Hello ALL! I would ask the next question... according http://www.keil.com/support/docs/2379.htm one must manually remove the reference between func2 and the ?CO?EXAMPLE1 segment and add MAIN ! FUNC2 reference between MAIN and FUNC2. But from App129 if I define code void (*func_array[])() = { func2 }; with the storing table in code space, I will get the correct call tree. Now is a question: if I would not make this overlay command like sad in the http://www.keil.com/support/docs/2379.htm bl51 EXAMPLE1.OBJ IX OVERLAY & (?CO?EXAMPLE1 ~ FUNC2, MAIN ! FUNC2) would I have any problem? How I understood it's harmless because there are no actual recursive calls in the code, just a reference from one item in the constant segment to another. Could somebody please make it a little bit more clear for me? Thank you very much, A.
See: http://www.keil.com/support/man/docs/lx51/lx51_overlaying.htm R.
thank you very much for your reply, but I still don't have an answer on my quistion about necessity of using overlay in this case. I don't see how the data can be overwritten and the call tree in this case seems to be correct... It would be very nice to get some more help. Thanks, A.
We recommend to use the OVERLAY directive in this context.
Thanks. 1.Does it mean, if one use printf("xxxxx") function to declare the pointer table in CODE space has no any sense anymore. All reference anyway will be done manually. 2.If I understood you correct, my example will be executed correct,(because the data can't be overwritten - there is no real recursion here and the call tree is ok), but to make code clean from linker warnings which indicate recursive calls and to be sure, that any real recursion has occured one should make these overlay operations. is it correct? Thank you very much, with respect, A.
Additionally... For the LX51 linker/locater in the manual "Macro assembler and utilities" in the chapter "Pointer to a function in Arrays or tables" one can find a sentence: "The LX51 linker always ignores the references from constant segments to program code and requires only to add the function calls". I've tried it out and what I saw after I've analysed the map file... During overlay analysis it realy ignores these references, but does not remove it from the call tree, like it does SPEEDOVL in the BL51! It means, one still needs delete the references manually! With best regards, A.
according http://www.keil.com/support/docs/2379.htm one must manually remove the reference between func2 and the ?CO?EXAMPLE1 segment and add MAIN ! FUNC2 reference between MAIN and FUNC2. But from App129 if I define code void (*func_array[])() = { func2 }; with the storing table in code space, I will get the correct call tree. The problem here is that there are 2 different data objects but only 1 data segment in code space. And, since one of them is referenced as a function pointer (or a table of function pointers), the linker must make the assumption that all of these are function pointers. There is a key phrase in the Application Note that you are ignoring: "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." The reason for this is that all CODE globals in a source file are lumped into a single segment. So, if you have function pointers and constant string data, you'll get the problem you describe. Yes. You should use OVERLAY to solve this problem. Or, as the application note suggests, put the function pointer table in a separate source file. Jon
Hello Jon, thanks for your reply. It's everything ok what you wrote. But.. The only "problem" what we have here is just a warning. The reason for it you've just described. The call tree after storing of function pointers table in code space is completely ok. I could see it in the map file. Without overlay the program will be executed correct. And using of overlay would just lead to the clean compilation without any warning L13. May be, it's not a fine way to handle it, but in this case, I don't see any reason that the program will fail. With regards, A.
I don't see any reason that the program will fail. Most developers don't include problems in their code that they KNOW will cause the application to fail. Besides, if they did, and they KNEW that the program would fail, then they are just being irresponsible. Since I have not seen your program, I do not know if it will fail or if it will run as designed. However, I know from experience that failing to make this simple change COULD cause you unexplained problems later (when you are not focused on this issue). And, since you are building in a requirement that a warning is to be ignored you may very well be training your staff to ignore a warning that, while innocuous at this time, may not be later. So, if you don't see any benefit in removing the questionable link in the call analysis, then don't. However, that's not what Keil Software recommends. Jon
ok. Thank you very much! Since I have not seen your program, I do not know if it will fail or if it will run as designed. I've just discussed the ex. code void func1 (unsigned char *msg) { ; } void func2 (void) { int b = 4; int c = 5; func1("xxxxxxxxxxxxxxx"); } code void (*func_array[])() = { func2 }; void main (void) { int a = 5; (*func_array[0])(); } I've added some variables for the test ... The map looks like OVERLAY MAP OF MODULE: HELLO (HELLO) SEGMENT DATA_GROUP +--> CALLED SEGMENT START LENGTH ---------------------------------------------- ?C_C51STARTUP ----- ----- +--> ?PR?MAIN?HELLO ?PR?MAIN?HELLO 0008H 0002H +--> ?CO?HELLO ?CO?HELLO ----- ----- +--> ?PR?FUNC2?HELLO BL51 BANKED LINKER/LOCATER V5.12 05/04/2005 08:33:13 PAGE 2 ?PR?FUNC2?HELLO 000AH 0004H +--> ?PR?_FUNC1?HELLO ?PR?_FUNC1?HELLO 000EH 0003H You see there is no any problem here(only this warning). May be this ex. http://www.keil.com/support/docs/2379.htm is not good for this sort of problems. It would be very interesting to see how this code can fail(without big changes and with function pointers table stored in the code space )... With best regards, A.
It would be very interesting to see how this code can fail(without big changes and with function pointers table stored in the code space )... Very well. The following code (which is a very slight modification of yours) generates the exact same warning and call tree.
void func1 (unsigned char *msg); void func2 (void); code void (*func_array[])() = { func2, }; void func1 (unsigned char *msg) { ; } void func2 (void) { int b = 4; int c = 5; (*func_array[0])(); func1("xxxxxxxxxxxxxxx"); } void main (void) { int a = 5; (*func_array[0])(); while (1); }
Jon, ok, but in this case you have a real recursion(the function calls itself, what I wanted avoid in case if I don't use overlay) and the only one way to make this program running is using of reentrant functions. With best regards, A.