CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Pointer to ROM fails with data 0x00

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bigseacow



Joined: 17 Jul 2009
Posts: 8

View user's profile Send private message

Pointer to ROM fails with data 0x00
PostPosted: Tue Sep 08, 2009 7:11 am     Reply with quote

I have encountered an interesting problem while using pointers to ROM. When the data being pointed to is 0x00 the pointer jumps to the previous array for the next and remaining values of the array. The example program below shows this through the output. If the array is stored in RAM instead, the issue does not occur. For my application I must store values in ROM, as there is not enough RAM.

Any comments on if this is a bug or how to fix this is greatly appreciated.

The compiler version is 4.099

Code:

#include <18F8722.h>
#device adc=10
#device *=16
#device PASS_STRINGS=IN_RAM // Allows ptrs to rom

#define CPUCLK 7372800
#use delay(clock=CPUCLK)
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, ERRORS, parity=N, bits=8)

#fuses NOWDT
#fuses HS, EMCU, NOWAIT
#fuses NOPROTECT, IESO, NOBROWNOUT, NOPUT, STVREN
#fuses CPD
#fuses NODEBUG
#fuses NOLVP, NOWRT, NOWRTD, WRTC, NOWRTB, NOEBTR
#fuses NOEBTRB, NOCPB

void PrintArray(char * iArray);

  const char MY_ARRAY[6][4] =
  {
    {0xB0, 0x68, 0xE0, 0x8F},
    {0x01, 0x02, 0x7F, 0x05},
    {0x90, 0x00, 0x41, 0x43},
    {0x2F, 0x22, 0x42, 0x26},
    {0x1F, 0x12, 0x43, 0x28},
    {0x00, 0x00, 0x38, 0x40}
  };

void main(void)
  {
  // Calls to pass the const array 
  PrintArray(MY_ARRAY[0]);
  PrintArray(MY_ARRAY[1]);
  PrintArray(MY_ARRAY[2]);
  PrintArray(MY_ARRAY[3]);
  PrintArray(MY_ARRAY[4]);
  PrintArray(MY_ARRAY[5]);

  while (TRUE);
  }
 
// Print the array out via RS232 for debugging 
void PrintArray(char * iArray)
  {
  char idx = 0;
  for (idx = 0; idx < 4; idx++)
    {
    printf("Array Idx: %X Val: %X\r\n", idx, iArray[idx]);
    }
    printf(" \r\n");
  }



PROGRAM OUTPUT:

Array Idx: 00 Val: B0
Array Idx: 01 Val: 68
Array Idx: 02 Val: E0
Array Idx: 03 Val: 8F

Array Idx: 00 Val: 01
Array Idx: 01 Val: 02
Array Idx: 02 Val: 7F
Array Idx: 03 Val: 05

Array Idx: 00 Val: 90
Array Idx: 01 Val: 00
Array Idx: 02 Val: 7F
Array Idx: 03 Val: 05

Array Idx: 00 Val: 2F
Array Idx: 01 Val: 22
Array Idx: 02 Val: 42
Array Idx: 03 Val: 26

Array Idx: 00 Val: 1F
Array Idx: 01 Val: 12
Array Idx: 02 Val: 43
Array Idx: 03 Val: 28

Array Idx: 00 Val: 00
Array Idx: 01 Val: 12
Array Idx: 02 Val: 43
Array Idx: 03 Val: 28
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 08, 2009 1:54 pm     Reply with quote

If the compiler sees a 0x00 in the data, it thinks it has found the end
of a string.

Examples:

If the data doesn't contain any 0x00 bytes, then it works OK.
Code:

const char MY_ARRAY[6][4] =
  {
    {0xB0, 0x68, 0xE0, 0x8F},
    {0x01, 0x02, 0x7F, 0x05},
    {0x90, 0x00, 0x41, 0x43},
    {0x2F, 0x22, 0x42, 0x26},
    {0x1F, 0x12, 0x43, 0x28},
    {0x01, 0x20, 0x38, 0x40}   // No 0x00 bytes in this row
  };

It copies the 4 bytes in the last row to RAM before it calls the
PrintArray() routine. This is correct:
Code:
.... PrintArray(MY_ARRAY[5]); 
0010C:  MOVLW  01 // Copy 1st element to 0x06
0010E:  MOVWF  06
00110:  MOVLW  20 // Copy 2nd element to 0x07
00112:  MOVWF  07
00114:  MOVLW  38 // Copy 3rd element to 0x08
00116:  MOVWF  08
00118:  MOVLW  40 // Copy 4th element to 0x09
0011A:  MOVWF  09
0011C:  CLRF   0A
0011E:  CLRF   0E
00120:  MOVLW  06
00122:  MOVWF  0D
00124:  BRA    007A  // Jump to PrintArray() routine



But if there is a 0x00 byte anywhere in the data, the compiler thinks it's
seeing the end of a string.
Code:

const char MY_ARRAY[6][4] =
  {
    {0xB0, 0x68, 0xE0, 0x8F},
    {0x01, 0x02, 0x7F, 0x05},
    {0x90, 0x00, 0x41, 0x43},
    {0x2F, 0x22, 0x42, 0x26},
    {0x1F, 0x12, 0x43, 0x28},
    {0x00, 0x20, 0x38, 0x40}  // First byte is 0x00
  };


Note that it doesn't copy the 4 elements of the last row to RAM.
That's why you're seeing garbage displayed in your PrintArray routine.
Code:

...... PrintArray(MY_ARRAY[5]); 
0010C:  CLRF   06
0010E:  CLRF   0A
00110:  MOVLW  06
00112:  MOVWF  09
00114:  BRA    007A   // Jump to PrintArray() routine


This was tested with vs. 4.099 but I think it's the same in any version.
bigseacow



Joined: 17 Jul 2009
Posts: 8

View user's profile Send private message

PostPosted: Tue Sep 08, 2009 2:37 pm     Reply with quote

Thanks for your reply. This explains exactly what is going on.

Is there any nice way around this?

The data I am using will contain 0x00 so I would gather the other option would be to copy the array from ROM to RAM on my own and then pass a pointer to the RAM array.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Sep 08, 2009 2:56 pm     Reply with quote

You can copy it with memcpy():
Code:

void main(void)
{
int8 temp[4];

memcpy(temp, MY_ARRAY[5], 4);
PrintArray(temp);

while(1);
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group