Decoding the output of `avr32-size`

Does anyone know how to decode the output of the size / avr32-size utility?

Here is the partial output from make for the teletype firmware:

teletype.elf  :
section                size         addr
.reset               0x200c   0x80000000
.rela.got               0x0   0x8000200c
.init                  0x1a   0x8000200c
.text                0xd934   0x80002028
.exception            0x200   0x8000fa00
.fini                  0x18   0x8000fc00
.rodata              0x4118   0x8000fc18
.dalign                 0x4          0x4
.ctors                  0x8          0x8
.dtors                  0x8         0x10
.jcr                    0x4         0x18
.got                    0x0         0x1c
.data                0x1d3c         0x1c
.balign                 0x0       0x1d58
.bss                 0x1f80       0x1d58
.heap               0x12328       0x3cd8
.comment               0x2f          0x0
.debug_aranges       0x21b0          0x0
.debug_pubnames      0x4e8f          0x0
.debug_info         0x4437b          0x0
.debug_abbrev        0x961d          0x0
.debug_line         0x27881          0x0
.debug_frame         0x6340          0x0
.debug_str           0xd267          0x0
.debug_loc          0x12cc2          0x0
.debug_macinfo    0x20d3b05          0x0
.stack               0x2000      0x16000
.flash_nvram        0x23e84   0x80040000
.debug_ranges        0x3a58          0x0
Total             0x21c9557


   text	   data	    bss	    dec	    hex	filename
0x13c8a	 0x1d50	0x3a130	 326410	  4fb0a	teletype.elf

Or you can get the same info by running avr32-size, e.g avr32-size -B teletype.elf:

   text	   data	    bss	    dec	    hex	filename
  81034	   7504	 237872	 326410	  4fb0a	teletype.elf

Looking over “text, data and bss: Code and Data Size Explained” and combining it with the output of avr32-size:

  • The ROM size is text + data = 88538, but I need to add the size of .flash_nvram to find out how much of the 512kb I’ve used? So really it’s 235614.
  • RAM usage is: some booking suff (irq tables, etc), the RW .data, .bss, .heap and .stack. Which should (and does) add up to 96k. The stack size is fixed in one of the config files at 8k. Given that I know there is very minimal usage of the heap (just the USB code afaik), in effect .heap is how much free RAM I have to work with? So for the teletype that is ~72kb.

Any flaws in my logic? I’d like to get this written up and put in the the README.md on the libavr32 repo, as it’s the kind of thing I keep having to lookup. And I imagine it will be useful for Ansible firmware dev too.

5 Likes

Not specific to avr, but I only ever use the summary output unless there’s some very specific section I care about. So really you just need to know how to interpret the text, data, and bss sizes for the most part.

I think that article pretty much sums up everything you need to know in regular usage.

3 Likes

been curious about this too, and agreed it would be a very useful info to have and especially so for ansible firmware dev.

been meaning to start a thread on ansible dev too (possible refactor to make adding new apps easier, scale / preset management etc) but trying to get other things out out of the way first so probably won’t get to it until a couple of weeks from now…

2 Likes

Yeah, except the output from avr32-size -B teletype.elf seems to have a very odd value for bss:

   text	   data	    bss	    dec	    hex	filename
  81034	   7504	 237872	 326410	  4fb0a	teletype.elf

237872 is a lot bigger than the 96k or RAM the AV32UC3B0512 has!

Compared with the output from avr32-size -A teletype.elf:

teletype.elf  :
section               size         addr
.reset                8204   2147483648
.rela.got                0   2147491852
.init                   26   2147491852
.text                55604   2147491880
.exception             512   2147547648
.fini                   24   2147548160
.rodata              16664   2147548184
.dalign                  4            4
.ctors                   8            8
.dtors                   8           16
.jcr                     4           24
.got                     0           28
.data                 7484           28
.balign                  0         7512
.bss                  8064         7512
.heap                74536        15576
.comment                47            0
.stack                8192        90112
.flash_nvram        147076   2147745792
Total             35427671

(I removed the .debug_* lines)

If we apply a bit of unix voodoo, with avr32-size -A teletype.elf | grep '^\..*' | grep -v '^.debug.*' | sort -k 3, we can sort by address:

