Many tool chains and linker are able to produce S19 files, such as with the GNU tools it is the ‘objcopy‘ which does this job (see “Binary (and S19) Files for the mbed Bootloader with Eclipse and GNU ARM Eclipse Plugins“). But these tools usually cannot handle the special cases. For example on the Freescale Kinetis K64F my serial bootloader (see “Serial Bootloader for the Freedom Board with Processor Expert“) had a problem with these lines in the S19 file:
The interesting thing was that my bootloader worked fine, except the flash was not correctly programmed :-(. With a lot of trial-and-error, I found out that the problem is because the blocks did not start on a 64-bit aligned address at 0xC30C. So somehow the blocks needs to be 64-bit (8 byte) aligned with using the Flash Memory (FTFE) module, and 8 bytes need to be written in one cycle. When I merged the ‘not aligned’ lines in the S19 file, everything worked fine :-).
When I have found this out, issues reported by others suddenly made sense too, and I believe similar reports/requests in the Freescale community are triggered by that.
So I have two options:
- Add special code in the bootloader/flash programmer to deal with that situation.
- Make sure that the S19 files are easily consumable by the bootloader and are correctly aligned.
I prefer option 2, as this does not blows up my bootloader code. Instead, I can easily align the S19 files with the SRecord (http://srecord.sourceforge.net/) utility (see “CRC Checksum Generation with ‘SRecord’ Tools for GNU and Eclipse“).
The ‘srec_cat’ tool in SRecords has the following option:
This option may be used to specify the exact number of data bytes to appear in each output record. There are format-specific limitations on this value, you will get an error if the value isn’t valid.
Assuming that my S19 file has the starting memory blocks aligned to 64-bit (which has to be the case), specifying an Output_Block_Size to a multiple of 8 bytes will make sure that every line in the S19 will be 8 byte aligned.
There is a second related option to that:
From time to time, with large files, you may notice that your data records are spit unexpectedly on output. This usually happens where record lengths are not a power of 2. If this bothers you (or your comparison tools) this option may be used to repack the output so that SRecord’s internal block boundaries are not visible in the output.
So using both options should make sure that my blocks are properly aligned.
For example I can use this command line
srec_cat test4.s19 -Output_Block_Size 8 -Output_Block_Packing -output test4new.s19
and it will transform/align my S19 file so everything is 64-bit aligned:
And I can easily have multiple 8-byte blocks on one line too to reduce the overhead in the file:
srec_cat test4.s19 -Output_Block_Size 64 -Output_Block_Packing -output test4new64.s19
produces a file with 64-byte aligned records:
Now it is an easy step to have this integrated for example into the Eclipse build process as a post-build action (see “Executing Multiple Commands as Post-Build Steps in Eclipse“).
Certain flash devices need special alignment. It is easier to produce properly aligned S19 files than making a bootloader more complex. The srec_cat SRecords tool makes it easy to control the size and alignment of the records.
Happy Aligning 🙂
- SRecord tool to manipulate and convert S19 files: http://srecord.sourceforge.net/
- Serial Bootloader article: Serial Bootloader for the Freedom Board with Processor Expert
- Creating S19 files with GNU objcopy: Binary (and S19) Files for the mbed Bootloader with Eclipse and GNU ARM Eclipse Plugins
- Freescale K64F: http://www.freescale.com/products/arm-processors/kinetis-cortex-m/k-series/k6x-ethernet-mcus/kinetis-k64-120-mhz-ethernet-usb-256kb-sram-mcus:K64_120
- Executing one or multiple commands after linking: Executing Multiple Commands as Post-Build Steps in Eclipse
I am very suprised that you go for solution 2 rather than solution 1.
When supplying bootloaders for other people to use, it can be a great problem to “force” then to do things with the output generated by “their” tools (whichever tools they happen to be used) rather than make the actual operation robust. Many programmers don’t even know what SRECs are (which initially comes as a surprise but in the real-world this is the case) and it is simplest in the long run to make things as fool-proof as possible rather than investing time educating them to work around “known” deficiencies in what you are supplying to them.
In the flash driver that I use there is an 8 byte intermediate buffer that transparently handles this and adds around 10 lines of C code and 8 bytes to the RAM use. This should be insignificant even in the smallest boot loader and so seems to be the correct way to go.
yes, I agree with you for a bootloader you supply to other users to use/load binaries. But we are using that bootloader internally, so we have control over the firmware update files. Even more that we have some boards with that bootloader already in the field, so having it changed in the S19 file was the right approach in my view.
I see – your post does state twice that the reason was to avoid complexity and so this was not clear.
Often a serial loader can update itself (a requirement in mayby 15% of products I have been involved with) which then allows updating the loader in the field too. You may consider adding this fall-back in the future 😉