XMEGA programming via bootloader & Intel .hex files

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

Hi all,

 

I've written a bootloader for an ATXmega128A1U using AVR1316 and the flash files from XBoot. I have my own UI program which communicates with the main application firmware (not important here) and programs new firmware via the bootloader.

Upon power-up the bootloader runs. It lasts for 5 seconds then jumps to the main application section, unless within that 5 seconds a programming command is sent to it via uart. If so the next bytes received are stored into a page buffer (unsigned char array with 512 elements) and whenever the buffer is full I program that page to the relevant address. This is repeated until the whole hex file is programmed. I've tested this and I've successfully programmed a page of flash. My question relates to Intel .hex files - will the hex files generated by AS7 always consists of full pages? Because if not then the last page of the file will not be programmed in my case as I've written it to wait for full pages to be received. I can change the bootloader if this is the case its not a problem, I just need to know and so far I've not been able to find out.

Any feedback would be great! If I've missed any info out which any of you need to help me then let me know and I'll shed some light. Thanks in advance! 

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

Intel Hex files will not necessarily contain full pages of data and in some cases the segments may not even be contiguous. If you need to only send full pages, it would be up to your "UI program" to make sure this happens.

 

It bootloaders I have written, it expects a start address and length of data header for each block transferred and the UI transfers an end of transmission when it reads the termination line from the hex file (":00000001FF").

David

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

I've never understood anyone putting the complexity of an Intel decoder into a boot loader (which is the only code that has to be simple and 100% error free). Why not simply do the hex to bin using powerful tools on the PC then just send the binary (and a separate base address if not always 0).

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

I'm not decoding the hex files in my bootloader, I decode the hex files line by line in my UI, extract the data from them and send that on its own. My bootloader simply loads each character received into buffer the same size as my uC's flash pages, then when its full it programs it.

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

Thanks for the advice. What would you say then, to me doing something like this: In my UI, if I find a partial page, simply transmit 0xFF for the remainder of that page and let the bootloader carry on as normal? Empty flash locations should contain 0xFF correct?

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

Then if you are using something like libbfd to read the hex what's the issue? You should get a block of binary and a length. If that length is not a multiple of the SPM page then, yes, you may want to pad it with trailing FFs to the next page boundary.

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

The issue was essentially me not knowing enough about .hex files, not knowing weather a .hex could contain pages that aren't full, and what to do if this was the case. Between yourself and frog_jr you've answered my question, so thanks! smiley

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

Hex can have records in any order and they can be sparse (holes), there's even a potential for more than one record at the same address - so to read a complete image you really need to read the entire thing first and process all the records and construct a memory buffer that represents the complete load image. Then either use that binary or rewrite a padded/linear new .hex file. For the latter you can achieve that with srec_cat from the Srecord set of utilities.

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

The flash memory is so small, I just allocate a big buffer for the largest possible size I will need (say 256k) and full it with 0xFF. Then I load and decode the .hex file into that buffer, wipe the MCU's flash and send any page that isn't all 0xFF. I also bury some metadata in the firmware image so I know what the page size etc. is.

 

https://github.com/mojo-chan/hid...

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

Okay so I've just programmed my entire application image via my bootloader successfully... I think? Everything appears to be working, however I read the .hex file back out of my device and used WinMerge to compare it to the actual .hex file I attempted to program my device and there are some subtle differences however I'm not sure that they actually matter?

 

These are the last 3 lines (before the termination line) of the .hex I programmed:

    :0C45200024BF338701960895F894FFCF64
    :10452C004753504330303030003F3F3F0030302F46
    :08453C0030302F303030300028

 

And these are the last 3 lines I read back from my device after programming (again, no termination line included):

    :1045200024BF338701960895F894FFCF4753504333
    :1045300030303030003F3F3F0030302F30302F30B0
    :1045400030303000FFFFFFFFFFFFFFFFFFFFFFFFE7

 

As previously discussed I've padded out with 0xFF. The reason I'm not sure that it matters is because on one hand, if you observe the addresses and the data then the data is the same in all the same places, however on the other hand it is a difference.

 

Can anyone advise?

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

They are equivalent. The hex created by the programming tool may make a separate entry for the initialized variables, whereas the read program does not make a distinction since it ends up being contiguous programmed bytes.

David

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

Don't use merge tools on .hex files until you pass them both through a utility (srec_cat, objcopy, etc) that will normalise them.

 

Personally if I want to compare binary I compare binary! So I'd take both. Convert each to binary and then use a tool such as the excellent vbindiff in Linux. Even plain diff will tell you if they are binary equal. Another way is to MD5 both the binaries and check they have the same hash.

 

All you lose at the time of change from hex to bin is the base address but you can check that visually by looking at the .hex