Bootloader: C:0x0000 - C:0x7FFF Manages CAN-Communication and in-field update. Application C:0x8000 - C:0xEFFF Applications is controlled with bootloader over CAN 2.0. Compiled both seperatly and merge the Hex-file. Interrupts and function calls work. At level of 8 successive funtions calls the acces to an struct in Applications XDATA mem is incorrect. The expected pointer is not given. Any adwise?
At level of 8 successive funtions calls the acces to an struct in Applications XDATA mem is incorrect. A few questions: * What is meant by "successive" ? Is the function called eight times in a row, or does it mean the eighth depth level of the call tree ? * Are the function's arguments passed on the stack (i.e. is the function declared reentrant) ? If yes, check for a stack overflow. * Are you using function pointers or any other constructs that might make it necessary to manually adjust the call tree ? * Does the function work correctly when called from a lower depth ?
* What is meant by "successive" ? Is the function called eight times in a row, or does it mean the eighth depth level of the call tree ? It mean the eighth depth level of the call tree. * Are the function's arguments passed on the stack (i.e. is the function declared reentrant) ? If yes, check for a stack overflow. Arguments passed via register. * Are you using function pointers or any other constructs that might make it necessary to manually adjust the call tree ? There are a lot of function pointers and indirect calls in my application. Why manually adjust the call tree? * Does the function work correctly when called from a lower depth ? mom, im testing.
"There are a lot of function pointers and indirect calls in my application. Why manually adjust the call tree?" Because, if you don't, you most certainly will get exactly the kind of behaviour that you describe!! :-0 Stop Now! Read the application note http://www.keil.com/appnotes/docs/apnt_129.asp Also, search the knowledgebas for "function pointer", and take a look at this recent thread: http://www.keil.com/forum/docs/thread8021.asp
Same problem on lower level. The struct i want to access is global for this modul. i do something like this:
tXSEvent_ChannelPtr XSDevice_GetEventChanByID( tXSDevice_DeviceEntry* deviceEntryPtr, tXS_Group groupID, tXS_Channel chanID) { xdata tXSEvent_SourcePtr eventSrcEntry; xdata tXSEvent_ChannelPtr retVal; char temp[0x06]; retVal = (tXSEvent_ChannelPtr)0x0000; InitUart(); SendUart(0x05," dEP:"); sprintf(temp,"%p", deviceEntryPtr); SendUart(0x06,temp); if(0x00 != deviceEntryPtr) { /* check if group id is supported */ if( groupID < deviceEntryPtr->numEvents ) { eventSrcEntry = &(deviceEntryPtr->eventListPtr[groupID]); SendUart(0x04," eSE"); sprintf(temp,"%p",&(deviceEntryPtr->eventListPtr[groupID])); SendUart(0x06,temp); /* zero pointer check. */ if((0x00 != eventSrcEntry)) { /* check if channel is supported for the group */ if(chanID < eventSrcEntry->numChannels) { retVal = &(eventSrcEntry->channelListPtr[chanID]); SendUart(0x03,"-1-"); } } } } SendUart(0x03," rV"); sprintf(temp,"%p",retVal); SendUart(0x06,temp); return retVal; }
There are a lot of function pointers and indirect calls in my application. Why manually adjust the call tree? Because the linker cannot figure out more complex call scenarios (i.e. anything more complex than having a table of constant function pointers in code memory) and will reserve much more memory than is necessary. Even worse, it might make wrong assumptions about overlayable memory areas, which will lead to memory corruption. http://www.keil.com/support/man/docs/bl51/bl51_ol_fp.htm There's also an application note concerning function pointers and possible pitfalls: http://www.keil.com/appnotes/docs/apnt_129.asp However, this might all be completely unrelated to the problem you describe. If the argument is really passed in a register (look at the assembly code to find out if this really is the case), then maybe the wrong value gets passed in the first place.
Calling at lower level dont work. I use the Extended Linker with NOOVERLAY control enabled. The address of DeviceGroups is passed correct as u can see the examble. ASM for function call:
299: eventChannelPtr = XSDevice_GetEventChanByID( &XSIM_DeviceGroups, groupID, chanID); C:0xA051 7B01 MOV R3,#0x01 C:0xA053 7A82 MOV R2,#eventChannelPtr(0x82) C:0xA055 79AE MOV R1,#0xAE C:0xA057 908368 MOV DPTR,#0x8368 C:0xA05A E0 MOVX A,@DPTR C:0xA05B FD MOV R5,A C:0xA05C A3 INC DPTR C:0xA05D E0 MOVX A,@DPTR C:0xA05E 90838D MOV DPTR,#0x838D C:0xA061 F0 MOVX @DPTR,A C:0xA062 129E38 LCALL XSDevice_GetEventChanByID(C:9E38)
<dEP Pointer is correct. At eSE is the error. Ah. So the pointer does get passed correctly, and becomes corrupted later on. That is a different can of worms entirely, and would point more towards a problem with the call tree, i.e. the pointer gets stored in a memory location and is later overwritten. pre>tXSDevice_DeviceEntry* deviceEntryPtr If this is always a pointer to a location in xdata memory, it is a waste to use a generic pointer.
tXSDevice_DeviceEntry xdata * deviceEntryPtr
View all questions in Keil forum