AVR: Confused About an Array of Functon Pointers at Runtime

I have some code that I am running on an atmega169. I am building a static array of function pointers like so:

typedef uint8_t (*routine)(void);

extern routine testRoutine; extern routine testRoutine2;

routine routines[] = { (routine)&testRoutine, (routine)&testRoutine2 };

This compiles and links fine and at runtime the "routines" array contains the addresses that are found for testRoutine and testRoutine2 when I do avr-nm on the .elf file for the project. However, when I load the hex file onto the device and debug it - there is no code at those addresses so when the jump is performed it executes the opcode

0xff which is found there. This seems impossible as I thought that avr- nm was using post link addresses. I don't see how the addresses could change post link. I am sure I am missing something obvious here. Please enlighten me. Thanks.
Reply to
the el vez
Loading thread data ...

typedef uint8_t routine(void);

uint8_t testRoutine(void); uint8_t testRoutine2(void);

routine* routines[] = { testRoutine, testRoutine2 };

Leo Havmøller.

Reply to
Leo Havmøller

snipped-for-privacy@e65g2000hsc.googlegroups.com...

That worked perectly! However, now I am really confused as avr-nm still shows those routines at the higher addresses. And in fact - everything that is listed from avr-nm seems totally out of whack. What gives? Any detailed explaination is greatly greatly appreciated.

Reply to
the el vez

I don't know AVR but it's sounds like in your original case the linker didn't see the references to your functions and decided not to include them while in the second case the reference to the function name, not just the address, was enough to convince the linker to put it in. In this situation I'd create a couple of dummy calls to your functions to see if that solves the problem,

e.g.

int main(void) { extern dummy; // have int dummy=0; in some other module to make sure the optimizer can't figure out what you're up to if (dummy) { testRoutine(); testRoutine2(); } ... }

Andrew

Reply to
andrew queisser

I think there are 2 errors here:

1) testRoutine and testRoutine2 are pointers to functions, they are not functions. At run-time you have to initialize them with the addresses of executable functions, otherwise they are uninitialized and points to nothing. What you see as initialized correctly is just the address of a pointer. 2) You shouldn't use the & operator in your array. It does not show a compile error only because you casted to routine.
Reply to
Adrian

It might be optimising the routines away. If you have no direct calls to these routines, the linker or compiler may remove the code as being "dead code". Try adding a dummy call to one of the routines somwhere. Your toolset probably has some directive with which you can tell the compiler / linker that the code is not dead code, and should not be removed.

Regards Anton Erasmus

Reply to
Anton Erasmus

In that event, I would consider the compiler was too clever for its own good. A pointer to a function is a reference to that function, as surely as a call is.

Reply to
David R Brooks

I cannot which compilers I used that had this behaviour, but it was very aggresive in it's dead code removal. There wer special #pragmas to indicate to the compiler that a functions was being called through some sort of indirect calling mechanism. AFAICR part of the "problem" on why it could not alwyas figure things out correctly was that the linker was single pass.

Regards Anton Erasmus

Reply to
Anton Erasmus

Indeed. IIRC I encountered this dead-code removal issue with a Keil8051 compiler some yrs back. I think there was a pragma available to let the tools know to not optimize the functions out....

Bo

Reply to
Bo

I'm reasonably sure you remember that backwards. C51 would only err on the side of caution here (and complain about it rather loudly), i.e. it included all uncalled functions in the final program, at considerable costs to overall RAM consumption because it disturbs call tree analysis.

Reply to
Hans-Bernhard Bröker

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.