.comment                47            0
.dalign                  4            4
.ctors                   8            8
.dtors                   8           16
.jcr                     4           24
.data                 7484           28
.got                     0           28
.balign                  0         7512
.bss                  8064         7512
.heap                74536        15576
.stack                8192        90112
.reset                8204   2147483648
.init                   26   2147491852
.rela.got                0   2147491852
.text                55604   2147491880
.exception             512   2147547648
.fini                   24   2147548160
.rodata              16664   2147548184
.flash_nvram        147076   2147745792

Which is really nice as you get a very visual layout of RAM and ROM (the ROM starts at 2147483648 / 0x80000000). It’s worth noting that .flash_nvram does not start at the end of .rodata, but instead starts at 0x80040000 as defined in config.mk.

I’ve also discovered the readelf utility. Try avr32-readelf -e teletype.elf and the even longer avr32-readelf -a teletype.elf.

3 Likes

It looks like the .bss summary is simply including the size of .flash_nvram in the calculation. Looks like it’s .flash_nvram + .bss + .stack + .heap

2 Likes

great deconstruction here!

i believe this is correct. did you discover anything further to indicate otherwise?

i’ve been thinking about how to improve this also, to facilitate contributions. of course the first step would be to break the individual apps out of their dual-app files. i had some now insufficient reasoning behind having things in the same file-- some idea of potential shared memory and preset-code, but that could still happen with a different scheme. let’s discuss some approaches in another thread when we feel it’s time.

1 Like

Not yet. I’ll have a proper look to see what usage of [m,c,re]alloc there is in libavr32, just in case the heap is being used more than we think. Then write something detailed up on my website, and put a tl;dr on the libavr32 readme.

I can chip in a little bit to this too, I did have a quick look through the Ansible source code the other day. I think you’ll need to think of a more robust scheme for reassigning event handlers if you want something that scales to more apps. Similarly you’ll need to think about RAM usage and making sure that non-running apps are not using any, maybe a larger stack or even using the heap. The other modules in the “increasingly misnamed trilogy” have actually got enough ROM and RAM free to fit a few apps in too.

2 Likes

If the modules had a decent malloc implementation included then switching apps could cause the current app to be deallocated and the new one allocated. You’d then rely on malloc / the heap to take care of managing the memory instead of the apps statically allocating everything.

The apps would then need to register event handlers with whatever the module “framework” was.

1 Like

I have no idea about the quality of the malloc implementation, but there is no virtual addressing, so I think heap fragmentation becomes a real possibility.

Maybe just statically allocate a large amount or RAM to be used by the running app (via pointer voodoo). There might be some tricks to statically assert the size of an app’s struct is small enough.

Hmm other then the app, what else would be doing heap allocations at runtime? I think it would likely be fine. Having the app do multiple smaller allocations at startup would probably help too.

1 Like

A quick ag tells me the USB code does. I can’t be certain that we execute that code without more in depth delving. But if it does it every time a device is connected (or every time packets are transferred) that could lead to issues couldn’t it?

I would be rewllly surprised if it was each time a packet was transferrred, that would be incredibly inefficient. Also USB endpointd generally have fixed buffer sizes so there should be no need to allocate. At least none of the USB drivers I’ve ever dealt with have had to do that…

I’d guess it probably only needs to do it at initialization, but it could be when a device is connected, though that should also be avoidable since you should generally know exactly how much memory you need by the time you initialize the USB stack…

So this turned into something of a rabbit hole.

I’ve written up what I could figure out about RAM and ROM usage here: http://samdoshi.com/post/2016/10/avr32-ram-and-rom-usage/

I’ve also added a shortened version to the libavr32 readme.

https://github.com/monome/libavr32/pull/15

5 Likes

thank you for doing this, this is awesome, will save me hours of research (and beautifully documented on top of that)!

1 Like

Thank you that’s very kind. I might do a follow up at some point talking about analysing memory usage (e.g. sorting variables and code by size).

It’s all so very different from the web dev work I used to do though!

1 Like

Thanks for this. The section on LMA and VMA just helped me understand something important in an ARM feature I’ve been trying to get working :slight_smile:

1 Like

A year later, .text size on teletelype-2.1.0-rc2 is 69% larger.

.text               0x16f00

100% of this increase represents improvement to the code base and teletype functionality, so congratulations are in order for all contributors to monome/teleteype! :+1:


Apologies for the thread necromancy, but I’ve been having a sober second thought over some of my code lately, and I came back around to this post.

4 Likes

i happened to come across this writeup while randomly googling some things. super helpful! tysm

1 Like