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

Problems with Passing Pointers as Parameters

Okay, I'm trying to pass a pointer to a char buffer to a function. It works fine in the Keil simulator/debugger, but not on the target hardware.

// Variable Declaration
#define MAX_RX_SIZE 100
static char xdata cmdBuffer[MAX_RX_SIZE];

// Calling function
void CallingFunc(void) {
// cmdBuffer is read in from serial
// port and contains "EF"
printf("\r\nP2_CMDFOUND\r\n");
printf(cmdBuffer);

if (!process_EraseFlash(cmdBuffer)) {
printf("\r\nP2_INVALARG\r\n");
printf(cmdBuffer);
printf("\n**invalid arguments");
}
else {
printf("\r\nFcn Success\r\n");
printf(cmdBuffer);
}
}

// Called Function
BYTE process_EraseFlash(char *cmdBuffer) reentrant
{
printf("\r\nP2_CMDEF\r\n");
printf(cmdBuffer);
if (strcmp(cmdBuffer, "EF"))
return FALSE;

if (flash_ChipErase())
printf("\r\nOK");
else
printf("\r\n**Error>\r\n");
return TRUE;
}

Okay, here's the output from the simulator:
P2_CMDFOUND
EF
P2_CMDEF
EF
OK
Fcn Success
EF

And here's the output from the target hardware:
P2_CMDFOUND
EF
P2_CMDEF

P2_INVALARG
EF
**invalid arguments

Looks like the pointer is not being passed to the process function properly, as the process function thinks the buffer is empty.

Any ideas? I'm stuck here.

Thanks,
Chris Beattie

  • If it works OK in the simulator but NOT on the target hardware, then there is something that is there in the simulation that is NOT there in the target hardware.

    Since your buffer is in XDATA, are you sure that the XDATA on your target is working?

    Jon

  • Okay, I'm trying to pass a pointer to a char buffer to a function. It works fine in the Keil simulator/debugger, but not on the target hardware.

    // Variable Declaration
    #define MAX_RX_SIZE 100
    static char xdata cmdBuffer[MAX_RX_SIZE];
    
    // Calling function
    void CallingFunc(void) {
      // cmdBuffer is read in from serial
      // port and contains "EF"
      printf("\r\nP2_CMDFOUND\r\n");
      printf(cmdBuffer);
    
      if (!process_EraseFlash(cmdBuffer)) {
        printf("\r\nP2_INVALARG\r\n");
        printf(cmdBuffer);
        printf("\n**invalid arguments");
      }
      else {
        printf("\r\nFcn Success\r\n");
        printf(cmdBuffer);
      }
    }
    
    // Called Function
    BYTE process_EraseFlash(char *cmdBuffer) reentrant
    {
      printf("\r\nP2_CMDEF\r\n");
      printf(cmdBuffer);
      if (strcmp(cmdBuffer, "EF"))
        return FALSE;
    
      if (flash_ChipErase()) 
        printf("\r\nOK");
      else 
        printf("\r\n**Error>\r\n");
      return TRUE;
    }
    
    Okay, here's the output from the simulator:
    P2_CMDFOUND
    EF
    P2_CMDEF
    EF
    OK
    Fcn Success
    EF
    
    And here's the output from the target hardware:
    P2_CMDFOUND
    EF
    P2_CMDEF
    
    P2_INVALARG
    EF
    **invalid arguments
    
    Looks like the pointer is not being passed to the process function properly, as the process function thinks the buffer is empty.

    Any ideas? I'm stuck here.

    Thanks,
    Chris Beattie

  • In reply to both your posts...

    I definately think the problems are related, just not sure what's causing it. I'm using a Dallas 87C520 for the actual target hardware and a MetaLink RA-87C530 Emulator. Everything works on the Keil simulator, the errors occur on both the Emulator and target micro.

    I customized the Startup.a51 file as follows:

    IDATALEN	EQU	80H	; the length of IDATA memory in bytes.
    ;
    XDATASTART	EQU	0H	; the absolute start-address of XDATA mem
    XDATALEN	EQU	400H	; the length of XDATA memory in bytes.
    ;
    PDATASTART	EQU	0H	; the absolute start-address of PDATA memory
    PDATALEN	EQU	0H	; the length of PDATA memory in bytes.
    .
    .
    .
    IBPSTACK	EQU	1	; set to 1 if small reentrant is used.
    IBPSTACKTOP	EQU	0FFH+1	; set top of stack to highest location+1.
    ;
    .
    .
    .
    STARTUP1:
    ; Mask all interrupts.  We don't want any interrupts coming in while
    ; we are trying to start up.
    		MOV     IE, #0
    
    ; Specify that internal XDATA exists.
                    ANL     PMR, #0FCh    ; CLEAR DME0 & DME1
                    ORL     PMR, #01h     ; SET DME0
    
    ; Change priority of interrupts
                    SETB    PT1     ; Timer 1 High Priority
    
    ; Select fastest XDATA timing.
                    MOV     CKCON, #00H
    

    Am I doing something wrong? How can I verify that XDATA is working properly?

    Also, the variable is declared in xdata and used in the same .c file as it's declared in just fine, it's only when I pass a pointer to the memory that I get problems:

    Uart.c:
    static char xdata cmdBuffer[MAX_RX_SIZE];
    
    // Calling function
    void CallingFunc(void) {
      // cmdBuffer is read in from serial
      // port and contains "EF"
      printf("\r\nP2_CMDFOUND\r\n");
      printf(cmdBuffer);   // ***WORKS FINE*** Prints "EF"
    
      process_EraseFlash(cmdBuffer);
    }
    

    Commands.c:
    // Called Function
    BYTE process_EraseFlash(char *cmdBuffer) reentrant
    {
      printf("\r\nP2_CMDEF\r\n");
      printf(cmdBuffer);         // ***FAILS*** Prints Blank Line
    }
    

    I'm not sure if it's an XDATA problem or if there's a trick to passing pointers to XDATA or what...

    Chris

  • Try using slower access to XDATA. If you do not have fast enough RAM, that may be causing the problems.

    Jon

  • I'll give that a shot in the morning. Let you know if it worked then.

    Thanks,
    Chris

  • Hi Erik,<br>
    <br>
    well, just looked it up again... you can sure use the internal clock too. I just remembered an old application of mine, where I used a variable external clock to meassure the length of something moving through a light barrier. The external clock was relative to the speed of the movement. So I was not sure, if the c51 would be able to use the internal clock for the capture mode... just too long ago :))<br>
    <br>
    Take care<br>
    Sven

  • Changed it to the slowest XDATA timing, no luck. I actually have an annual maintenance agreement, should I open up a support call?

    Chris

  • You may want yo try contacting support, however, it appears from other your other thread that removing reentrant helped somewhat.

    The reentrant stacks have worked with no problems for a long time so I'm not sure why it would work under simulation but not on the target.

    Anyway, I think your problem is related to the reentrant stack pointer. Maybe it is getting corrupted somehow.

    Have you included the reentrant keyword in your prototypes for the reentrant routines? For example:

    BYTE process_EraseFlash (
      char *cmdBuffer) reentrant;
    

    This is required to tell other routines that arguments are passed on the reentrant stack.

    Jon

  • Yep, both the prototypes and definitions were declared as reentrant. I think I may be overflowing the reentrant stack. I'll post more on the other thread.

  • The XDATA memory you are using is actually internal to the Dallas 520 chip, so unless both the emulator and the target chip have something wrong, its not the hardware. The speed of access will have no effect on the internal XDATA memory. The wait states you can add in the 520 affect only RAM that is connected external to the chip.