AVR libc function sizes?

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Does anyone know of a list anywhere that gives an estimation of flash usage for a given function in AVR-libc? Just a list of some of the bigger ones like printf would be handy to have.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It deepends on a lot of things. Remember that different AVRs have e.g. different sizes for return addresses pushed on the stack. There are different variants of the library build for different AVRs, and flash consumption for a specific function might differ between variants. For the printf functions there is also the variants for minimal, standard and FP support to take into consideration.

Rather than someone pre-producing a list that would be hard to get accurate and covering all variants, you just call the function so that it gets linked in. Then look in the .map file for the consumption.

Note that only looking at e.g. printf() will not tell the whole story. It calls other functions under the hood.

And therein lies another difficulty determining what e.g. using printf() costs. The underlying functions are used by many different "top" or "user" functions. Most notably for printf() is snprintf(). Now, assume that you have used no other functions that relies on snprintf() - now you use printf(), and the cost increases with the cost of snprintf(). If you instead have already called e.g. fprintf(), then that has already caused snprintf() to be linked in. Now if you also call printf(), then there will be no new added cost for snprintf(). So you not only need to know that you call printf(), you also need to know what other functions it relies on, and what other functions that also relies on the functions that printf() relies on you already have called.

See?, it will soon become a big mess impossible to handle...

By all means, if you succeed in producing a list covering enough variants then please post it here! ;-)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Simplistically just build an empty program, note the size, add a call to foo(), rebuild, note the size, subtract the original size. That is the size of foo(). Rinse and repeat. But really, why does it matter? The only time code size is actually important is when your build gets to 1 byte more than the size of the device you are using.

Note also that printf("hello") will be replaced by puts("hello") so you may need to work on your test code to ensure you get a "fair" result.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
It deepends on a lot of things. Remember that different AVRs have e.g. different sizes for return addresses pushed on the stack. There are different variants of the library build for different AVRs, and flash consumption for a specific function might differ between variants. For the printf functions there is also the variants for minimal, standard and FP support to take into consideration.

Rather than someone pre-producing a list that would be hard to get accurate and covering all variants, you just call the function so that it gets linked in. Then look in the .map file for the consumption.

Note that only looking at e.g. printf() will not tell the whole story. It calls other functions under the hood.

And therein lies another difficulty determining what e.g. using printf() costs. The underlying functions are used by many different "top" or "user" functions. Most notably for printf() is snprintf(). Now, assume that you have used no other functions that relies on snprintf() - now you use printf(), and the cost increases with the cost of snprintf(). If you instead have already called e.g. fprintf(), then that has already caused snprintf() to be linked in. Now if you also call printf(), then there will be no new added cost for snprintf(). So you not only need to know that you call printf(), you also need to know what other functions it relies on, and what other functions that also relies on the functions that printf() relies on you already have called.

See?, it will soon become a big mess impossible to handle...

By all means, if you succeed in producing a list covering enough variants then please post it here! ;-)


Sounds doable! :)

I imagine someone crafty with the time could script an engine to walk the function dependencies and automate a test compilation for each call, taking into account dependent calls to create a memory baseline and see how much each one contributes. How to present that information as something useful would interesting within itself. Out of my league :shock:

clawson wrote:

Simplistically just build an empty program, note the size, add a call to foo(), rebuild, note the size, subtract the original size. That is the size of foo(). Rinse and repeat. But really, why does it matter? The only time code size is actually important is when your build gets to 1 byte more than the size of the device you are using.

Note also that printf("hello") will be replaced by puts("hello") so you may need to work on your test code to ensure you get a "fair" result.

It matters for the exact reason you said, when you run out of memory. For those of us who aren't seasoned veterans in embedded programming, it'd be nice to know just how much the convenience of a function is going to cost us. Using something like printf and scanf for simple terminal stuff can quickly gobble up a lot on an 8k device. I know a lot of this just comes from experience, but for newcomers or those from a PC experience, it could help a lot for design and part selection.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Generally work on the principle of 1K for float, 1K for printf (and scanf) and insignificant amounts for pretty much everything else, few library functions are more than 100 bytes so if you're within 100 bytes of the boundary of your chip you are probably using the wrong chip: trade up to the next model in the family sequence.