How to merge Application hex file and bootloader hex file

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am using atmega328pb. I have developed application code and bootloader code to update the application code in future.

So, for now I am uploading the bootloader code first in the MCU and then application code with -D command, so that the previous code will not get deleted.

But, I want to merge both the hex file so that while production, I can upload both files at once.

So, how can I do this.

Please help.

Thanks in advance.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One word: srec_cat

 

(the old fashioned way is simply to glue them in a text editor and remove the termination record at the end of the first bit (the app))

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you have a bootloader, load it once and use it!!!!

 

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

imrana326 wrote:

I am using atmega328pb. I have developed application code and bootloader code to update the application code in future.

So, for now I am uploading the bootloader code first in the MCU and then application code with -D command, so that the previous code will not get deleted.

But, I want to merge both the hex file so that while production, I can upload both files at once.

So, how can I do this.

Please help.

Thanks in advance.

 

You CAN simply use a text editor and merge the two .HEX files together. Just be sure that the ending sequence ( :00000001FF ) is not included from the first file.

 

Here's an example:

 

First HEX file (your application):

:100000000C94C70C0C94F80C0C94F80C0C94F80C91
:100010000C94F80C0C94F80C0C94F80C0C94F80C50
////// snip //////
:107C88000080BF000000000000000049283C2D00D3
:107C9800000000DA2E3C2D7E2E892E972EAB2E1C4E
:027CA8002F00AB
:00000001FF <--- end of file must be edited out

 

Second HEX file (the bootloader):

:107E00001FBE1092660084B714BE8D7089F0109268
:107E1000C1001AB80FB6F894A895809160008861E7
////// snip //////
:107FC0008091C00087FFFCCF8091C6000895F8DF44
:0C7FD0008032E9F784E1EDDFA895089508
:00000001FF

 

Combined:

:100000000C94C70C0C94F80C0C94F80C0C94F80C91
:100010000C94F80C0C94F80C0C94F80C0C94F80C50
////// snip //////
:107C88000080BF000000000000000049283C2D00D3
:107C9800000000DA2E3C2D7E2E892E972EAB2E1C4E
:027CA8002F00AB
:107E00001FBE1092660084B714BE8D7089F0109268
:107E1000C1001AB80FB6F894A895809160008861E7
////// snip //////
:107FC0008091C00087FFFCCF8091C6000895F8DF44
:0C7FD0008032E9F784E1EDDFA895089508
:00000001FF

 

Note that the "end of file" data from the FIRST file only has been removed.  The HEX files contain address data in them, so it knows where to load into. Therefore, it doesn't matter which one comes first, as long as all "end of file" markers are removed except for the last one.

 

FYI here are the Intel HEX file data types (the 4th byte):

 

// Intel HEX record types
#define DATA_RECORD 00
#define EOF_RECORD 01
#define EXT_SEGMENT_ADDR 02
#define SEGMENT_START_ADDR 03
#define EXT_LINEAR_ADDR 04
#define LINEAR_START_ADDR 05

 

Typical HEX record:

 

:107E00001FBE1092660084B714BE8D7089F0109268

 

Green: Record size in HEX (i.e. 0x10 = 16 bytes)

Violet: Load address in HEX

Blue: Record type (see above)

Orange: Actual data

Red: 8 bit checksum

 

The INTEL Hex format also supports addresses beyond 0xFFFF by using either the Intel "Segment/Offset" scheme or a linear scheme.  Take a look at the first 2 records of my MEGA2560 bootloader code:

 

:020000023000CC
:10F8000001E20EBF0FEF0DBF11241FBE2AC080936F

 

See.. the first record type is 0x02 (extended segment address) followed by a 16 bit offset in little-endian.

The second record's first address is 0xF800, so combined this means that the bootloader starts loading into 0x03F800 (260096 in decimal).  Take the flash size of the MCU (262144) and subtract the bootloader start address (260096) and you get 2048 which is the size of my bootloader (2K). See? Cool, huh?

 

Good reference (a PDF file):  LINK

 

Lastly, you'll need to be sure that the BLB (bootloader lock bits) are set properly to allow you to burn both your application AND the bootloader. Then you should set the BLB back to protect the bootloader area.

 

Hope this helps.

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ki0bk wrote:

If you have a bootloader, load it once and use it!!!!

 

 

 

I guess that's a lot easier than my method!  LOL!

Gentlemen may prefer Blondes, but Real Men prefer Redheads!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, the information from this topic is really solid gold for bootloader users!

I have a similar situation somehow, only that for me the main problem is that I have two setups so I have to be very carefull if my bootloader is flashed or not.

 

Basically on my desk I have a microcontroller that I flash by JTAG either with ATMEL STUDIO (not so much anymore) either directly from Linux with avarice.

The problem with this kind of flashing is that if a bootloader is already previously flashed, it will be erased.

And here comes my question, is it possible to flash the application via JTAG and also keeping the bootloader functional?

 

The second setup is actually on the actual HW where JTAG is disabled as I am using the associated ADCs, so I can flash only by CAN. Also as soon as the uC board is mounted inside the HW, the JTAG connector and jumpers are no longer accesible

so if I can't flash by CAN or the bootloader is damaged then the HW has to be dissasembled.

 

What is the -D command and what does it do? Is this an avrdude parameter? Will using it solve my problem so I can flash the application without erasing the bootloader?

Or do I also have to play with the lock bits?

Or should I make some command that concatenates the bootloader and the app latest .hex and flashes them together?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


I wasn't near a computer when I posted #2. I am now. So...

C:\Program Files (x86)\Atmel\Studio\7.0>dir srec_cat*.* /s
 Volume in drive C is OSDISK
 Volume Serial Number is 7AF3-B2D0

 Directory of C:\Program Files (x86)\Atmel\Studio\7.0\shellutils

04/09/2019  11:57         1,454,872 srec_cat.exe
               1 File(s)      1,454,872 bytes

So it looks like AS7 already has srec_cat in the installation.

 

