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.
you have been told again and again that your problems are related to yout total refusal to appreciate the architecture of the microcontroller you use and just push on with the function pointers that is one of the microprocessor methods which this microcontroller is incapable of. I can appreciate that Keil, to stay ANSI compliant, has somehow wrangled this functionality into the compiler, does that make it what you should use by no means Why on earth would anyone want to continue helping you when you refuse to follow advice given several times (get rid of the function pointers). "the '51 ain't no PC" got it? Erik
That's not correct. Both Projects compilied together work. The problem is the compilation of the second project. Here Startup and linker-script:
NAME FSWSTARTUP80C515 ?PR?_do_cinit?FSWSTARTUP80C515 SEGMENT CODE ?PR?_do_deinit?FSWSTARTUP80C515 SEGMENT CODE ?CO?FSWSTARTUP80C515 SEGMENT CODE PUBLIC _cinit_scn PUBLIC _do_deinit PUBLIC _do_cinit RSEG ?CO?FSWSTARTUP80C515 _cinit_scn: DB 000H,000H RSEG ?CO?FSWSTARTUP80C515 IDATALEN EQU 00H XDATASTART EQU 8000H XDATALEN EQU 6FFFH PDATASTART EQU 0H PDATALEN EQU 000H IBPSTACK EQU 0 IBPSTACKTOP EQU 0xFF +1 XBPSTACK EQU 0 XBPSTACKTOP EQU 0xFFFF +1 PBPSTACK EQU 0 PBPSTACKTOP EQU 0xFF +1 PPAGEENABLE EQU 0 PPAGE EQU 0 PPAGE_SFR DATA 0A0H ?XSIMSTACK SEGMENT IDATA RSEG ?XSIMSTACK DS 0x1 RSEG ?PR?_do_cinit?FSWSTARTUP80C515 _do_cinit: USING 0 STARTUP1: IF IDATALEN <> 0 MOV R0,#IDATALEN - 1 CLR A IDATALOOP: MOV @R0,A DJNZ R0,IDATALOOP ENDIF IF XDATALEN <> 0 MOV DPTR,#XDATASTART MOV R7,#LOW (XDATALEN) IF (LOW (XDATALEN)) <> 0 MOV R6,#(HIGH (XDATALEN)) +1 ELSE MOV R6,#HIGH (XDATALEN) ENDIF CLR A XDATALOOP: MOVX @DPTR,A INC DPTR DJNZ R7,XDATALOOP DJNZ R6,XDATALOOP ENDIF IF PPAGEENABLE <> 0 MOV PPAGE_SFR,#PPAGE ENDIF IF PDATALEN <> 0 MOV R0,#PDATASTART MOV R7,#LOW (PDATALEN) CLR A PDATALOOP: MOVX @R0,A INC R0 DJNZ R7,PDATALOOP ENDIF IF IBPSTACK <> 0 MOV ?C_IBP,#LOW IBPSTACKTOP ENDIF IF XBPSTACK <> 0 MOV ?C_XBP,#HIGH XBPSTACKTOP MOV ?C_XBP+1,#LOW XBPSTACKTOP ENDIF IF PBPSTACK <> 0 MOV ?C_PBP,#LOW PBPSTACKTOP ENDIF ;MOV SP,#?XSIMSTACK-1 ;LJMP ?C_START ?C0003: RET RSEG ?PR?_do_deinit?FSWSTARTUP80C515 _do_deinit: USING 0 ?C0004: RET END
REGFILE (..\05_out\xsim_debug.ORC) PRINT("..\05_out\xsim_debug.map") NOOVERLAY CLASSES ( XDATA (X:0x8000-X:0xF7FF, X:0xF800-X:0xFFFF), XDATA_ADL(X:0x0000 - X:0x2FFF), XDATA_HISIO (X:0x3000-X:0x3FFF), XDATA_HISFF (X:0x7000-X:0x74FF), XDATA_XSIM (X:0x8000-X:0xEFFF), CODE (C:0x8000-C:0xEFFF), CODE_ADL(C:0x0000-C:0x6AFF), CODE_HISFF(C:0x7600-C:0x7FFF), CODE_HISIO (C:0xE600-C:0xEFFF), CODE_XSIM(C:0x8100-C:0xB2FF), CONST_XSIM(C:0x8000-C:0xFFFF) )& SEGMENTS( ?CO?ADLATUS_ASWENTRYTABLE(C:0x8000), ?C?LIB_CODE(C:0x807C), ?C_INITSEG(C:0x841F), ?PR?XSIM_ASMREFRESHWDT?XSIM_ASMREFRESHWDT(C:0x8070), ?PR?XSIM_ISR_TIMER1?XSIM_INTERRUPTS(C:0x801b), ?XSIMSTACK(I:0x91) ) )
That's not correct. Both Projects compilied together work. The problem is the compilation of the second project. WHAT ON EARTH HAS "Both Projects compilied together work" to do with the fact that your use of function pointers blow "the compilation of the second project" If you took the time to get rid of the utterly stupid attitude that "C IS C" and read up on the way the '51 and the tools for it work, you would understand why you have the problem you have, the reason of which Andy has already posted twice. not really satisfying answer - "the '51 ain't no PC" got it? Of course, it can not be 'satisfying' to someone that insist on ignoring the underlying architecture. That, however does not change that it is a FACT. Erik
I'm still here. This testmain() in the applications-µVision-project works fine. Debugging information over serial port. All adresse corect.
void main(void) { tXS_ParameterPtr paramPtr; paramPtr->value[0x00u] = 0x00u; XSIM_EventDetachAll(paramPtr); while(1); }