while using Keil8.04 compiling and link, there is a fatal error: *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?DISP_MOTORSETUP?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?_LCD_SHOWCHAR?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?_LCD_SHOWHZ?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?_LCD_SHOWSTR?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?DISP_CYCLICSETUP?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?DISP_MOTORRUNSETUI?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?DISP_GENERALSETUI?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?DISPAR_TIME?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?DISPAR_STARTTIME?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?DISPAR_ALARMTEMP?MAIN *** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?MAIN CALLER: ?PR?SETUP_MOTORRUNPAR?MAIN *** FATAL ERROR L232: APPLICATION CONTAINS TOO MANY RECURSIONS Target not created.
I don't konw why, if there are some error while use function pointer or the pro struct include too many layers? waiting for your idears. this problem has pazzled me several days. If mesessary, i can upload my code for you !
if there are some error while use function pointer
Using function pointers should be avoided when using the C51 compiler.
If you insisit on using them, be very, very sure to read and follow the instructions given in the compiler manual regarding this topic.
You may, for example, have to modify the linkers calling tree manually.
thanks for you replay, in detail, the function pointer was used for my menu, and in the display program, constant pointer was used to pointed to strings of my menu's char, and i also saw others had the same problems, but i can't find any avalible mothod, could you please have a look at my code ,and give me some advice?
Don't just sit there puzzling - do some research.
eg, use the online help for warning L13 - or look it up in the Manual: http://www.keil.com/support/man/docs/bl51/bl51_l13.htm
read the related Knowledgebase Articles, and follow the links to More Information
Similarly for error L232: http://www.keil.com/support/man/docs/bl51/bl51_l232.htm
Use the 'Search' facility to find information about Function Pointers in C51; eg, http://www.keil.com/appnotes/docs/apnt_129.asp
etc, etc,...
function pointer was used for my menu, and in the display program, constant pointer was used to pointed to strings of my menu
Note that the string constants in a .c file live in the same segment as the code in that .c file. If you have a table of function pointers, as for a menu, the the data refers to the functions (via this table), and the functions refer to the data (if they print strings, for example). Even though this really isn't recursion, it appears to the linker that way. Hence the warning.
I dislike ignoring warnings. The workarounds here involve splitting the .c file into pieces. You can move the function pointer table, or you can move the string constants. Either way clutters the global namespace and causes you to create extra .h files or extern definitions that really shouldn't be necessary.
This is one reason I wish for the ability to name segments with C51. That way, I could keep all the self-contained data in one modular file, yet split the data into two segments to avoid the apparent recursion.
uchar Setup_MotorPar(void)reentrant; uchar Setup_CyclicPar(void) reentrant; uchar Setup_GeneralPar(void) reentrant; uchar Setup_MotorRunPar(void) reentrant;
uchar Disp_GeneralSetUI(void)reentrant; uchar Disp_MotorRunSetUI(void) reentrant; uchar Disp_MotorSetup(void)reentrant; uchar Disp_CyclicSetup(void) reentrant;
typedef struct{ uchar Key_NowIndex;
uchar KeyEtr_State; uchar KeyUp_State; uchar KeyDo_State; uchar KeyAdd_State; uchar KeyDec_State; uchar KeySel_State; uchar KeyLaug_State; uchar KeyMode_State; uchar KeyCancel_State; uchar KeyEsc_State;
uchar (*Current_Operate)() reentrant; } KeyTab_Struct; // #define Size_Of_Key_Tab 21 code KeyTab_Struct KeyTab[Size_Of_Key_Tab]={ // Ind C 上 下 åŠ å‡ S L M CL ES { 0, 1, NA, NA, NA, NA, NA, 0, NA, NA, NA, DispUI_Main }, //0 // { 1, 2, 1, 1, NA, NA, NA, 0, 1, NA, 0, DispUI_View }, // { 2, 2, NA, NA, NA, NA, NA, NA, 2, NA, 0, DispUI_Setup}, { 1, 11, 2, 10, NA, NA, NA, NA, 1, NA, 0, Disp_MotorSetup }, { 2, 12, 3, 1, NA, NA, NA, NA, 2, NA, 0, Disp_MotorSetup }, { 3, 13, 4, 2, NA, NA, NA, NA, 3, NA, 0, Disp_MotorSetup }, { 4, 14, 5, 3, NA, NA, NA, NA, 4, NA, 0, Disp_MotorSetup }, { 5, 15, 6, 4, NA, NA, NA, NA, 5, NA, 0, Disp_CyclicSetup }, { 6, 16, 7, 5, NA, NA, NA, NA, 6, NA, 0, Disp_CyclicSetup }, { 7, 17, 8, 6, NA, NA, NA, NA, 7, NA, 0, Disp_CyclicSetup }, { 8, 18, 9, 7, NA, NA, NA, NA, 8, NA, 0, Disp_CyclicSetup }, { 9, 19, 10, 8, NA, NA, NA, NA, NA, NA, 0, Disp_MotorRunSetUI}, {10, 20, 1, 9, NA, NA, NA, NA, NA, NA, 0, Disp_GeneralSetUI },
{11, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1, Setup_MotorPar }, {12, NA, NA, NA, NA, NA, NA, NA, NA, NA, 2, Setup_MotorPar }, {13, NA, NA, NA, NA, NA, NA, NA, NA, NA, 3, Setup_MotorPar }, {14, NA, NA, NA, NA, NA, NA, NA, NA, NA, 4, Setup_MotorPar }, {16, NA, NA, NA, NA, NA, NA, NA, NA, NA, 6, Setup_CyclicPar }, {17, NA, NA, NA, NA, NA, NA, NA, NA, NA, 7, Setup_CyclicPar }, {18, NA, NA, NA, NA, NA, NA, NA, NA, NA, 8, Setup_CyclicPar }, {19, NA, NA, NA, NA, NA, NA, NA, NA, NA, 9, Setup_MotorRunPar }, {20, NA, NA, NA, NA, NA, NA, NA, NA, NA, 10, Setup_GeneralPar },
};
uchar KeyFunc_IndexBef; uchar KeyFunc_IndexNow; uchar (*KeyFun_Ptr)(void) ; //typedef char(*FuncPtr)();
All of above is my menu define. in detail, the constant string of UI is strored in the main.h, and the menu define is located in the main.c, the constant strings were called by the function Disp_MotorSetup ... and the function Disp_MotorSetup ..were called by a function pointer which is defined above.
... that you code is entirely unreadable?
Please read the instructions on how to post source code - they are really quite clearly stated: www.danlhenry.com/.../keil_code.png
Note that TABs don't work (well) - use spaces instead,
and don't forget to check it in the 'Preview'...
thanks for your advice, this is the first time I post messeage in the forum. The followings are my code: <per>
//the declaration of the functin uchar Setup_MotorPar(void); uchar Setup_CyclicPar(void); uchar Setup_GeneralPar(void); uchar Setup_MotorRunPar(void);
uchar Disp_GeneralSetUI(void); uchar Disp_MotorRunSetUI(void); uchar Disp_MotorSetup(void); uchar Disp_CyclicSetup(void);
uchar (*Current_Operate)() reentrant; } KeyTab_Struct;
#define Size_Of_Key_Tab 21 code KeyTab_Struct KeyTab[Size_Of_Key_Tab]={ { 0, 1, NA, NA, NA, NA, NA, 0, NA, NA, NA, DispUI_Main }, //0 { 1, 11, 2, 10, NA, NA, NA, NA, 1, NA, 0, Disp_MotorSetup }, { 2, 12, 3, 1, NA, NA, NA, NA, 2, NA, 0, Disp_MotorSetup }, { 3, 13, 4, 2, NA, NA, NA, NA, 3, NA, 0, Disp_MotorSetup }, { 4, 14, 5, 3, NA, NA, NA, NA, 4, NA, 0, Disp_MotorSetup }, { 5, 15, 6, 4, NA, NA, NA, NA, 5, NA, 0, Disp_CyclicSetup }, { 6, 16, 7, 5, NA, NA, NA, NA, 6, NA, 0, Disp_CyclicSetup }, { 7, 17, 8, 6, NA, NA, NA, NA, 7, NA, 0, Disp_CyclicSetup }, { 8, 18, 9, 7, NA, NA, NA, NA, 8, NA, 0, Disp_CyclicSetup }, { 9, 19, 10, 8, NA, NA, NA, NA, NA, NA, 0, Disp_MotorRunSetUI}, {10, 20, 1, 9, NA, NA, NA, NA, NA, NA, 0, Disp_GeneralSetUI },
uchar KeyFunc_IndexBef; uchar KeyFunc_IndexNow; uchar (*KeyFun_Ptr)(void);
</per>
All of above is my menu define. in detail, the constant string of UI is strored in the main.h, and the menu define is located in the main.c, the constant strings were called by the function Disp_MotorSetup ... and the function Disp_MotorSetup ..were called by a function pointer which is defined above
instead of (abbreviated)
//uchar Setup_MotorPar(void); uchar Setup_CyclicPar(void); {14, NA, NA, NA, NA, NA, NA, NA, NA, NA, 4, Setup_MotorPar }, {16, NA, NA, NA, NA, NA, NA, NA, NA, NA, 6, Setup_CyclicPar }, do this: uchar Setup_MotorPar(void); uchar Setup_CyclicPar(void); #define SMP 1 // Setup_MotorPar(void); #define SCP 2 // Setup_CyclicPar(void); {14, NA, NA, NA, NA, NA, NA, NA, NA, NA, 4, SMP }, {16, NA, NA, NA, NA, NA, NA, NA, NA, NA, 6, SCP }, then in the routine: switch (table.offset) // whatever it is { case SMP: Setup_MotorPar(); break; case SCP: Setup_CyclicPar(); break; }
had this been another processor than the '51 I might very well have done like you, but the '51 has its pecularities and working with them is so much more fruitful that trying to fight them
Erik
Thanks for you reply. That is a selectable way to avoid function pointer, in cost, there should be another 'switch-case' for my menu. I had modified the struct arry, just like below:
<per> code struct fuc_index Fuc_table[--]={ .. {14, NA, NA, NA, NA, NA, NA, NA, NA, NA, 4, Setup_MotorPar }, {16, NA, NA, NA, NA, NA, NA, NA, NA, NA, 6, Setup_CyclicPar }, .. };
I just modified 'code' to 'xdata',and the recursion warnning were all disappeared, but while the program running, and calling function using function pointer, no error but it was a Ilegal Pointer which was pointed by keil, I am not very clearly about it, If the storing way of the constant struct which concluds constant function pointer lead to the error?
That is a selectable way to avoid function pointer
you are using TWO things that the '51 architecture is singularily unsuited for "function pointers' and "recursive calls".
What I suggested was to get rid of BOTH.
If 'programmers convenience' is more important to you that 'process effiecienmcy' then what you are doing is just fine, but the overhead of using these twu things that the '51 must be "wrangled into" performing is very likely to get you on trouble some day.
The case of a "working code" falling apart the day you are asked to make a "nominal addition" is not unheard of.
"I just modified 'code' to 'xdata'"
That can't possibly work!
A function pointer obviously has to point to CODE space, doesn't it?
Note that the tags are 'pre' and '/pre' - not 'per' and '/per' This should be obvious from the preview...