So what I would do is make a two project solution in AS7, one for the bootloader, one for the application. Make one depend on the other. (so they are built in a fixed order when you "Build Solution". In the Post-Build step of the one that builds second simply add

srec_cat $(OutputDirectory)\$(OutputFilename).hex -Intel $(OutputDirectory)\..\..\Bootloader\$(Configuration)\Bootloader.hex -Intel -o Combined.hex -Intel

The attached .zip file contains an AS7 project that shows this in template form:

 

 

When built this does:

 

------ Build started: Project: Bootloader, Configuration: Debug AVR ------
		Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
		C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 8 --output-sync 
------ Build started: Project: Application, Configuration: Debug AVR ------
		Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
		C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 8 --output-sync 
		srec_cat D:\test\Boot_and_Application\Application\Debug\Application.hex -Intel D:\test\Boot_and_Application\Application\Debug\..\..\Bootloader\Debug\Bootloader.hex -Intel -o Combined.hex -Intel
========== Build: 2 succeeded or up-to-date, 0 failed, 0 skipped ==========

I guaranteed that application is build after bootloader by:

 

 

I remembered to set the bootloader to a different area in the HEX with:

 

 

And this all creates:

 

 

There are effectively TWO programs in there (you can see all the 0C94 interrupt tables repeated twice). One is located at 0x0000 and one at 0x7000.

 

Quod Erat Demonstrandum.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Krupski wrote:

imrana326 wrote:

I am using atmega328pb. I have developed application code and bootloader code to update the application code in future.

So, for now I am uploading the bootloader code first in the MCU and then application code with -D command, so that the previous code will not get deleted.

But, I want to merge both the hex file so that while production, I can upload both files at once.

So, how can I do this.

Please help.

Thanks in advance.

 

You CAN simply use a text editor and merge the two .HEX files together. Just be sure that the ending sequence ( :00000001FF ) is not included from the first file.

 

Here's an example:

 

First HEX file (your application):

:100000000C94C70C0C94F80C0C94F80C0C94F80C91
:100010000C94F80C0C94F80C0C94F80C0C94F80C50
////// snip //////
:107C88000080BF000000000000000049283C2D00D3
:107C9800000000DA2E3C2D7E2E892E972EAB2E1C4E
:027CA8002F00AB
:00000001FF <--- end of file must be edited out

 

Second HEX file (the bootloader):

:107E00001FBE1092660084B714BE8D7089F0109268
:107E1000C1001AB80FB6F894A895809160008861E7
////// snip //////
:107FC0008091C00087FFFCCF8091C6000895F8DF44
:0C7FD0008032E9F784E1EDDFA895089508
:00000001FF

 

Combined:

:100000000C94C70C0C94F80C0C94F80C0C94F80C91
:100010000C94F80C0C94F80C0C94F80C0C94F80C50
////// snip //////
:107C88000080BF000000000000000049283C2D00D3
:107C9800000000DA2E3C2D7E2E892E972EAB2E1C4E
:027CA8002F00AB
:107E00001FBE1092660084B714BE8D7089F0109268
:107E1000C1001AB80FB6F894A895809160008861E7
////// snip //////
:107FC0008091C00087FFFCCF8091C6000895F8DF44
:0C7FD0008032E9F784E1EDDFA895089508
:00000001FF

 

Note that the "end of file" data from the FIRST file only has been removed.  The HEX files contain address data in them, so it knows where to load into. Therefore, it doesn't matter which one comes first, as long as all "end of file" markers are removed except for the last one.

 

FYI here are the Intel HEX file data types (the 4th byte):

 

// Intel HEX record types
#define DATA_RECORD 00
#define EOF_RECORD 01
#define EXT_SEGMENT_ADDR 02
#define SEGMENT_START_ADDR 03
#define EXT_LINEAR_ADDR 04
#define LINEAR_START_ADDR 05

 

Typical HEX record:

 

:107E00001FBE1092660084B714BE8D7089F0109268

 

Green: Record size in HEX (i.e. 0x10 = 16 bytes)

Violet: Load address in HEX

Blue: Record type (see above)

Orange: Actual data

Red: 8 bit checksum

 

The INTEL Hex format also supports addresses beyond 0xFFFF by using either the Intel "Segment/Offset" scheme or a linear scheme.  Take a look at the first 2 records of my MEGA2560 bootloader code:

 

:020000023000CC
:10F8000001E20EBF0FEF0DBF11241FBE2AC080936F

 

See.. the first record type is 0x02 (extended segment address) followed by a 16 bit offset in little-endian.

The second record's first address is 0xF800, so combined this means that the bootloader starts loading into 0x03F800 (260096 in decimal).  Take the flash size of the MCU (262144) and subtract the bootloader start address (260096) and you get 2048 which is the size of my bootloader (2K). See? Cool, huh?

 

Good reference (a PDF file):  LINK

 

Lastly, you'll need to be sure that the BLB (bootloader lock bits) are set properly to allow you to burn both your application AND the bootloader. Then you should set the BLB back to protect the bootloader area.

 

Hope this helps.

 

 

Thanks for your answer.

I tried and its working.

 

 

:107E00001FBE1092660084B714BE8D7089F0109268

As you said violet color is showing address in hex.

As I set 0x3800 start bootloader section address but why its showing 7000 at beginning line in hex file?

 

few lines of hex file of bootloader

:107000000C945A380C9464380C9464380C9464389A
:107010000C9464380C9464380C9464380C94643880
:107020000C9464380C9464380C9464380C94643870

 

...................

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

imrana326 wrote:
As I set 0x3800 start bootloader section address but why its showing 7000 at beginning line in hex file?
Word versus Byte - tons of prior threads explain this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

Could this merging of the 2 .hex files together be also replicated for a Linux makefile setup?

For example to have a make flash2 command that would merge the bootloader and the application hex and the flash them to the microcontroller?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bbogdanmircea wrote:
be also replicated for a Linux makefile setup?
Sure. srec_cat works just as well in Linux as Windows.

 

If you are .deb user (Debian, Ubuntu etc) then this:

 

https://packages.debian.org/search?searchon=contents&keywords=srec_cat&mode=exactfilename&suite=buster&arch=any

 

shows that you need to "apt-get srecord" to install it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, now that I am thinking again, better for me would be that just when flashing the application the bootloader would not be erased.

Is that also possible from avrdude?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

bbogdanmircea wrote:
Is that also possible from avrdude?
Depends on the AVR - Xmega support that, tiny/mega do not. Not sure about AVR-0/AVR-1 but as they are really Xmega they probably do too. (though they are a bit odd having the bootloader at 0 so maybe not?)