We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I want to call a number of functions with function pointers. I have studied a number of posts and App. notes, including APNT 129 and I am still getting a linker error. On page 7 of APNT 129 is says:- The following is a function pointer table definition that C51 and BL51 can handle automatically: code long (code *fp_tab []) (void) = { func1, func2, func3 }; Note that the only difference is storing the table in CODE space. and later:- As long as the function pointer table is located in a separate source file, C51 and BL51 make all the correct links in the call tree for you. I assume the .h file is OK for "a separate source file"
Here is my code:- in the myprog.h file:-
extern uchar set_day(uchar xpos, uchar ypos, uchar action); extern uchar set_hours(uchar xpos, uchar ypos, uchar action); extern uchar set_mins(uchar xpos, uchar ypos, uchar action); // Function pointer table code uchar(code *set_table[])(uchar, uchar, uchar) = {set_day, set_hours, set_mins};
in the myprog.c file:-
#include "myprog.h" /* Declarations*/ ........ ........ main(){ ..... ..... // function called with:- (*set_table[0])(an_xval, a_yval, an_action); ..... ..... ..... } // Functions:- (after main() in myprog.c) uchar set_day(uchar xpos, uchar ypos, uchar action){ ... ... } set_hours(uchar xpos, uchar ypos, uchar action){ ... ... } set_mins(uchar xpos, uchar ypos, uchar action){ ... ... }
When I link this, I get three L13 warnings. The M51 file reports:-
... ... PROGRAM RECURSIONS REMOVED FROM CALL TREE ========================================= +--> ?CO?RGE_MAIN_04 <--+ ?PR?_SET_DAY?RGE_MAIN_04 +--> ?CO?RGE_MAIN_04 <--+ ?PR?_SET_HOURS?RGE_MAIN_04 +--> ?CO?RGE_MAIN_04 <--+ ?PR?_SET_MINS?RGE_MAIN_04 ... ... *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?RGE_MAIN_04 CALLER: ?PR?_SET_DAY?RGE_MAIN_04 *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?RGE_MAIN_04 CALLER: ?PR?_SET_HOURS?RGE_MAIN_04 *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?RGE_MAIN_04 CALLER: ?PR?_SET_MINS?RGE_MAIN_04
I would rather not have these warnings but is it safe to ignore them, bearing in mind the code seems to work when I download it. (I have only called the first pointer so far.)
Note that the message says "recursive call to segment". This is not a warning about a recursive function. It means that the entire code segment -- the .c file -- refers to itself. There's a function that calls other functions from the table of pointers. That table is part of the same segment. Those functions likely also call other functions or constant data in that segment. Hence, the recursion.
If you move the function pointer table to a separate .c file as recommended by the app note, the warnings should go away, because then the functions and table will be in separate segments.
Andy and Drew,
Thanks for your help. Yes, it works when I move the pointer to a separate .c file and not a .h file. I had a bit of fun working out how to declare it, however. One must initialise and assign the pointer in the separate file but then you have to tell the compiler where the function names are to which the thing points without getting involved in more recursions.
The way I did this was to put the function prototypes in the header file and include this file in both the main and function pointer source files:-
// func_ptr_tab.c #include myprog.h // Function pointer table code uchar(code *set_table[])(uchar, uchar, uchar) = {set_day, set_hours, set_mins}; .....
Then in myprog.h:-
..... uchar set_day(uchar xpos, uchar ypos, uchar action); uchar set_hours(uchar xpos, uchar ypos, uchar action); uchar set_mins(uchar xpos, uchar ypos, uchar action); .....
Finally, myprog.c is the same as before.
Cheers,
Simon
"The way I did this was to put the function prototypes in the header file and include this file in both the main and function pointer source files"
Yes, that is the normal way to "publish" symbols to be accessed by external modules - it's not specific to function pointers or Keil.