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
(Ok, I hope I got the formatting correct this time) 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.
tXSDevice_DeviceEntry* deviceEntryPtr
typedef struct _XSIMDEVICE { tXS_UINT8 numEvents; /**< Event entry count for the device.*/ tXS_UINT8 groupCount; /**< Group entry count for the device.*/ tXSEvent_SourcePtr eventListPtr; /**< Event group pointer. */ struct _XSIMDEVICEGROUPINFO groupList[0x10u]; /**< Pointer to list of group entries. */ } tXSDevice_DeviceEntry;
typedef xdata struct _XSIMDEVICE { tXS_UINT8 numEvents; /**< Event entry count for the device.*/ tXS_UINT8 groupCount; /**< Group entry count for the device.*/ tXSEvent_SourcePtr eventListPtr; /**< Event group pointer. */ struct _XSIMDEVICEGROUPINFO groupList[0x10u]; /**< Pointer to list of group entries. */ } tXSDevice_DeviceEntry;
A lot of Linker Errors with different Datatypes and Unresolved Externals. I guess you will have to hunt down all declarations of the function and change them accordingly. However, this was just something I noted on the side. The cause for your problem is most likely related to the call tree. Read the application note and the chapter in the linker's documentation.
I disabled NOOVERLAY to get a call tree in my map-file. But the calling tree of the application is empty. Perhaps it's a problem with my startup-code and linker-script inside application-project.
View all questions in Keil forum