Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Programming Error with 8051

Status
Not open for further replies.

ucsam

Advanced Member level 4
Joined
Oct 12, 2010
Messages
119
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,298
Location
kathmandu,nepal
Activity points
2,058
Hello everyone!

I am working on a project with an interrupt, i have a function that i called by both main function and the interrupt vector function but not at the same time. I have got the following errors please look ate them and let me know what does the error means and what is to be done to eliminate it


Build target 'Target 1'
linking...
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?_ARM_UP?CHK_CODE
CALLER1: ?PR?SIGNAL?CHK_CODE
CALLER2: ?C_C51STARTUP


Thank you!
 

CAUSE
Warning 15 indicates that the linker has found a function that may be called from both main code and an ISR (or functions called by an ISR) or from multiple ISRs at the same time.

One problem is that the function is not reentrant and it may get invoked (by an ISR) while the function is already executing. The result will be variable and probably involve some form of argument corruption.

Another problem is that memory used for local variables and arguments may be overlaid with the memory of other functions. If the function is invoked by an interrupt, that memory will be used. This may cause memory corruption of other functions.

For example, for your first warning 15 the WRITE_GMVLX1_REG function is being called from multiple roots. This function is defined in the file D_GMVLX1.C or D_GMVLX1.A51. It is called from both an ISR (or a function called by an ISR) and the function VSYNC_INTERRUPT in MAIN.C

RESOLUTION
There are several ways to solve this problem.

Method 1
If you are certain that the function is not executed in a reentrant fashion and that there is no physical memory used by the function (only registers are used), then you may simply choose to ignore this warning.

If arguments are passed in registers and if the function uses only registers during its execution, the function may be reentrant. However, you must be very careful that changes to compiler or to the compiler settings do not change this.

Method 2
If there is physical memory used by the function, you should use the linker OVERLAY directive to remove the function from overlay analysis. For example:

OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)
This prevents memory used by this function from being overlaid. If this function calls other functions that are also used elsewhere in your program, you may need to exclude those functions from overlay analysis as well. This overlay command makes the linker happy and removes the Warning 15 for this function.

The function is not reentrant. However, it may be called from multiple threads without corrupting other function memory. Nonetheless, you must ensure that the function is not called simultaneously by multiple threads.

Method 3
If the function could be called while it is executing then things become slightly more complex. You may:

Disable interrupts whenever the function is called from main code. You may use #pragma disable with the function that is called. You must also use the OVERLAY directive to remove the function from overlay analysis.
Make two copies of the function. One for main code and one for ISR code.
Make the function reentrant. For example:
void myfunc(void) reentrant {
...
}
This results in a reentrant stack being used to store arguments and local variables. With this method the reentrant stack must be configured in the STARTUP.A51 file. This consumes more RAM and slows down execution of the reentrant function.
 
thanks brother !! ( i hope i can say that :) ) your post was really very helpful!! though i didn't understand much, i am going to use the solution 3 !!

thanks again!!
 

simply write down reentrant keyword after your function which you are calling from interrupt & from other routines.

e.g.

void Function_1 (void) reentrant;
void Function_2 (void);

void Function_1 (void) reentrant
{
line 1....;
line 2....;
}


void Function_2 (void)
{
line1...;
line2...;
Function_1();
line3...;
}

void ISR (void) interrupt 2
{
line1...;
Function_1();
line2...;
line3...;
}

this will not give you any warning...
 
  • Like
Reactions: ucsam

    ucsam

    Points: 2
    Helpful Answer Positive Rating
Thank you everyone! i got only the 3 solution. Can u please explain me about the solution number 2 though i already solved it with solution 3! what is the use of using "reentrant" what does it tell the complier to do?
 

You can search "reentrant" on keil web site
u will get good explanation about it
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top