This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Bootloader, Application, Structures and deep pointer

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;
    }
    
    dEP Pointer is correct. At eSE is the error.

    Both Projects compilied together work.

  • 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

    This would be a memory-specific pointer to xdata memory, which takes up only two bytes instead of three.

  • (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

    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

    This would be a memory-specific pointer to xdata memory, which takes up only two bytes instead of three.

  • tXSDevice_DeviceEntry xdata * deviceEntryPtr
    
    A lot of Linker Errors with different Datatypes and Unresolved Externals. I change my typedef from
    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;
    
    to
    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;
    

    But do not work.

  • 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)
    )
    )
    

    not really satisfying answer - "the '51 ain't no PC" got it?

  • 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);
    }
    

    XSIM_EventDetachAll calls XSDevice_GetEventChanByID with the global address of DeviceGroups. The eventChannelPtr is returned correct.

    Your use of function pointers blow "the compilation of the second project" Really?

    I go home for today, perhaps solution tomorrow.

    Micha