What’s In A Hex File?

September 23, 2019

If you’ve ever worked with microcontrollers, you may have seen a file generated by your IDE with the .hex extension. If not, you can more than likely configure your IDE to generate one as one of your output build options. The most common format for this is the Intel HEX format which looks something like this:

:020000040800F2
:1000000010B5064C2378002B07D1054B002B02D0EE
:10001000044800E000BF0123237010BD040000204D
:100020000000000054000008044B10B5002B03D062
:100030000349044800E000BF10BDC04600000000B6
:10004000080000205400000880B582B000AF0123F2
:100050007B60FCE700000000F8B5C046F8BC08BCB7
:100060009E467047F8B5C046F8BC08BC9E4670472F
:08007000D8FFFF7F0100000032
:040078002900000853
:04007C000100000877
:04008000000000007C
:0400000508000000EF
:00000001FF

Above is part of a generated hex file for a simple test program that would be used to program an ARM based microcontroller. The great thing about this type of output is it’s all in human readable ASCII! The downside is this file is much larger than a binary file (.bin) would be for the same program.

Each character is a hexadecimal value (1 character represents 16 values). Let’s look at one of the lines to break down what this data means.

1 2   3   4                 5                 6
: 10 0000 00 10B5064C2378002B07D1054B002B02D0 EE  

1 - :
2 - 10
3 - 0000
4 - 00
5 - 10B5064C2378002B07D1054B002B02D0
6 - EE

1 – Colon represents the start of every new line in the file

2 – These two hex values represent the number of data bytes in the line. 0x10 = 16 bytes.

3 – These four values represent the memory location offset from base where the data should be placed. My controller’s Flash memory starts at address 0x08000000 so all zeros mean this will be placed in 0x08000000 + 0x0000 or the first location in my flash memory.

4 – This is the record type field. Basically it signifies what this specific line of data means. 00 shows this is straight data to be written. Most of the lines will have this record type. You can read more about the different record types here.

5 – This is the data itself! It can represent machine instructions and/or constant data.

6 – This is the checksum field. It serves as a value that whatever is writing the data can use to make sure the record has no errors. The value itself is the 2s compliment of the sum of all values on the line before it.

The end of a line is terminated by a line feed and character return.

Now you might be wondering why you’d want to look into this kind of output yourself. I’ve personally used it to verify that the memory locations my data is being written to are correct. When you use things like bootloaders, you need to offset your application address bytes to account for the data being taken by the bootloader itself. If you want your program base address to start at 2000 instead of 0000, having this hex file format is perfect for making sure your first address does indeed start where you want!

Leave a Reply