We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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; }
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 <pre> and </pre> 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; }
BYTE process_Help(char *cmdBuffer) reentrant { char xdata strHelp[20] = "Help Message"; cmdBuffer[0] = '\0'; printf(strHelp); return TRUE; }
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; }
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
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; }
*** WARNING L13: RECURSIVE CALL TO SEGMENT SEGMENT: ?CO?HELLOCOMMANDS CALLER: ?PR?_PROCESS_HELP?HELLOCOMMANDS