Is your project stuck?

Try Zylin's Roadside Assistance services
Small code and data size eCos application

Before you start

The silicon that is taken up by a CPU and the peripherals is a tiny fraction of what SRAM and flash takes up. This is clearly evident from the plethora of CPUs out there with 10's to a few 100's of kBytes SRAM/flash. You should expect the amount of embedded SRAM/flash to be fairly constant over time due to these fundamental limitations.

A lot of these 32 bit CPUs do not have an external bus so it isn't possible to add more flash/ram, nor does it make a whole lot of sense since that would increase the BOM and cost of production.

If you are used to embedded operating systems having a few 100's kBytes or a megabyte or three of SRAM/flash you may wonder how such devices are exploited.

These 32 bit devices are using all the tricks in the book from 8 and 16 bit microcontrollers. The typical scenario is that you will get a complete kit from e.g. Keil or IAR which includes: IDE, hardware debugger and a library that you can link your application with. This library will probably be highly specific to the device that you bought a kit for.

You'll find that a lot of tools and CPU vendors are pushing a lock-in strategy, which served them so well in the 8-16 bit world. In the 32 bit tools and CPUs are much more orthogonal. As long as the tools and embedded operating system are there, then the actual CPU architecture doesn't matter as much and can easily vary from project to project for an engineer. The choice of CPU is based more on peripherals, RAM/flash, performance and cost rather than what was done last time.

Why eCos for these devices?

Everyone have their reasons for wanting to use eCos or not wanting to use eCos. Perhaps you just like your operating system and tools work across a range of devices and projects you're involved in? Perhaps you are tired of messing around with licenses as people and computers are shuffled about?

Example

One of the great things about eCos is that you can configure pretty much everything. Below is an example that shows what is included in a small configuration of eCos.

$ ecosconfig new eb40a minimal
$ ecosconfig tree
$ make
$ arm-elf-gcc -Iinstall/include/ -g -Linstall/lib -Ttarget.ld hello.c -nostdlib --Wl,--Map=hello.map
$ arm-elf-size a.out
text data bss dec hex filename
6356 252 33148 39756 9b4c a.out

/* hello.c */
void cyg_start()
{
/* infinite loop is the equivalent of hello world, a standard printf takes 40kBytes! */
for(;;);
}

Looking inside a small hello world eCos app

Examining the .map file is the first step towards understanding what is included in the above example: hello.map

SizeComment
6000By default the interrupt support is compiled in. This interrupt support is general enough to support a multithreaded kernel. Hence it's somewhat biggish. Also serial port debug output routines are included and some higher level IO functions are included. These higher level IO functions allows you to treat a serial port or a file in much the same manner. Clearly there is a fair amount of "unecessary" stuff for such a simple application, but the overhead isn't too bad if you do need a more general approach to interrupts and IO
33000By default the system stack size is 32kBytes. The system stack is used to run e.g. interrupts and other single threaded system code. 1kByte would be plenty here and it is easily changed by setting

Tips for reducing size

Set CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE to something sensible. The default 32kBytes in the context of small SRAM/Flash CPUs makes no sense. The default is set to 32kBytes because it makes sense to ensure that the application runs on the first try so you don't have to spend time tinkering with stack sizes when you are chasing more fundamental startup problems.

Adjusting CYGNUM_HAL_COMMON_INTERRUPTS_STACK_SIZE to 512 in the example above and removing serial port, error codes and ISO fn support, yields:

$ arm-elf-size a.out
text data bss dec hex filename
5248 244 516 6008 1778 a.out

Other tips

For extremely space limited devices you may wish to consider sidestepping e.g. the eCos TCP/IP stack and use e.g. uIP directly.

The eCos TCP/IP stack supports lwIP and FreeBSD, but these stacks are quite general and can even support the POSIX API, which is overkill for deeply embedded devices that have the simplest possible web server needs.

The same goes for fitting a USB host/device stack into such devices.

You should also see some benefit from using ARM Thumb

What can eCos offer?

Since you probably can't use the higher level stacks with eCos and devices with only a few 10's of kBytes flash/SRAM, what can you use eCos for?

A good start would be to use eCos to have the same interrupt and multithreading RTOS common between projects and microcontrollers.

Next you can use as much of the higher levels of eCos as space permits, thus striking a balance between implementation effort and code and data size.


ZY1000 JTAG Debugger
ARM7/9/11, XScale, Cortex-M3
Fast. No drivers!