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

More Pointer Problems

Here's another good one. Again, works fine on simulator/debugger, but not on the target hardware.

If I do this:

BYTE process_Help(char *cmdBuffer) reentrant
{
cmdBuffer[0] = '\0';
printf( "Help Message");
return TRUE;
}

everything works fine. But if I do this:

BYTE process_Help(char *cmdBuffer) reentrant
{
char *strHelp = "Help Message";
cmdBuffer[0] = '\0';
printf(strHelp);
return TRUE;
}

it works fine on the simulator/debugger, but nothing is displayed when executed on the target hardware.

Any/All help welcome and appreciated.

Thanks,
Chris Beattie

  • Shouldn't strHelp be a character array instead of a character pointer???

    BYTE process_Help(char *cmdBuffer) reentrant
    {
    char *strHelp = "Help Message";
    cmdBuffer[0] = '\0';
    printf(strHelp);
    return TRUE;
    }
    
    -Walt

  • I tried the following:

    BYTE process_Help(char *cmdBuffer) reentrant
    {
    char strHelp[20] = "Help Message";
    cmdBuffer[0] = '\0';
    printf(strHelp);
    return TRUE;
    }

    And this does print SOMETHING, but it's all garbage. I guess that's better than nothing, but not quite right.

    Chris

  • Chris,

    please could you re-post your code samples using the &ltpre&gt and &lt/pre&gt tags, so that the layout is preserved and we can read them!

    See the link 'Tips for Posting Messages' in the lefthand sidebar
    http://www.keil.com/forum/tips.asp

    Have you read the section on memory-specific and generic pointers in the manual?

  • Nope, I haven't read those sections in the manual. Are they in the "C51 Compiler" Book or one of the others?

    Thanks,
    Chris Beattie

  • Hmmm,

    This sounds more and more like a memory problem on your target. Have you verified that the XDATA actually works?

    What chip are you using?

    Jon

  • Here's another good one. Again, works fine on simulator/debugger, but not on the target hardware.

    If I do this:

    BYTE process_Help(char *cmdBuffer) reentrant
    {
       cmdBuffer[0] = '\0';
       printf( "Help Message");
       return TRUE;
    }
    

    everything works fine. But if I do this:

    BYTE process_Help(char *cmdBuffer) reentrant
    {
       char *strHelp = "Help Message";
       cmdBuffer[0] = '\0';
       printf(strHelp);
       return TRUE;
    }
    

    it works fine on the simulator/debugger, but nothing is displayed when executed on the target hardware.

    Also, I have tried:
    BYTE process_Help(char *cmdBuffer) reentrant
    {
        char xdata strHelp[20] = "Help Message";
        cmdBuffer[0] = '\0';
        printf(strHelp);
        return TRUE;
    }
    

    Again this works fine on the debugger/simulator and at least I get something to print on the target hardware, but it is just garbage text (looks like uninitialized memory) instead of the message.

    Any/All help welcome and appreciated.

    Thanks,
    Chris Beattie

  • Okay, I read that part of the manual and tried to change my code to the following:

    BYTE process_Help(char xdata *cmdBuffer) reentrant
    {
        char xdata *strHelp = "Help Message";
        cmdBuffer[0] = '\0';
        printf(strHelp);
        return TRUE;
    }
    

    And now it doesn't print anything in the simulator and it prints garbage on the target...

    Chris

  • The difference between the working function and the non-working function is the non working functions declare variables on the reentrant stack. Are you setting the (I|X|P)BPSTACK variable in startup.a51?

    Are you using RTX51 Tiny? then this previous message appiles.

    RTX51 Tiny uses all the memory on the on-chip up till RAMTOP. If you are using reentrant functions in the small memory model this will overwrite by default the RTX51 Tiny stack. You need to specify a different RAMTOP for RTX51 Tiny in this case to have some reentrant stack available

  • This is what I'm doing in my startup.a51:

    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
    
    

    I'm honesty not sure what RTX51 Tiny is, so I'm not sure if I'm using it.

    I am using Small Reentrant, if I need to specify a different RAMTOP, how would I go about doing so?

    Thanks,
    Chris Beattie

  • Your problem may be in the way you are declaring your pointer. Since you are not specifying which memory the pointer strHelp resides in, I am assuming your memory model is small and strHelp is in internal data by default. I have found that to make pointers in internal memory using the C51 compiler, you have to declare them *exactly* the way the example shows on page 76 (the section on memory-specific pointers) of the C51 manual (User's Guide 01.97). The example shows:

    int xdata * data numtab; /*ptr in data to xdata int */

    I had declarations in my code that were the equivalent of the following:

    xdata int data *numtab;

    The manual said that the compiler would accept this form to maintain compatibility with old code - and indeed it did compile. However, the code would not work when it was being tested. Once my pointer declarations matched the first example above, they started to work. You might

  • xdata int data *numtab;

    is equivelent to

    int data * xdata numtab;

    So you were declaring the variable wrong until you went to the new style.


  • Since you are using small reentrant model, the reentrant stack shares its space with the call stack.

    Unfortunatly the compiler does not show stack space required for each invocation of a reentrant funtion.

    Looking at the disassembly, this particular function requires 3 bytes. Since the function is reentrant I am assuming you are calling it concurrently at least twice. So minimally you need 6 extra bytes in your stack, more if your concurrency count is higher. So one question is did you leave enough stack space so that the call stack and reeentrant stack do not overlap?

    Of course this example does not need to be reentrant. I am assuming your real function somehow calls itself.

    By the way, which micro are you using?

  • I'm going to try to eliminate the reentrant specification (I inherited this from another programmer). I'm using a Dallas 87C520 and a MetaLink iceMaster RA emulator.

    Chris

  • You should only remove the reentrant spec if you are sure that function
    will not be called from separate tasks (if you're using an RTOS) or from
    both a main loop and an interrupt handler. Otherwise having more than
    one context modifying data will cause corruption and unpredictable
    results.

  • NOW we're getting somewhere! I took out all the reentrant spcecifications on my process functions and it started to work correctly!

    HOWEVER, now I get once compiler warning per function that I am making recursive calls...

    From HelloCommands.c:

    BYTE process_Help(char *cmdBuffer) 
    {
        char *strHelp = "Help Message";
        cmdBuffer[0] = '\0';
        printf(strHelp);
        return TRUE;
    }
    

    produces the warning:
    *** WARNING L13: RECURSIVE CALL TO SEGMENT
        SEGMENT: ?CO?HELLOCOMMANDS
        CALLER:  ?PR?_PROCESS_HELP?HELLOCOMMANDS
    

    There is NOTHING recursive about that function, why am I getting this warning?

    Chris