# Loading a HEX file with PICkit 2

I'm trying to upload a hex file, generated from multiple C source files with xc8 in Proteus, into a PIC18F4520. Usually, I don't have any problems doing this but yesterday I ported some Arduino TFT display code to the PIC and tried to upload and test some basic screen functions. The HEX was uploaded and the PIC drove the screen perfectly except for a problem with the colour of text. I went through the code and found the problem was due to a variable that I accidentally declared as uint8_t instead of uint16_t thereby causing the colour to be truncated. The variable is one of a bunch of static variables with file scope:

static uint8_t _width    = ST7735_TFTWIDTH;
static uint8_t _height   = ST7735_TFTHEIGHT;
static uint8_t rotation  = 1;
static uint8_t cursor_y  = 0;
static uint8_t cursor_x  = 0;
static uint8_t textsize  = 1;
static uint8_t textcolor = 0xFFFF;  // this is the relevant line
static uint8_t text_wrap      = 1;
static uint8_t colstart = 0, rowstart = 0;


I corrected the declaration and built a new HEX in Proteus and tried to re-upload with the PICkit 2 application. When I imported the hex file to begin the upload, I got the warning: Hex file loaded is larger than device, which didn't make any sense since the memory summary is:

Memory Summary:
Program space        used  17DBh (  6107) of  8000h bytes   ( 18.6%)
Data space           used    6Dh (   109) of   600h bytes   (  7.1%)
Configuration bits   used     7h (     7) of     7h words   (100.0%)
EEPROM space         used     0h (     0) of   100h bytes   (  0.0%)
ID Location space    used     8h (     8) of     8h bytes   (100.0%)
Data stack space     used     0h (     0) of   580h bytes   (  0.0%)


Inspecting xc8 output in MPLABX this time, I found this message at the bottom: Warning: C:/.../train85.X.production.hex contains code that is located at addresses that do not exist on the PIC18F4520. This correlates with other answers I found online; it seems code is being written to non-existent addresses. The methods used by others to solve it seem varied: some made changes to the arrangement of CONFIG variables, making them more compact (which I've tried) while others edited the HEX itself manually. Some observations that may be pertinent:

• If I undo that single correction to the declaration above, the warning is no longer present.
• There are 2 large arrays for font details, that are stored in program memory with the const keyword. They are about 2.4k in size and are accessed through pointers in structs.
• If I move one of the font arrays to data memory by removing the const qualifier, the warning also goes away.
• When I ignored the warning and uploaded the HEX to the PIC with the PICkit application, there didn't seem to be any problems; the TFT display was driven perfectly and the text colour issue was solved.

The HEX, SYM, MAP and startup ASM files, pre- and post-correction, are located here in case you need them. I can't post my code here as there are several files, but I can provide a link to it, if necessary.

In case my question wasn't clear, I need to know the exact cause of the warning, as it relates to my code (HEX) and a solution to it. Is it safe to ignore it, like I did? Thanks in advance.

• @TomCarpenter For the PIC, declaring any variable with 'const' ensures that they are placed in program menory; thats the only requirement according the XC8 manual. I also checked the memory summary before and after removing 'const' and I got confirmation. – SoreDakeNoKoto May 28 '16 at 20:02
• No idea then - in both cases everything in the hex files is in a sensible range - the second one is 22bytes longer, but there should be plenty of space. The only noticeable difference between the two hex files is the alignment - one is aligned starting at an 8 word boundary, the earlier one starts at a 16 word boundary, but that shouldn't cause a problem. Maybe try clean+rebuild? Or even try adding an extra line of code to see if that realigns the hex. – Tom Carpenter May 28 '16 at 20:05
• @TomCarpenter Tried it and no luck :( – SoreDakeNoKoto May 28 '16 at 20:10

## 1 Answer

I think I know the problem. In your first hex file, the alignment is correctly on 2 byte, with 16 bytes on each line. The first few addresses are (in hexadecimal):

6830
6840
6850
6860
6870
6880
6890
68A0


Notice how the addresses go up in increments of 16bytes (10h), but crucially, notice how the lower digit is always zero (well strictly speaking a multiple of 2).

In the corrected hex file, the addresses are:

6829
6839
6849
6859
6869
6879
6889
6899
68A9


Here they are no longer correctly aligned. Notice how the lower digit is not a multiple of 2 - it is 9.

This is a problem simply because the PIC's program memory is organised in 2byte (16bit) chunks - each instruction is 16bit or 32bit IIRC.

Technically the hex file is correct, however it will confuse the heck out of the tools because technically address 0x6829 does not exist (0x6828 and 0x682A both do). The PICKit software will realign the hex file when it opens it - essentially adding in an extra 0xFF word at the beginning to realign the data to the correct place, and as a result the upload works and the program runs fine.

As to why it is happening, I really haven't a clue beyond a bug in a toolchain which is already glitchy at the best of times (the reason I gave up with PICs and went for AVRs instead!).

There may be a setting somewhere in the project to select the alignment of the hex file. If not, perhaps you could try adding an extra byte sized variable in the program memory (or make an existing one an extra byte in size) and see if that tricks the toolchain into realigning the hex file.

• Figuring out how to extract a map file or symbolically annotated decompilation from the toolchain would be a big help in sorting out what happened. – Chris Stratton May 28 '16 at 20:26
• @ChrisStratton There is a .map file generated for each hex. Will that do? – SoreDakeNoKoto May 28 '16 at 20:40
• It's certainly worth an attempt at examining those side by side to see if there are useful clues there. – Chris Stratton May 28 '16 at 20:42
• @TomCarpenter Thanks, your work-around worked! I changed another variable from uint8_t to uint16_t and I no longer get the warning. I dont know much about the Intel Hex format; how did you find this alignment issue? With a normal hex editor? – SoreDakeNoKoto May 28 '16 at 20:47
• @TisteAndii intel hex files are plain text, so any old text editor will open them. You can read about the format here – Tom Carpenter May 28 '16 at 21:25