EmbeddedRelated.com
Forums

Getting the code size of a function in C

Started by Tosca Berisha November 1, 2005
Grant Edwards wrote:
> On 2005-11-01, Tauno Voipio <tauno.voipio@INVALIDiki.fi> wrote: > > >>>>>I need to determine the size of a function or module since I >>>>>need to temporary relocate the function or module from flash >>>>>into sram for firmware updates. > > >>>>If you're using GCC, probably you do not need to copy >>>>anything, just locate your function to the initialized data >>>>section: > > >>>That works, but it can be a bit of a waste since the function >>>is sitting in both flash and RAM 100% of the time. If there >>>are multiple routines that need to be run from RAM at different >>>points in time, you can save a bit of RAM by overlaying them. > > >>The amount of code needed in RAM for Flash writing is pretty >>small: about 250 bytes on an ARM for garden-variety AMD >>Flashes. > > > But where is the "flash writing" code getting the data? > > In cases I've dealt with the "flash writing" code has to > impliment some sort of communications protocol in order to > receive the data to be programmed into flash. In the product > I'm working with right now, it takes 3KB of code to do a flash > update. That's a pretty significant chunk out of my 32KB of > RAM.
You do not need to keep the whole chunk in RAM at the same time. Also, only the inner loop of a Flash writer is necessary to be kept in RAM, the rest can reside in the Flash. The code responsible for the handling from the unlock sequence till the chip responds ready to poll has to be in RAM, but this is for erasing a segment or writing a single byte. The rest of code can be safely in the Flash without any problems. The incoming data is usually transferred in some kind of chunks (e.g. 128 bytes with Xmodem). It's no too difficult to keep one chunk in the RAM and read more when that's written. -- Tauno Voipio tauno voipio (at) iki fi
Tosca Berisha wrote:
> I need to determine the size of a function or module since I need to > temporary relocate the function or module from flash into sram for > firmware updates. > > How can I find that out during runtime. The > sizeof( myfunction) > generates an error saying "size of function unknown". > > Thanks.
In ELF files generated by GCC, the symbol table has not only the name, type (FUNC), and address of each symbol, but its size as well. Thus the symbol table in the ELF file will tell you how big the code for the function is; something like objdump usually does not print out this information, but it is there.
On 2005-11-01, Tauno Voipio <tauno.voipio@INVALIDiki.fi> wrote:

>>>The amount of code needed in RAM for Flash writing is pretty >>>small: about 250 bytes on an ARM for garden-variety AMD >>>Flashes. >> >> But where is the "flash writing" code getting the data? >> >> In cases I've dealt with the "flash writing" code has to >> impliment some sort of communications protocol in order to >> receive the data to be programmed into flash. In the product >> I'm working with right now, it takes 3KB of code to do a flash >> update. That's a pretty significant chunk out of my 32KB of >> RAM. > > You do not need to keep the whole chunk in RAM at the same > time. Also, only the inner loop of a Flash writer is necessary > to be kept in RAM, the rest can reside in the Flash.
You're right. I could split up the loader and keep part of it in flash, but it's extra work and it doesn't buy me anything. Once the decision is made to update flash, the entire RAM space becomes available. The data that's there belongs to an application that's being erased. It's a lot simpler to just copy the entire loader into RAM and run it from there. Up until that point, the loader is using 0 bytes of RAM.
> The code responsible for the handling from the unlock sequence > till the chip responds ready to poll has to be in RAM, but > this is for erasing a segment or writing a single byte. The > rest of code can be safely in the Flash without any problems.
It could, but there's no advantage to doing so.
> The incoming data is usually transferred in some kind of > chunks (e.g. 128 bytes with Xmodem). It's no too difficult to > keep one chunk in the RAM and read more when that's written.
Right. -- Grant Edwards grante Yow! The Osmonds! You are at all Osmonds!! Throwing up visi.com on a freeway at dawn!!!
On 2005-11-01, diablovision@yahoo.com <diablovision@yahoo.com> wrote:
> > Tosca Berisha wrote: >> I need to determine the size of a function or module since I need to >> temporary relocate the function or module from flash into sram for >> firmware updates. >> >> How can I find that out during runtime. The >> sizeof( myfunction) >> generates an error saying "size of function unknown". >> >> Thanks. > > In ELF files generated by GCC, the symbol table has not only > the name, type (FUNC), and address of each symbol, but its > size as well. Thus the symbol table in the ELF file will tell > you how big the code for the function is; something like > objdump usually does not print out this information, but it is > there.
The ELF file isn't available to the program at run-time. It's quite simple to put global simbols at the beginning and end of a section. Then all you have to do in C is declare those symbols as external char arrays. -- Grant Edwards grante Yow! I'm having an at EMOTIONAL OUTBURST!! But, visi.com uh, WHY is there a WAFFLE in my PAJAMA POCKET??
On Tue, 01 Nov 2005 21:31:35 -0000, Grant Edwards <grante@visi.com> wrote:

