GrumpyOldPizza / ArduinoCore-stm32l0

Arduino Core for STM32L0
125 stars 67 forks source link

binary size questions #32

Closed tve closed 5 years ago

tve commented 5 years ago

I've been playing with this core for a few days using a custom L082 board and I'm a bit shocked at the resulting binary (upload) sizes. A hello world takes just under 20KB, adding I2C brings it to ~30KB. Yes, the device has plenty of flash but the size affects the edit/compile/debug cycle. I'm using a BMP and it takes ~10 seconds to upload the 30KB. I looked at the map and the main culprits in the I2C case are the stm32l0 device drivers (in particular the interrupt handlers), malloc (is that really required?), and aeabi float arithmetic.

I'm curious what you are finding. Do you use LoRaWAN all the time and so the code size is gigantic anyway? Does the USB DFU bootloader make this irrelevant, i.e. super-fast? Do you find that the complex device drivers with DMA and all that are actually worth it?

Here are the functions >1KB using nm --print-size --size-sort:

080043bc 00000108 t stm32l0_uart_dma_receive    /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:111
08005d84 0000010a T __udivsi3
080033b0 00000114 T RTC_IRQHandler      /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_rtc.c:1305
08001a3c 0000013c T stm32l0_gpio_pin_configure  /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_gpio.c:87
08006e18 00000140 t stm32l0_rtc_bcd_year_to_days        /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_rtc.c:83
08003098 00000144 t stm32l0_rtc_timer_alarm     /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_rtc.c:574
080044f0 00000158 t stm32l0_uart_stop   /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:469
080034c4 0000015c T SystemInit  /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_system.c:195
08004e14 00000170 T stm32l0_uart_configure      /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:1121
08000a60 00000174 T _ZN4Uart5writeEPKhj
08001d7c 00000178 t stm32l0_i2c_start   /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_i2c.c:101
080060b0 00000182 T __udivmoddi4
08004648 00000184 t stm32l0_uart_start  /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:347
20001438 0000018c b armv6m_pendsv_control       /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/armv6m_pendsv.c:48
08002ef4 000001a4 T stm32l0_rtc_calendar_offset /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_rtc.c:1120
08001290 000001b8 T stm32l0_adc_read    /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_adc.c:179
08002754 000001bc T stm32l0_i2c_configure       /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_i2c.c:1167
08006ba4 000001c8 T g_APinDescription
08005e98 000001cc T __divsi3
08004184 000001d0 T stm32l0_timer_channel       /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_timer.c:428
08005364 000001d4 T _free_r
08006568 00000224 T __aeabi_fdiv
0800678c 00000264 T __aeabi_fmul
08006234 00000334 T __aeabi_fadd
08003ce8 000003f4 T stm32l0_system_initialize   /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_system.c:294
20000c38 00000408 D __malloc_av_
20000810 00000428 d impure_data
08004894 0000047c t stm32l0_uart_interrupt      /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:584
08003620 000004d0 T stm32l0_system_sysclk_configure     /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_system.c:647
08005580 00000554 T _malloc_r
08001fa4 0000069c t stm32l0_i2c_interrupt       /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_i2c.c:542
GrumpyOldPizza commented 5 years ago

It takes about 10ms to erase/program 128 bytes, or in other words, 12800 bytes/sec. I have seen way slower transfers using gdb/openocd, mainly because the SWCLK dropped back quite a bit, so that might contribute. It also seems that the builtin USB/DFU is also not as fast as it should be.

In any case it's not that great, but there is little one can do.

Your nm output implies that you are not using the Arduino IDE, and as a result not the proper compile/link flags (see the size of "impure_data"). You also seem to use "printf", which would explain the pulling in of all the __aeabi_f* functions (as well as malloc). But then again, I am just guessing.

Regarding complex device drivers. This code is meant for low power. If I2C uses DMA on the readback path, then the CPU can go to SLEEP while waiting for the transaction to be complete. However all of this has a cost in terms of code size. It's a tradeoff. The one made here is towards a certain feature set.

On Sun, Aug 12, 2018 at 1:40 PM, Thorsten von Eicken < notifications@github.com> wrote:

I've been playing with this core for a few days using a custom L082 board and I'm a bit shocked at the resulting binary (upload) sizes. A hello world takes just under 20KB, adding I2C brings it to ~30KB. Yes, the device has plenty of flash but the size affects the edit/compile/debug cycle. I'm using a BMP and it takes ~10 seconds to upload the 30KB. I looked at the map and the main culprits in the I2C case are the stm32l0 device drivers (in particular the interrupt handlers), malloc (is that really required?), and aeabi float arithmetic.

I'm curious what you are finding. Do you use LoRaWAN all the time and so the code size is gigantic anyway? Does the USB DFU bootloader make this irrelevant, i.e. super-fast? Do you find that the complex device drivers with DMA and all that are actually worth it?

Here are the functions >1KB using nm --print-size --size-sort:

080043bc 00000108 t stm32l0_uart_dma_receive /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:111 08005d84 0000010a T udivsi3 080033b0 00000114 T RTC_IRQHandler /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_rtc.c:1305 08001a3c 0000013c T stm32l0_gpio_pin_configure /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_gpio.c:87 08006e18 00000140 t stm32l0_rtc_bcd_year_to_days /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_rtc.c:83 08003098 00000144 t stm32l0_rtc_timer_alarm /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_rtc.c:574 080044f0 00000158 t stm32l0_uart_stop /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:469 080034c4 0000015c T SystemInit /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_system.c:195 08004e14 00000170 T stm32l0_uart_configure /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:1121 08000a60 00000174 T _ZN4Uart5writeEPKhj 08001d7c 00000178 t stm32l0_i2c_start /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_i2c.c:101 080060b0 00000182 T __udivmoddi4 08004648 00000184 t stm32l0_uart_start /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:347 20001438 0000018c b armv6m_pendsv_control /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/armv6m_pendsv.c:48 08002ef4 000001a4 T stm32l0_rtc_calendar_offset /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_rtc.c:1120 08001290 000001b8 T stm32l0_adc_read /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_adc.c:179 08002754 000001bc T stm32l0_i2c_configure /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_i2c.c:1167 08006ba4 000001c8 T g_APinDescription 08005e98 000001cc T divsi3 08004184 000001d0 T stm32l0_timer_channel /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_timer.c:428 08005364 000001d4 T _free_r 08006568 00000224 T aeabi_fdiv 0800678c 00000264 T __aeabi_fmul 08006234 00000334 T aeabi_fadd 08003ce8 000003f4 T stm32l0_system_initialize /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_system.c:294 20000c38 00000408 D __mallocav 20000810 00000428 d impure_data 08004894 0000047c t stm32l0_uart_interrupt /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_uart.c:584 08003620 000004d0 T stm32l0_system_sysclk_configure /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_system.c:647 08005580 00000554 T _malloc_r 08001fa4 0000069c t stm32l0_i2c_interrupt /home/thomas/ArduinoCore-stm32l0/system/STM32L0xx/Source/stm32l0_i2c.c:542

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/32, or mute the thread https://github.com/notifications/unsubscribe-auth/AG4QfCAH9tNltBG9Cn9fCabbT0V1knXmks5uQISwgaJpZM4V5qTT .