December 2, 2023

Let's learn USB! -- When will we run out of RAM ?

The F103 has only 20K of sram. This is probably the chips greatest limitation. It has yet to bother me, and is entirely adequate for most things the chip is used for, but it is something to be aware of.

This ram is at address 0x2000_0000 and extends to 0x2000_4fff. I.e. is is 0x500 bytes in size.

I initialize my stack pointer of 0x2000_5000 and thus let the stack grown down into the ram area from the top of the address space. How far can it grow before we get into trouble? How much space do we think we ought to allocate for the stack?

In truth, we don't allocate space for the stack, we just start it off as I just described and if we foolishly allocate big objects on the stack, all hell will break loose when it crashes into data areas that get allocated at the start of ram. The question then becomes what the size is of the allocated data area (data+bss).

If you don't know, BSS is, in the C context, uninitialized global data. If you write something like "int stuff[64];" outside of a function, that will end up in BSS and will get set to zero when the code starts up.

The "size" command

Here is an interesting link, not entirely on topic, but I want to preserve it somewhere for future reference: My current build process yields and elf file, and I can run the "size" command on it to get output like this:
[tom@trona daed]$ size main.elf
   text	   data	    bss	    dec	    hex	filename
   5300	    364	   3508	   9172	   23d4	main.elf
Very handy! I can see here that I have 364+3508 bytes used in ram. A total of 3872 bytes, which comes way short of the 20480 bytes available. It would not be hard to write some kind of script that I could run as part of my Makefile driven build process that would warn me if this got too big. Let's say I decide 4K is plenty for the stack, then if data+bss exceeds 16K, I would blow a whistle.

I got interested in this after some erratic behavior when I set up a queue for uart output. My suspicion was that I might have a stack overflow issue, but that doesn't seem likely.

All I see is zeros

When I run "size" on another project, I get:

[tom@trona usb_baboon]$ size baboon.elf
   text	   data	    bss	    dec	    hex	filename
      0	      0	      0	      0	      0	baboon.elf
This is less than informative. What has gone wrong here? It turns out this is due to the -gc,sections option that I took from another makefile (where it was -Wl,-gc-sections). When I get rid of this, I get: size baboon.elf text data bss dec hex filename 11632 312 1664 13608 3528 baboon.elf

In passing, I should mention "readelf". It has a multitude of options.
I find "readelf -S baboon.elf" to be useful.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org