Author Topic: STM32 project code size problem ( small active load)  (Read 18291 times)

0 Members and 6 Guests are viewing this topic.

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1061
Re: STM32 project code size problem ( small active load)
« Reply #25 on: October 23, 2022, 10:40:31 am »
Quote
Setting stack/heap to 0 won't work.
It will work, you just will not get any help from the linker warning you about data sizes. Once you have a good idea of the stack size used for your app you can plug in a number and start getting warnings at compile time about your data size getting too large. Those values which were created in the linker are only used in the linker, and are only used to pad a section to cause a ram overflow as a warning.
 

Offline Sniper1Topic starter

  • Regular Contributor
  • *
  • Posts: 142
  • Country: ro
Re: STM32 project code size problem ( small active load)
« Reply #26 on: October 23, 2022, 10:41:46 am »
well when i bouth this one i went with more or less the specs of an arduino uno since i knew that on it i had way more then enough RAM and FLASH for what i was doing
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 6123
  • Country: nl
Re: STM32 project code size problem ( small active load)
« Reply #27 on: October 23, 2022, 10:51:41 am »
For these kind of microcontrollers bare metal programming is a way of reducing code size to a minimum. Sure it takes getting to know the peripherals, but it is not that difficult.

Find your self a nice IDE like visual studio or eclipse or even a simple text editor can do. Setup a make script and build your project.

For what you intend to use it you won't need any library functions. Making PWM can be done with the timers. The CPU only has to setup the registers for it. Reading a couple of buttons or a rotary encoder is simple. Also controlling a 2 line 16 character display is not that difficult.

Some of the things you need can be found in this repository: https://github.com/pecostm32/STM32F303_Sine_Square_Generator

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1061
Re: STM32 project code size problem ( small active load)
« Reply #28 on: October 23, 2022, 10:51:52 am »
Quote
well when i bouth this one i went with more or less the specs of an arduino uno since i knew that on it i had way more then enough RAM and FLASH for what i was doing
Its not always easy to compare 8bit usage of flash/ram to a 32bit mcu. You can most likely make what you have work- you are currently using ~10k flash and less than 1K of ram, unless you plan on creating a lot more code.
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6926
  • Country: es
Re: STM32 project code size problem ( small active load)
« Reply #29 on: October 23, 2022, 10:54:22 am »
Just set heap to 0 and never use malloc.

Not so simple, std lib (printf, etc)and some parts of HAL need to allocate some memory.
Just learn how to deal with it, adjusting the heap to the required amount.

LTO actually does optimize HAL quite a lot.
You'll see how almosy all HAL init code disappears from the call graph, and suddenly your main becomes 3KB in size, but packing everything in a much more efficient way.


It will work, you just will not get any help from the linker warning you about data sizes.
What I was trying to say is the objetive of doing that (Getting compiler warning) won't work.
The code will compile just fine! But your system might crash or behave in a unpredictable ways if heap/stack grow too much, will overlap other parts of the memory.
Try yourself:
For a MCU with 16Kb of RAM, create a global array of 15KB, then make a function with a local array also with size of 15KB (this would be allocated into the stack).
Initialize the array in main, call the function writing random stuff, then check how the global array contents magically changed.

Edit: Updated to CubeIDE 1.10.1. Surprise, as f**ing always it crashed, needing to delete the whole ST folder and reinstalling. St updates are a joke.
« Last Edit: October 23, 2022, 11:08:25 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline cv007

  • Super Contributor
  • ***
  • Posts: 1061
Re: STM32 project code size problem ( small active load)
« Reply #30 on: October 23, 2022, 11:05:03 am »
Quote
Not so simple, std lib (printf, etc)and some parts of HAL need to allocate some memory.
The heap still exists. Those minimum size values just pad out the end of the ram region to cause a region overflow so you get a warning when your data size starts to increase. Its nice to have if the numbers you provide make sense. Until you get those numbers you can skip the check, and monitor data usage like one normally would do. Once you have numbers you know are good, plug them in and you can pay less attention to the data size as the linker is watching it for you.
 

Offline hans

  • Super Contributor
  • ***
  • Posts: 1984
  • Country: 00
Re: STM32 project code size problem ( small active load)
« Reply #31 on: October 23, 2022, 11:14:21 am »
Just set heap to 0 and never use malloc.

Not so simple, std lib (printf, etc)and some parts of HAL need to allocate some memory.
Just learn how to deal with it, adjusting the heap to the required amount.

