|
|||||||||||
|
Technical Support On-Line Manuals BL51 User's Guide |
BL51 User's GuideIn a RAM VariableWhen a function pointer is assigned to a global variable that is stored in RAM (DATA, IDATA, PDATA, or XDATA), the call tree generated by the linker is inaccurate. For example, given the following example program:
int direct_func (int a, int b, int c)
{
volatile int total = a+b+c;
return (total);
}
int indirect_func (int a, int b, int c)
{
volatile int total = a+b+c;
return (total);
}
int (*fp) (int, int, int) = indirect_func;
int caller (void)
{
int retval;
retval = direct_func(4,5,6);
retval += (*fp) (1,2,3);
return (retval);
}
void main (void)
{
int value;
value = caller();
while (1);
}
The correct Call Tree is illustrated by the following flow chart.
However, indirect_func is referenced only by the initialization code (initseg) that assigns values to variables (fp, the function pointer, in this case). It is not referenced in the caller function. Therefore, the linker generates the following Call Tree and Overlay Map.
FUNCTION/MODULE BIT_GROUP DATA_GROUP --> CALLED FUNCTION/MODULE START STOP START STOP ============================================================= ?C_C51STARTUP ----- ----- ----- ----- +--> ?PR?MAIN?MAIN +--> ?C_INITSEG MAIN/MAIN ----- ----- 0008H 0009H +--> ?PR?CALLER?MAIN CALLER/MAIN ----- ----- 000AH 000BH +--> ?PR?_DIRECT_FUNC?MAIN _DIRECT_FUNC/MAIN ----- ----- 000CH 000DH ?C_INITSEG ----- ----- ----- ----- +--> ?PR?_INDIRECT_FUNC?MAIN _INDIRECT_FUNC/MAIN ----- ----- 0008H 0009H The linker call tree must be adjusted by removing the reference from initseg to indirect_func and adding a reference from caller to indirect_func using the following overlay command: ... OVERLAY(?C_INITSEG ~ indirect_func, caller ! indirect_func) ... After adjusting the call tree, the Overlay Map appears as follows: FUNCTION/MODULE BIT_GROUP DATA_GROUP --> CALLED FUNCTION/MODULE START STOP START STOP ============================================================= ?C_C51STARTUP ----- ----- ----- ----- +--> ?PR?MAIN?MAIN +--> ?C_INITSEG MAIN/MAIN ----- ----- 0008H 0009H +--> ?PR?CALLER?MAIN CALLER/MAIN ----- ----- 000AH 000BH +--> ?PR?_DIRECT_FUNC?MAIN +--> ?PR?_INDIRECT_FUNC?MAIN _DIRECT_FUNC/MAIN ----- ----- 000CH 000DH _INDIRECT_FUNC/MAIN ----- ----- 000CH 000DH ?C_INITSEG ----- ----- ----- ----- Note
| ||||||||||
|
|||||||||||