|
|
View previous topic :: View next topic |
Author |
Message |
bigseacow
Joined: 17 Jul 2009 Posts: 8
|
Pointer to ROM fails with data 0x00 |
Posted: Tue Sep 08, 2009 7:11 am |
|
|
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
|
|
Posted: Tue Sep 08, 2009 1:54 pm |
|
|
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
|
|
Posted: Tue Sep 08, 2009 2:37 pm |
|
|
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
|
|
Posted: Tue Sep 08, 2009 2:56 pm |
|
|
You can copy it with memcpy():
Code: |
void main(void)
{
int8 temp[4];
memcpy(temp, MY_ARRAY[5], 4);
PrintArray(temp);
while(1);
}
|
|
|
|
|
|
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
|