StevedB
StevedB

Reputation: 51

PIC18 variable declaration and initialisation fails in hardware

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

Answers (1)

StevedB
StevedB

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

Related Questions