Electronic – Editable PIC Serial Number in HEX File

compilermicrocontrollerpic

Currently I have a serial number hard-coded in my firmware for a design I'm working with. The firmware can read and report back the serial number. That works fine for what I need. The trouble is that each new serial number requires me to change my code and recompile. This is cumbersome when there are a lot of units to be built, has the possibly to introduce errors, and is all-around bad practice. The serial numbers are given to me and the hardware design is set in stone, so I can't add any features in hardware to serialize the units (EEPROM/Silicon ID Chip/Pull-Ups). What I would like to do is locate the serial number at a fixed address, compile the code once, then edit that address in the compiled HEX file for each new serial number. The number is referenced in several places, so ideally, I want to define & locate it once, then reference that "variable" everywhere else in my code. Does anyone know how to locate constant data at a specific addressable memory location of my choosing, using the C18 Compiler? Is there a better way anyone can suggest?

Best Answer

Specifically to resolve the question of binding variables to specific addresses in flash memory on the PIC18 with the C18 compiler, please reference the section "Pragmas" in the hlpC18ug.chm in the doc directory where the compiler is installed.

To do this you need to define a new "section" in memory and bind it to a start address so

#pragma romdata serial_no_section=0x1700

This creates a new section called "serial_no_section" that starts at address 0x1700 in flash (program) memory (because we defined "romdata" in the #pragma).

Directly after the #pragma line, define your variable(s) so:

#pragma romdata serial_no_section=0x1700
const rom int mySerialNumber = 0x1234;
#pragma romdata

Now you have 0x12 at address 0x1700 and 0x34 at address 0x1701 in memory (because PIC18 uses the little-endian model). The "const rom" ensure that the compiler knows that this is a const variable type, and that the variable lies in "rom" memory and thus need to be accessed via table read instructions.

The final #pragma romdata statement ensures that any following variable declarations are linked to default memory sections as the linker sees fits rather than following on in the "serial_no_section" section.

Now all code can simply reference the variable "mySerialNumber", and you know exactly what address the serial number can be found at in memory.

Editing the HEX code can be a bit challenging as you need to calculate the checksum for each line you edit. I am working on a C++ class to decode and encode Intel HEX files which should make this easier, but it is not finished yet. Decoding files works, encoding again is not yet implemented. The project (if you are interested) is here https://github.com/codinghead/Intel-HEX-Class

Hope this helps