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".
You'll need to do something in your linker script to create global symbols before and after the function. In your C code, you should then be able to take the address of those global symboals and do some math to determine the size.
--
Grant Edwards grante Yow! UH-OH!! We're out
at of AUTOMOBILE PARTS and
visi.com RUBBER GOODS!
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.
--
Grant Edwards grante Yow! I'll show you MY
at telex number if you show
visi.com me YOURS...
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.
--
Grant Edwards grante Yow! Xerox your lunch
at and file it under "sex
visi.com offenders"!
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.
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.
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.
It could, but there's no advantage to doing so.
Right.
--
Grant Edwards grante Yow! The Osmonds! You are
at all Osmonds!! Throwing up
visi.com on a freeway at dawn!!!
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??
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.
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!!
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.
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.
That's why adding global labels before and after the function is much safer than useing the function pointer for anything.
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 --->
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!!
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.
Indeed, such an address X must exist --- but calling 'the end' of that function may be premature. There's no general way of making sure that between X and that other label, you'll have enclosed significantly less than the entire program, and even less that positioning such labels in the C source has any relation with the actual address range covered by (fragments of) the function.
And that's only scratching the surface. Next you'll have to worry about other functions being called by the function in question, often without the C source showing any sign of their existence. E.g. on some C-unfriendly architecture, accessing a structure element in an array of structures in "far" memory can easily cost 3 or more calls to "secret" C runtime library functions.
Then, with all due respect, you haven't been looking closely enough.
Let's stay right here, shall we? I hope we can agree that Keil C51 (current version) is quite definitely a realq-world toolchain, and as embedded as they come, right? So: inspect what its optimization options like "reuse common entry code", "common block subroutines", and particularly the machinery they call "linker code packing" can do.
Fact is that a single function can fall apart into multiple distinct blocks of code, which the linker can principally distribute all over the place, if it so wishes, and that toolchains doing this not actually exist, but are highly relevant in this newsgroup.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
I never said anything about position labels in C source. I thought I was quite explicit that I was talking about using the linker script for placing symbols before/after the memory section containing the function.
Of course.
Then relocating that function probably won't work if the called functions aren't available. It's quite easy to determine if that's the case by looking at the generated assembly.
Then don't use those optimizations.
With all the toolchains I've used, there was always a way to place a function into a distinct section of memory such that that section's start/end addresses could be made globally visible at link-time. It may have required placing the function in a separate file and not using optimizations, but it was never that hard. If the Keil 51 compiler really is that difficult to work with, then I'm glad I never had to use it.
--
Grant Edwards grante Yow! Excuse me, but didn't
at I tell you there's NO HOPE
visi.com for the survival of OFFSET
PRINTING?
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.