Hi all Further to the issue of storing a table of function pointers into flash, and accessing this table accurately..
I've tried several variations, and looked at the .lst files in each case. Some variations were more elegant to the C purist, but caused severe code bloat, even at -O3. But I've arrived at a scheme which for me gives the most efficient and (under the circumstances) most readable code: // make a 'ptr to func' type to help readability typedef void (*FuncPtr)(void); // make a pseudo-type to access function tables, so we can // have a 'function table handle' typedef uint16_t FuncPtrTable; // declare our table of funcs, put it into flash FuncPtr funcs_table[] PROGMEM = { func1, func2, func3 }; // define a macro to create a 'function pointer table handle' #define pgm_get_functab(tab) (FuncPtrTable)(&tab[0]) // define a macro to read a pointer from the function table #define pgm_read_fptr(taddr, i) \ ((FuncPtr)(pgm_read_word(taddr+((i)<<1)))) // now let's use this stuff int main() { // declare our pointer to function FuncPtr fptr; // create a 'function table handle' FuncPtrTable ftab = pgm_get_functab(funcs_table); ... // get a pointer off the table, and invoke it fptr = pgm_read_fptr(ftab, i); (*fptr)(); // or more simply - this works just the same (*pgm_read_fptr(ftab, i))(); ... } I tried the approach of: fptr = (FuncPtr)pgm_read_word(&funcs_table[0] + i * 2); but it has a huge footprint of 48 bytes - terrible for repeated use. Hence the notion of setting up a 'function table handle', then using it with the 'pgm_read_fptr()' macro - much shorter at around 8 bytes. Anyway, I hope all this might help in the future with others battling to learn gcc-avr and how to do flash-based function tables. If anyone can come up with a scheme that's better - for code readability and/or compactness, I'd be grateful to hear about it. Cheers David _______________________________________________ AVR-GCC-list mailing list AVR-GCC-list@nongnu.org http://lists.nongnu.org/mailman/listinfo/avr-gcc-list