Reputation: 51
can someone help with this?
In summary: declaring and initialising a variable does not work in PIC hardware – whereas it works fine in simulation. Also, this problem seems to be worse if the variable is a structure. I am using: MPLAB X IDE V3.55, XC8 V1.41, PIC18F26K40 on Explorer 8 board with PICKIT3 debugger cable.
Details:
For a simple case like:
uint8_t myvar = 0x55;
void main(void)
{
uint8_t var = myvar;
}
Using the variables window in the debugger myvar is always zero when I run this in hardware. But if I run the same code in the simulator it is all OK!
I have:
Checking the values in the ‘File Registers’ debugger window. I can see no 0x55 when run in hardware – but it’s there in the simulator (at address 0x21).
It does work in hardware if:
Now if I use a struct type instead of a simple uint8_t like:
typedef struct {
uint8_t a;
char b[8];
}MYSTRUCT;
MYSTRUCT ms = { 0x55, "HELLO" };
void main(void)
{
uint8_t var = ms.a;
}
The ms variable is initialised properly in simulation, but not in hardware. This time it does not initialise if the variable is declared in main or as a global. Again, declaring as a const does work. So there seems to be inconsistency here:
uint8_t struct type
global variable declaration and initialisation N N
global const declaration and initialisation Y Y
local variable declaration and initialisation Y N
After debugging and stepping through with the assembler (.as) file it looks like myVar is trying to be initialised, but for some reason just doesn't in hardware. See below the relevant lines from the .as file. the address and value at key stages is shown as captured from the debugger during simulation. You can see at the end '__pdataCOMRAM' (the pointer into ram for myVar) is assigned 0x55. If I step through this in the hardware all steps are identical, but when we get to the end '__pdataCOMRAM' doesn't have the value of 0x55, but 0x00.
Address Value
global __pdataCOMRAM
__pdataCOMRAM:
file "main.c"
line 32
global _myVar
myVar: 0x21 0x00
ds 1
file "dist/C18_18F87K22/debug\initTest.X.debug.as"
line #
psect cinit
; Initialize objects allocated to COMRAM (1 bytes)
global __pidataCOMRAM 0x144 0xff55
; load TBLPTR registers with __pidataCOMRAM
movlw low (__pidataCOMRAM)
movwf tblptrl
movlw high(__pidataCOMRAM)
movwf tblptrh
movlw low highword(__pidataCOMRAM)
movwf tblptru
tblrd*+ ;fetch initializer
movff tablat, __pdataCOMRAM+0 0x21 0x55
Am I doing something dumb here or is there a compiler option I’m missing or is it a compiler or debugger bug? I would like to understand this problem so I don’t fall into any pitfalls further along in my development.
Cheers, Steve
Upvotes: 3
Views: 1012
Reputation: 51
It would appear there is a known silicon issue stopping access to program memory immediately after a reset. There is an ERRATA macro 'NVMREG' as a get around. Specific steps to solve were: Set project option 'Conf'>'XC8 global options'>'XC8 linker' select 'Additional options' category, then add NVMREG to Errata option. Then it all worked OK. Credit to 1and0 on the microchip forum for that one!
Upvotes: 2