.hex file last few lines are irregular

This isn't an error but is something I wonder what caused it. The following are the last few lines of a compiled project. As you can see, the first line is for address 2DD0, nice 16-byte aligned.
Then the next line only has 14 bytes. Then the lines have 16 bytes again but not 16-byte aligned. Then the last data line has the 2 bytes! Then the file ends. So what caused the partial line with 14 bytes and can I not have partial lines like zero padding incomplete line (last line)?

I examined a number of .hex files and most of them have incomplete lines followed by complete 16-byte lines. Is this some sort of "partition"? All of the .hex I examined have NO bootloaders, in case you wonder. The bootloader is just slapped onto the rest of the code so there's a break in address.


The file format is called Intel HEX. It has different line length.

Have a look at the Wikipedia page description.

I've noticed that myself. I don't understand what causes the toolchain to put anomalously short lines in like that either. But it does, and it's valid intel hex (though I did once encounter something that would only work when the size of the pages was a multiple of the number of bytes in every line; but we were using a tool that processed the hex files and output them with all lines of equal length anyway)

There isn't even any break in the data or anything there, the next line then starts 2 bytes earlier.

I suspect it happens where two "sections" meet, but don't know for sure.

Different address start different lines in the intel HEX format. The first bytes tell the receiver where to place the date in memory. What is at those address in processor dependent.

The file format is called Intel HEX. It has different line length.

Have a look at the Wikipedia page description.

Intel HEX - Wikipedia

Thank you for pointing out the file format and what each line means. We all know that, which was NOT my question.


Very short projects such as blink won't have this issue. I too suspect that there are sections in the code. For now, I'm doing this by hand, which isn't too bad. The misalignment happens at the very end and isn't hard to hand align. Later I'll write a Python script to align it automatically. A lazy way would be to upload the .hex and download it back with avrdude :wink:

I bet I have to chop off the trailing FF bytes but it's gonna be aligned. My main goal is to program AVR with ESP32 so this is only a side goal. If I do find out what caused it or even how to fix it, I'll post back.

Why do you want it to be aligned?

At least in the situation where I needed it aligned, there was a particular bootloader (chipboot - not what I would have picked - but I wasn't the one making that decision, I was just making it work on a different part :-P) where you could literally open a serial console, and copy/paste the hex into it.... but, if the boundary between lines didn't line up with memory page boundaries, everything collapsed

To make a simple uploader function, without the need to understand Intel .hex format. I strip all extras away and only keep the ASCII-binary and convert to binary.

From what the doc says, you can load anywhere to the buffer between 0x00 and 0x63 in word address in any order. Then you can write the buffer to any address with the write program page command, is that correct? Say I want it to write a few sparse bytes in the buffer (not worried about the rest) and then write the buffer to 0xbeef (assuming it has that much memory), it would work, correct?

Actually I don't know how flashing works. Without a chip erase command you can only change 1 to 0. Then if you mess up grouping partial lines you may be writing to the same address in two consecutive page writes and the second write just OR to the first write where the two writes overlap?

We all know that, which was NOT my question.

Sorry about that. I try not to assume what someone knows.

I too suspect that there are sections in the code.

You could have a look into the map file. There should be a section where you can see what is placed in memory, its size and from what file the code or data comes from as well as fill information. Simply search for the address in the new line after an incomplete line in your hex file. For your example 2DEE.

Maybe you can spot a pattern there. I found two cases (just picked some random projects) and there was a linker stub at the end of the standard library objects at the address where the hex file alignment stopped. The map file at the address looked like this

.glue_7 0x0000df54 0x0
.glue_7 0x0000df54 0x0 linker stubs

So, the linker is probably finished adding all the objects from your code and the standard library and therefore finishes the line and then another process in the linker adds some extra stuff to the hex file.

Great! Thanks Klaus_K. I've never looked into the map file. I'll see if I can find any information there. Meanwhile I'll probably write a Python script to render Intel .hex into raw with padding. It's too much work to do this in C/C++.

The erasing when self programming (ie, through bootloader vs isp programming is different. ISP only has chip erase, self programming only does page erases

I don't know the answer relating to Arduino, but the short/long lines in an executable load file has been the case for and many decades as I can remember. I think it has to do with the inclusion of pre-compiled code into your program.