Just as the compiler has added custom support for bits, it should also add custom support for function pointers. Here is one idea:
//Saves on storage (1 byte) //Is faster (fixed jump table) //No need to add/remove references in the linker void fn1( void ){}; void fn2( void ){}; void fn3( void ){}; void fn4( void ){}; enumfn MyFnType { fn1, fn2, fn3 }; //must have same signatures MyFnType myFnVar; void FnA(void) { myFnVar = fn1; // do not add fn1 to FnA's call tree myFnVar = fn4; // compiler error } void FnB(void) { (myFnVar)(); // do add fn1,fn2,fn3 to FnB's call tree }
You can accomplish the same thing with the tools now. Refer to the "TABLES OF FUNCTION POINTERS" section in the following application note: http://www.keil.com/appnotes/docs/apnt_129.asp Jon
Even though I am into "Tree preservation", not having to use the error prone OVERLAY directive sounds great. Can you help me? My simple example fails. I must be missing something.
void fn1(void){ } void fn2(void){ } void fn3(void){ } code void (code *fp_tab [])(void) = { fn1, fn2, fn3 }; void ( code* fp)(void); void fn( void ) { fp = fp_tab[0]; } void main(void) { fn(); (*fp)(); } ?C_C51STARTUP +--> ?PR?MAIN?STATETEST ?PR?MAIN?STATETEST +--> ?PR?FN?STATETEST ?? where is ?CO?STATETEST ?PR?FN?STATETEST +--> ?CO?STATETEST ?? ?CO?STATETEST should not be here ?CO?STATETEST +--> ?PR?FN1?STATETEST +--> ?PR?FN2?STATETEST +--> ?PR?FN3?STATETEST
; FUNCTION fn (BEGIN) ; SOURCE LINE # 12 ; SOURCE LINE # 13 ; SOURCE LINE # 14 0000 900000 R MOV DPTR,#fp_tab 0003 E4 CLR A 0004 93 MOVC A,@A+DPTR 0005 FE MOV R6,A 0006 7401 MOV A,#01H 0008 93 MOVC A,@A+DPTR 0009 8E00 R MOV fp,R6 000B F500 R MOV fp+01H,A ; SOURCE LINE # 15 000D 22 RET ; FUNCTION fn (END)
Since only constants are involved, the compiler should be able to optimize the "fp = fp_tab[0];" to a simple move. Instead you get... The 8051 only provides one instruction for reading code memory: MOV A, @A+DPTR. The code generated by the compiler looks pretty optimal to me. Can you suggest a better solution? Jon
How about mov fp,#high(fn1) mov fp+1,#low(fn1)
View all questions in Keil forum