Zephyr and the Memory Footprint
Do you want to use Zephyr RTOS on a Microcontroller with only a few bytes of Flash? There are a few options and settings to play with. Let's try it!
With almost "standard" settings
On the Optimizing for Footprint doc site you will find some hints how to reduce the memory footprint. Ok let's do it. I compiled the following application by using this configs:
|
main.c: void main (void) {
uint32_t i = 0;
// run the loop for ever
while (true) {
i++;
}
}
|
prj.conf: # disable all peripherals
CONFIG_GPIO=n
CONFIG_SERIAL=n
CONFIG_SPI=n
CONFIG_I2C=n
# disable the boot banner
CONFIG_BOOT_BANNER=n
# disable all debug and log messages
CONFIG_DEBUG=n
# enable compiler size opt. (this is the default anyway)
CONFIG_SIZE_OPTIMIZATIONS=y
|
With this application and settings I could reduce the total application to 6872 bytes:
west build -p auto -b <board name>
Memory region Used Size Region Size %age Used
FLASH: 6872 B 16 KB 41.94%
SRAM: 1232 B 2 KB 60.16%
IDT_LIST: 56 B 2 KB 2.73%
Ok, this is just the compiled kernel to have an idea how much flash it needs. You can analyze the memory usage from the rom/ram-report.
By using west build -t rom_report you will get a really nice report of the flash coverage. The same procedure for a ram usage report: west build -t ram_report
For more details have a look at the Zephyr Docs: Optimization Tools).
Simply switch off everything
From the rom report, we can see that various things such as timers etc. are also compiled. We can therefore reduce the footprint a little further. In the | minimal footprint example, further configurations are explained. So the timer and the multi threading can be switched off. With this settings I are able to reduce the total memory footprint down to 3476 bytes:
Memory region Used Size Region Size %age Used
FLASH: 3476 B 16 KB 21.22%
SRAM: 896 B 2 KB 43.75%
IDT_LIST: 56 B 2 KB 2.73%
prj.conf file used for this compilation:
# disable all peripherals
# disable all peripherals and drivers
CONFIG_WATCHDOG=n
CONFIG_PINMUX=n
CONFIG_GPIO=n
CONFIG_SERIAL=n
CONFIG_SPI=n
CONFIG_I2C=n
CONFIG_FLASH=n
CONFIG_EEPROM=n
# disable power management
CONFIG_PM=n
# disable the boot banner and delay
CONFIG_BOOT_DELAY=0
CONFIG_BOOT_BANNER=n
# disable dynamic interrupts
CONFIG_DYNAMIC_INTERRUPTS=n
CONFIG_IRQ_OFFLOAD=n
# disable memory protection
CONFIG_THREAD_STACK_INFO=n
CONFIG_THREAD_CUSTOM_DATA=n
CONFIG_FPU=n
# disable all console, debug and log messages
CONFIG_DEBUG=n
CONFIG_CONSOLE=n
CONFIG_UART_CONSOLE=n
CONFIG_STDOUT_CONSOLE=n
CONFIG_PRINTK=n
CONFIG_EARLY_CONSOLE=n
# single-threaded, no timer support in the kernel
CONFIG_MULTITHREADING=n
CONFIG_KERNEL_MEM_POOL=n
# disable timer support in the kernel
CONFIG_SYS_CLOCK_EXISTS=n
# enable compiler size opt. (this is the default anyway)
CONFIG_SIZE_OPTIMIZATIONS=y
Ok, thats nice, but how useful is this?. So let's see what a "real" helloworld application needs.
Hello World with LED and Console Output
tbd.
Appendix
These examples were tested with a nucleo_l011k4 board from ST Microelectronics and Zephyr Version v2.5.0-rc1-40-g7592863643e1. For other boards the numbers may vary slightly. However, these are certainly valid for processors with ARM M0 core.