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.
dear friend,
i have function fSaveData. which is called at depth of 5
void fSaveData( uint8x_t* ucArray, uint16x_t uiStartAddress, uint16x_t uiTotal_Bytes,uint8x_t ucResetFlag)
{
uint16x_t aa; uint16x_t bb; uint8x_t cc; uint16x_t dd; uint16x_t ee; uint16x_t ee; uint16x_t ff; uint8_t gg[15]={0};
// code //code
// withing that function i am calling one more function, depth of 6 fWrite2eeprom(ucArray,uiStartAddress,ucCummBytes,uiIndex,ucResetFlag); //
}
as per http://www.keil.com/support/man/docs/c51/c51_le_funcparmsstack.htm c51 had given fixed addred to each variable. but when i called function fWrite2eeprom then my variable of function fSaveData get courrupts this is happning frequently.
this may be case of stack overflow. but in every courrption i got same value in XRAM fixed location.
please help me on this! please ask if my question is not clear
yogesh
We can't help you out because we don't know what code you run.
You can check if you have a stack overflow.
And you can check, inside fWrite2eeprom() if the address that gets overwritten changes content.
hi,
please see my code.M51
TYPE BASE LENGTH RELOCATION SEGMENT NAME ----------------------------------------------------- * * * * * * * D A T A M E M O R Y * * * * * * * REG 0000H 0008H ABSOLUTE "REG BANK 0" IDATA 0008H 0001H UNIT ?STACK * * * * * * * X D A T A M E M O R Y * * * * * * *
it shows no other variables in internal RAM.
please my startup code
IBPSTACK EQU 0 ; set to 1 if small reentrant is used. ; <o> IBPSTACKTOP: End address of SMALL model stack <0x0-0xFF> ; Set the top of the stack to the highest location. IBPSTACKTOP EQU 0xFE +1 ; default 0FFH+1 .
in startup file rest all other thing are default (generated by keil).
by debugger i seen i am using call depth of 9, so required bytes is 18 only, my stack size is around 240 bytes. so it is very difficult to overflow (i have littel less understanding about this).
in side fWrite2eeprom i am not updating that locations.
please ask me what exactly you need, i will share the required data.
thanks for your support.
Dear All, i got root cause of this problem,
it problem in KEIL C51 compiller. actually when function is called keil complier gives fixed address to all arrguments. The above statement is also ture for function called in interrupt. But if some local variables in interrrupt then it assigning already used address. It overlap the address of ground loop local variables and interrupt local variables.
in my case when ever interrupt is occure it modify 0xXXXX memory which also belong some other local variables in ground loop. this bug in C51 kill lots of my time.
regards, yogesh
But that is not a problem with the C51 compiler, but with how it is used.
It is well documented that C51 converts auto variables and parameters into global variables shared memory locations with other auto variables and parameters based on the call tree analysis.
So ISR:s shouldn't call same functions as main loop does. And code should specifically mark functions that needs to be reentrant - or code rewritten to not make sure of recursive designs.
The important thing here is that the 8051 chip just isn't designed for use with a traditional stack for parameters and local variables.
Dear Per Westermark,
i analyzied your reply, please find my query in embedded with your reply.
accpect, i may not be aware of it, but want to be!
if possible provide me document links,also i want to see call tree, is this possible?
So ISR:s shouldn't call same functions as main loop does.
in my case function is only called in ISR, not in ground loop.
see my interrupt
static void XFER (void) interrupt 13 //one sec and one min interrupt metrology { int a=0x00; gucOneMinuteCount++; fTimeinSec();// changed 20/apr/2012
in this interrupt function is fTimeinSec();//
please see function
void fTimeinSec() { uint32x_t lRTsec,ltemp; const int lDaysInMonth[12]={0,31,59,90,120,151,181,212,243,273,304,334}; . . . . }
now what complier did, it assigned same fixed memory location to varialbles used in function fTimeinSec() and some of the ground loop function arguments. ofcourse this may due to function fTimeinSec() is not dependent on any function. but interrupt can be occure any time (that is why it is interrupt). call tree found interrupt function and ground loop function is independent while it is not. then it courrupt locations.
now it looks clearly, call tree analysis not done properly. interrupt variable and arrguments should consider for call tree dependancy.
And code should specifically mark functions that needs to be reentrant - or code rewritten to not make sure of recursive designs.
neither i am using reentrant nor i m using recursive designs.
it would be your great help if you make understand what is limitation of traditional stack for parameters and local variables.
thanks,
KISS, keep interrupts short and simple
have your interrupt increment some variable and in main() use it and, correspondingly, decrement it
how is gucOneMinuteCount defined? truly global, module local, local?
it seems that with your construct fTimeinSec(); acn, just as well, be called in main
Erik
dear Erik,
Variable gucOneMinuteCount is defined as
1) volatile uint8x_t gucOneMinuteCount=0x00; in Global file. this variable is increment in interrupt and checked in ground loop.
it is true globle variable. 2) in function fTimeinSec(); i apart from local variable (which i already mentioned), i m using one more globle variable i.e. gRTsec which is defined as - int32_t gRTsec=0; (global).
fTimeinSec(); is called at only interrupt.
regards,
fTimeinSec(); is called at only interrupt. WHY?, it will work just as well in the main()
KISS
Dear Erik,
My interrupt is triggers on every sec. so i don't want to update my variable before one sec. that's why i m calling this function at every 1 sec interrupt.
in groud loop its frequency of updation is very high, which i don't want.
But still all above question is alive?
if (gucOneMinuteCount != old....) { old... = gucOneMinuteCount; fTimeinSec() }
Now it looks some problem exist, and your suggesting work around.
And moreover we are not discussing about problem. why same address is assigned to procedure arrgument in interrupt?
now i'will not reply here, but if any body want to discuss then again i am avaiable.