>On 2005-11-01, Tauno Voipio <tauno.voipio@INVALIDiki.fi> wrote: > >>>>The amount of code needed in RAM for Flash writing is pretty >>>>small: about 250 bytes on an ARM for garden-variety AMD >>>>Flashes. >>> >>> But where is the "flash writing" code getting the data? >>> >>> In cases I've dealt with the "flash writing" code has to >>> impliment some sort of communications protocol in order to >>> receive the data to be programmed into flash. In the product >>> I'm working with right now, it takes 3KB of code to do a flash >>> update. That's a pretty significant chunk out of my 32KB of >>> RAM. >> >> You do not need to keep the whole chunk in RAM at the same >> time. Also, only the inner loop of a Flash writer is necessary >> to be kept in RAM, the rest can reside in the Flash. > >You're right. I could split up the loader and keep part of it >in flash, but it's extra work and it doesn't buy me anything. >Once the decision is made to update flash, the entire RAM space >becomes available. The data that's there belongs to an >application that's being erased. It's a lot simpler to just >copy the entire loader into RAM and run it from there. Up >until that point, the loader is using 0 bytes of RAM.
... so just assume the function occupies all the RAM, and copy that many bytes.
Tosca Berisha <tberisha@uucp.gov> wrote:

> How can I find that out during runtime.
No way. A portable program has no way at all of finding this out, i.e. it cannot be done "in C" at all. And even a non-portable program, using features outside the C programming language proper, typically won't be able to do this at run-time. Stuff like this has to be set up at link time, the latest, and often you'll need to do it at compile time already. There's even a non-negligible probability that it can't be done at all, or only in assembly. Some toolsets have special extensions (#pragma or __attribute__()) in the source, or some magic incantation to put in the linker commands) that tell the linker a particular function will be stored in a location different from the one it's meant to run from. -- Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.
On 2005-11-02, Mike Harrison <mike@whitewing.co.uk> wrote:

>>You're right. I could split up the loader and keep part of it >>in flash, but it's extra work and it doesn't buy me anything. >>Once the decision is made to update flash, the entire RAM space >>becomes available. The data that's there belongs to an >>application that's being erased. It's a lot simpler to just >>copy the entire loader into RAM and run it from there. Up >>until that point, the loader is using 0 bytes of RAM. > > ... so just assume the function occupies all the RAM, and copy > that many bytes.
Sure, but once you've put in a label so you know where the function starts, putting in a second one so you know where it ends only takes a couple more keystrokes. -- Grant Edwards grante Yow! An air of FRENCH at FRIES permeates my visi.com nostrils!!
Grant Edwards <grante@visi.com> wrote:

> Sure, but once you've put in a label so you know where the > function starts, putting in a second one so you know where it > ends only takes a couple more keystrokes.
Except that unlike the single starting point, which usually must exist for the C function to be callable from unrelated translation units, there's no particular reason for a given C function to even *have* exactly one end where such a label could be put. Nor is there a requirement that the entry point be at the start of the code region for that function. There's not even a requirement that a C compiler would have to translate a single function to a single, consequtive block of code. Optimization by function tail merging exists. As I stated elsewhere in this thread: it's easily possible that on a given platform the only way of pulling this off is by coding all the relevant parts in assembler. -- Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.
On 2005-11-02, Hans-Bernhard Broeker <broeker@physik.rwth-aachen.de> wrote:
> Grant Edwards <grante@visi.com> wrote: > >> Sure, but once you've put in a label so you know where the >> function starts, putting in a second one so you know where it >> ends only takes a couple more keystrokes. > > Except that unlike the single starting point, which usually > must exist for the C function to be callable from unrelated > translation units, there's no particular reason for a given C > function to even *have* exactly one end where such a label > could be put.
Nonsense. There is some address X such that all bytes in the function have addresses less than X. Unless you've got some weird non-linear memory addressing scheme.
> Nor is there a requirement that the entry point > be at the start of the code region for that function.
That's why adding global labels before and after the function is much safer than useing the function pointer for anything.
> There's not even a requirement that a C compiler would have to > translate a single function to a single, consequtive block of > code. Optimization by function tail merging exists.
It may not be a requirement, but I've never seen a C compiler that didn't. This is comp.arch.EMBEDDED. We've got to work with real-world toolchains here, not some imaginary "could do anything the ISO spec allows" toolchain. comp.lang.c is that way --->
> As I stated elsewhere in this thread: it's easily possible > that on a given platform the only way of pulling this off is > by coding all the relevant parts in assembler.
I've been doing embedded C for 20 years on a dozen different target architectures and at least as many toolchains. I've never seen a target/toolchain where what the OP wants isn't easily doable with some trivial linker-script hacking. -- Grant Edwards grante Yow! WHOA!! Ken and at Barbie are having TOO visi.com MUCH FUN!! It must be the NEGATIVE IONS!!
Grant Edwards wrote:
> > I've been doing embedded C for 20 years on a dozen different > target architectures and at least as many toolchains. I've > never seen a target/toolchain where what the OP wants isn't > easily doable with some trivial linker-script hacking.
OK. Have a look at the Hi-Cross C Compiler. It translates every function into a separately linked unit. The units are linked in only if there are references to them. The addresses allocated by the linker for consecutive functions are not consecutive. For the reasons in this discussion (Flash writer) I tried to find the function sizes, but failed miserably. The binary file created was also a jumble of criss- crossed function-size pieces, so that I had to make an extra pre-sorting and merge pass before writing to Flash. My guess is that the functions were ordered by the stored call tree order collapsed in a weird way. -- Tauno Voipio tauno voipio (at) iki fi