LTO actually does optimize HAL quite a lot.
You'll see how almosy all HAL init code disappears from the call graph, and suddenly your main becomes 3KB in size, but packing everything in a much more efficient way.


You sure? I've used HALs from many parts (from 8-bit AVRs to Cortex-m7), and in all cases I've never seen malloc being added. I could always set heap to 0 bytes.

If you're getting heap usage in your program, consider switching to the nano or newlib stdlib implementation. You don't want to run the full stdlib on an embedded device.
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6926
  • Country: es
Re: STM32 project code size problem ( small active load)
« Reply #32 on: October 23, 2022, 11:28:01 am »
Let me show an example:
Code: [Select]
void test (void){
#define TEST_SZ 16384
uint32_t data[TEST_SZ];
for (uint32_t i=0;i<TEST_SZ;i++){
data[i] = GPIOA->IDR;
if(data[i]==12)
GPIOB->IDR=data[i];
}
for (uint32_t i=0;i<TEST_SZ;i++){
GPIOA->ODR = data[i];
}
}

This does nothing really, but as GPIO registers are volatile, it prevents the compiler from optimizing and removing the large buffer.
As you see, my buffer is 16384*4=64KB in size! A lot more than this MCU has.
Where's the compiler warning? Nowhere.
Code: [Select]
13:34:38 Build Finished. 0 errors, 0 warnings. (took 2s.9ms)

Then if you check the Static Call Analyzer, you'll find out there's a function using that much memory.
Code: [Select]
Function    Local cost
test          65552
Running this would completely destroy the memory and ultimately cause a Hardfault exception when trying to access illegal/no-existing memory adressses.
But if you allocate a little less, ex. 1.5KB, it would just overwrite other random variables, causing your program to perform like it had some hard drugs.

So it's up to you to watch this and adjust the minimum stack size.
The reserved stack size is nothing more than a way to prevent heap and normal memory from overlapping, it basically statically allocates a global variable "heap".
So when your allocate too much in other place, you'll get a out of memory error. Otherwise, the heap would grow inadvertently and overwrite random memory areas like in this example.
When setting the reserved stack to the largest value reported in stack analyzer call graph (65632 bytes), Boom! Now you get the expected result!
Code: [Select]
region `RAM' overflowed by 64544 bytes

So that's it.  Setting the stack to 0 is just silly. Set it to the actual reported usage.
Why isn't this being done automatically? I have no idea. But feel lucky, other compilers doesn't report stack or heap usage.
How to deal with that in those cases? I have no idea. Global variables everywhere, I guess.
« Last Edit: October 23, 2022, 11:49:54 am by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Sniper1Topic starter

  • Regular Contributor
  • *
  • Posts: 142
  • Country: ro
Re: STM32 project code size problem ( small active load)
« Reply #33 on: October 23, 2022, 11:34:48 am »
For these kind of microcontrollers bare metal programming is a way of reducing code size to a minimum. Sure it takes getting to know the peripherals, but it is not that difficult.

Find your self a nice IDE like visual studio or eclipse or even a simple text editor can do. Setup a make script and build your project.

For what you intend to use it you won't need any library functions. Making PWM can be done with the timers. The CPU only has to setup the registers for it. Reading a couple of buttons or a rotary encoder is simple. Also controlling a 2 line 16 character display is not that difficult.

Some of the things you need can be found in this repository: https://github.com/pecostm32/STM32F303_Sine_Square_Generator

Yes that would be nice i am atm trying to do that with an RP2040 and failing a lot so i am not that confident if i can pull it off
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 6123
  • Country: nl
Re: STM32 project code size problem ( small active load)
« Reply #34 on: October 23, 2022, 11:50:03 am »
Yes that would be nice i am atm trying to do that with an RP2040 and failing a lot so i am not that confident if i can pull it off

It takes some practice. I have not played with the RP2040 yet, but the CPU is also an ARM cortex. The peripheral system is different as far as I read about it here. something with a PIO (programmable IO) controller that can do a lot apart from the CPU.

The STM is simpler. Starting point is to get the data sheet and reference manual for the one you are using from st.com https://www.st.com/en/microcontrollers-microprocessors/stm32l010k4.html#documentation

Most of the peripherals are similar between the different ranges like the L0, F1, F3, etc. So look at the startup bit in my code and see if it matches your registers. Clock frequencies most likely need to be adjusted, and you will need the header file for your device, but you can find that in the project you are using now.

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 638
  • Country: be
Re: STM32 project code size problem ( small active load)
« Reply #35 on: October 23, 2022, 01:47:08 pm »
If the stack grows too much, it will overwite other memory regions and start a lot of gremlins and funny stuff going in your code.
Suddenly you do Fruits=Apples+Oranges, Eggs turns to -1763, Tomatoes to 0xFFF12 and things like that ::)

Placing stack at the bottom of RAM would help. Stack growth beyond the limit will cause hard fault rather then trashed variables. This doesn't work for FreeRTOS though (and some other RTOSes, perhaps).
 

Offline Sniper1Topic starter

  • Regular Contributor
  • *
  • Posts: 142
  • Country: ro
Re: STM32 project code size problem ( small active load)
« Reply #36 on: October 23, 2022, 02:45:17 pm »
Yes that would be nice i am atm trying to do that with an RP2040 and failing a lot so i am not that confident if i can pull it off

It takes some practice. I have not played with the RP2040 yet, but the CPU is also an ARM cortex. The peripheral system is different as far as I read about it here. something with a PIO (programmable IO) controller that can do a lot apart from the CPU.

The STM is simpler. Starting point is to get the data sheet and reference manual for the one you are using from st.com https://www.st.com/en/microcontrollers-microprocessors/stm32l010k4.html#documentation

Most of the peripherals are similar between the different ranges like the L0, F1, F3, etc. So look at the startup bit in my code and see if it matches your registers. Clock frequencies most likely need to be adjusted, and you will need the header file for your device, but you can find that in the project you are using now.

THX
i already built a RP2040 board and it seems to work more or less (SD card problems + RTC problems) but i traced them back to code so not the hard part that is why i am trying to use VS code not Arduino
as for STM32 i am looking atm is there is any MCU with the same footprint and M core available in stock , just in case
then again now i have 5k Flash and 500+ B RAM free , so i think il manage , so just maybe i will get a larger MCU since once i order some PCBs it is hard to redo them and easyer to replace 1 component that is very unlikely to need changes
BTW let me ask again just to make sure:
So i have a L0 is there a chance a F1 3 etc will be pin compatible with what i have atm ? (there are some L0 but none in stock)
 

Offline pcprogrammer

  • Super Contributor
  • ***
  • Posts: 6123
  • Country: nl
Re: STM32 project code size problem ( small active load)
« Reply #37 on: October 23, 2022, 03:10:26 pm »
A quick scan showed me that yours is 32 pins, and the F1, F3, F4 are at the smallest 48 pins. So I guess not.

The L4 states it has pin compatibility with other STM32 lines.

And for what I read about it all STM32 devices are hard to get.

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 638
  • Country: be
Re: STM32 project code size problem ( small active load)
« Reply #38 on: October 23, 2022, 03:12:41 pm »
Also, try enabling LTO to sabe additional space by adding "-flto" to the compiler and linker arguments.

A word of caution regarding LTO.

Some versions of gcc will remove the vector table from the binary. GNU Arm Embedded Toolchain 9-2020-q2-update (9.3.1) surely does this. The reason is that the vector table is not referenced by any code, so the compiler is free to get rid of "unused" symbol.

To avoid this, decorate the vector table with __attribute__((__used__)) . Check the map file, anyway.
 

Offline Sniper1Topic starter

  • Regular Contributor
  • *
  • Posts: 142
  • Country: ro
Re: STM32 project code size problem ( small active load)
« Reply #39 on: October 23, 2022, 03:51:08 pm »
sadly yes i only got L0 with 32 pins then again i am in no rush i intend to place the PCB and Mouser orders somewhere in mid late November
 

Online bson

  • Supporter
  • ****
  • Posts: 2785
  • Country: us
Re: STM32 project code size problem ( small active load)
« Reply #40 on: October 23, 2022, 06:24:58 pm »
For a device like this dump the ST HAL libraries and work directly with the hardware, creating only exactly the abstraction your project actually needs.  Then 'cat' all your sources together into a single file and compile with -fwhole-file.  (This intermediate is sometimes called a fat source.)

Make sure to compile with -ffunction-sections and link with ld --gc-sections so unused functions (and lambdas, if you use C++) are removed by the linker.

Have the linker add a symbol at the end of the stack (through the link script).  Then while running enable a hardware watchpoint on that symbol (through the debugger, e.g. with gdb you'd use "awatch endofstack"); this has a good probability of catching a stack overflow.
« Last Edit: October 23, 2022, 06:26:31 pm by bson »
 

Offline Sniper1Topic starter

  • Regular Contributor
  • *
  • Posts: 142
  • Country: ro
Re: STM32 project code size problem ( small active load)
« Reply #41 on: October 23, 2022, 07:35:44 pm »
Also on a side note what is the best place to find libraries for STM32? atm i find them via YT videos but this is probably not great for more specific ICs
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4660
  • Country: us
Re: STM32 project code size problem ( small active load)
« Reply #42 on: October 23, 2022, 10:33:00 pm »
Quote
what is the best place to find libraries for STM32?
ST has put their HAL and Cube libraries on github (which is wonderful!)
https://github.com/STMicroelectronics/STM32CubeL0/
As previously mentioned, these may not be well optimized for size and memory use, but at least you can look at them without having to wade through a full local Cube install.
Also https://github.com/libopencm3
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6926
  • Country: es
Re: STM32 project code size problem ( small active load)
« Reply #43 on: October 24, 2022, 12:00:00 am »
C'mon, you already have the HAL, still 50% free flash, should be enough for your code!
« Last Edit: October 24, 2022, 12:26:29 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Sniper1Topic starter

  • Regular Contributor
  • *
  • Posts: 142
  • Country: ro
Re: STM32 project code size problem ( small active load)
« Reply #44 on: October 24, 2022, 12:22:48 pm »
yea ill manage now the lcd lib was not as large as i thought
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6926
  • Country: es
Re: STM32 project code size problem ( small active load)
« Reply #45 on: October 24, 2022, 12:28:58 pm »
What LCD and lib are you using?
Remember with u8g2 you can strip down fonts and include only the required characters, this greatly reduces space.
Mosts libs include a huge font with all ascii chars, then you might need only numbers, but it'll be stored whole into the flash.

Definitely, the crappy **_HandleTypeDefs** are using almost half of the ram, woudl be nice to get rid of them.
Switching the project to LL (LowLevel) libraries will do it, still provide a library to interface the hardware.

I did the test, ram and flash went down to 26%!
Only 32 bytes used by the system.
Then the stack and heap were using 256bytes each (The reserved sizes in the linker script), could be tracked down and reduced by taking care on the code.

If you'll be using stdlib functions (*printf*), then check the allocated heap with the mallinfo function I posted earlier (AFTER using those functions, heap get allocated on first call), assigning just a little more (i.e 32 bytes), and that would be it.
Otherwise, as fas as I know only the USB library allocates memory that way, you probably could set the heap to 0 in your code otherwise, but always check first with mallinfo.

Same for user stack:
Analyze the list / call graph and assign the heap a slightly larger value.
That way you'll be protecting the heap and user memory from colliding, yet wasting the minimal resources.

If you don't allocate large structures inside your functions (Or avoid long chained calls between functions, each one allocating more data), then stack usage will be minimal.
It's this behavior what increases the Stack a lot:
Code: [Select]
void func4(void){
  uint8_t buffer4[128]; //<-- Another 128bytes on stack (512 now)
  return;               // Now all stack will be freed up
}
void func3(void){
  uint8_t buffer3[128]; //<-- Another 128bytes on stack (384 now)
  func3();              // Another function call, perhabs buffer3 was not required anymore 
}
void func2(void){
  uint8_t buffer2[128]; //<-- Another 128bytes on stack (256 now)
  func3();              // Another function call, perhabs buffer2 was not required anymore
}
void func1(void){
  uint8_t buffer1[128]; //<-- 128bytes on stack
  func2();              // Stack not freed up, but calling another function, perhabs buffer1 was not required anymore
}

Which will be greatly minimized if you avoid the call-hierarchy, breaking the functions in a diferent way:
Code: [Select]
int func4(void){
  uint8_t buffer4[128]; //<-- 128bytes on stack
  do_whatever();
  return result;        // stack freed up
}
int func3(void){
  uint8_t buffer3[128]; //<-- 128bytes on stack
  do_whatever();
  return result;        // stack freed up
}
int func2(void){
  uint8_t buffer2[128]; //<-- 128bytes on stack
  do_whatever();
  return result;        // stack freed up
}
int func1(void){
  uint8_t buffer[128];  //<-- 128bytes on stack
  do_whatever();
  return result;        // stack freed up
}
void handle(void){
  if( func1()=='do_func2' ){
    if( func2()=='do_func3' ){
      if( func3()=='do_func4' ){
        func4();
      }
    }
  }
}

Or by many other ways.
First example will forcefully need a stack of not less than 512bytes, second will only use 128.

Developing in LL will be a bit harder, but still much easier than managing the registers yourself.
« Last Edit: October 24, 2022, 01:24:36 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->