S-Record, Intel Hex and Binary Files


My earlier posts were around the Kinetis gcc compiler which comes with CodeWarrior for MCU10.3. MCU10.3 comes as well with the Freescale Kinetis compiler as in MCU10.2. In “S-Record Generation with gcc for ARM/Kinetis” I explored how to generate S19 or other output files with gcc. However, you only can produce one file format at a time. What if I need multiple formats or a different format. What if I need to do the same with non-gcc build tools? S-Records are usually easy as supported in the linker. Other formats need a bit more plumbing. So this post is how I can create and manipulate the different output formats, so I can use it with a bootloader.

S19 Files

The format of S19 (or S-Records) is explained in this Wikipedia article. To generate S-Records (or S19 files) e.g. with the Freescale Kinetis (non-gcc) is easy: there is a check box for it:

Generate S-Record Option

Generate S-Record Option

This passes the -srec option to the linker, and produces something like this:

S0030000FC
S3FD0000000080C00020DDBE0000CDAD0000F1AD0000F5AD0000F9AD0000FDAD000001AE000005AE000009AE00000DAE0000D9AD000011AE000015AE0000E5AD00005583000019AE00001DAE000021AE000025AE000029AE00002DAE000031AE000035AE000039AE00003DAE000041AE000045AE000049AE00004DAE000051AE000055AE000059AE00005DAE000061AE000065AE000069AE00006DAE000071AE000075AE000079AE00007DAE000081AE000085AE000089AE00008DAE000091AE000095AE000099AE00009DAE0000A1AE0000A5AE0000A9AE0000ADAE0000B1AE0000B5AE0000B9AE0000BDAE0000C1AE0000C5AE0000C9AE0000CDAE0000C9
S3ED000000F8D1AE0000D5AE0000D9AE0000DDAE0000E1AE000085B5000085B50000E5AE0000E9AE0000EDAE0000F1AE0000F5AE0000F9AE0000FDAE000001AF000005AF000009AF00000DAF000011AF000015AF000019AF00001DAF00006982000021AF000025AF000029AF00002DAF000031AF000035AF000039AF00003DAF000041AF000045AF000049AF0000997D00004DAF000051AF000055AF000059AF00005DAF000061AF000065AF000069AF00006DAF000071AF00004984000075AF000079AF00007DAF000081AF000085AF000089AF00008DAF000091AF000095AF000099AF00009DAF0000A1AF0000DC
S3FD0000041008B5DFF82C00006800280AD102F06EF80121DFF820000068016300F02FF902F075F8DFF810000068006BBDE808407047E828FF1F1400FF1F0021DFF808000068016370471400FF1F08B502F07BF8DFF860104A684AF22011C0F207014A434AF22011C0F20701081A10184108DFF840008160DFF83C008168DFF83400006881420AD2DFF82C0081684DF29000C0F203000918DFF81C008160DFF814008168DFF810000160DFF808008068BDE808407047D828FF1FF8B507460E46DFF8D0008078002860D0DFF8C4008178DFF8C400405C00F0020000282FD0DFF8B410DFF8AC0080780918087800F0FD000870DFF89C008078032100F00CFA39
....

X-Record (or Intel Hex)

The other option is to produce an X-Record file with passing an -xrec option to the linker:

X-Record or Intel Hex option

X-Record or Intel Hex option

Actually that option naming is confusing, as that file format it produces s known as Intel Hex. Below is the beginning of the file produced for the same application as above, but in X-Record/Intel Hex format:

:020000040000FA
:4000000080C00020DDBE0000CDAD0000F1AD0000F5AD0000F9AD0000FDAD000001AE000005AE000009AE00000DAE0000D9AD000011AE000015AE0000E5AD00005583000075
:4000400019AE00001DAE000021AE000025AE000029AE00002DAE000031AE000035AE000039AE00003DAE000041AE000045AE000049AE00004DAE000051AE000055AE000030
:4000800059AE00005DAE000061AE000065AE000069AE00006DAE000071AE000075AE000079AE00007DAE000081AE000085AE000089AE00008DAE000091AE000095AE0000F0
:4000C00099AE00009DAE0000A1AE0000A5AE0000A9AE0000ADAE0000B1AE0000B5AE0000B9AE0000BDAE0000C1AE0000C5AE0000C9AE0000CDAE0000D1AE0000D5AE0000B0
:40010000D9AE0000DDAE0000E1AE000085B5000085B50000E5AE0000E9AE0000EDAE0000F1AE0000F5AE0000F9AE0000FDAE000001AF000005AF000009AF00000DAF000079
:4001400011AF000015AF000019AF00001DAF00006982000021AF000025AF000029AF00002DAF000031AF000035AF000039AF00003DAF000041AF000045AF000049AF0000B0
:40018000997D00004DAF000051AF000055AF000059AF00005DAF000061AF000065AF000069AF00006DAF000071AF00004984000075AF000079AF00007DAF000081AF000028
:2001C00085AF000089AF00008DAF000091AF000095AF000099AF00009DAF0000A1AF00000F
:020000040000FA
..........

Binary Files

Both above formats (S-Record and Intel Hex) are text formats. Another common format is the ‘binary’ format. In this format, the memory is just written byte by byte ‘as is’. So how can I generate such a format?

Burner

The solution is to use the burner utility which is an integrated tool for the 8/16bit (Freescale S08) tool chain. For S08 projects I can have a *.bbl (Batch Burner Language) file in my project to generate all kind of output formats. The syntax of the .bbl file is explained in the documentation, see this link. And documentation is not much-needed as there is a graphical user interface.

Hint: the Burner utility is really powerful and can be used in batch jobs to do all kind of manipulations on the files: converting between formats, extracting or merging files, and so on.

Burner Executable

The burner executable is located inside the MCU10.3 MCU\prog folder along with the S08 build tools. But it can be used for anything which produces as standard ELF format.

Burner executable inside MCU prog folder

Burner executable inside MCU prog folder

Command Line Interface

The burner has a batch/command line interface. As burner.exe is a Win32 application, it can be used from the DOS shell or make files with the piper.exe in front to have it as Console32 application:

piper.exe burner.exe -h
Burner Command Line Interface

Burner Command Line Interface

Graphical Interface

Starting the Burner.exe in graphical mode (e.g. double clicking with the Windows Explorer) opens it in a window mode:

Burner UI

Burner UI

I want to use the graphical mode to configure it to produce a script file for me, which I can use later to produce a binary file (or anything I want). For this I open the Burner Dialog:

Burner Input and Output Files

Burner Input and Output Files

Here I specify my input and output files.

In the ‘Content’ tab I specify the format and memory range, plus what should happen for memory gaps (undef byte):

Burner Content Settings

Burner Content Settings

The ‘Command Line’ tab shows the generated command line (batch burner language) source I could use in make files or as a post-build step:

Burner Command File

Burner Command File

I can execute this directly. For this I switch back to the ‘Input/Output’ tab and press the ‘Execute’ button:

Burner Execute Button

Burner Execute Button

This reports the status and result to the console:

Burner Console Output

Burner Console Output

Inspecting the generated binary file with EHEP shows this:

Binary File in EHEP Hex View

Binary File in EHEP Hex View

Automation: Post-Build Step

While the UI mode is fine to explore things, I want to use the burner as part of my build. For this, I use the same concept as I used in my CRC post: Build Steps.

But first I need to create a file with my commands in it. For this, I can copy-paste the commands from the Burner ‘Command File’ tab:

Burner.bbl with Macros

Burner.bbl with Macros

Note that I have replaced the absolute path with a macro (%ABS_FILE%). I want to have my script working relative to my project. I will pass that variable in the command line to the burner below.

Next is to set up a post build step. For this I’m using the following command line:

"${MCU_TOOLS_HOME}/prog/piper.exe" "${MCU_TOOLS_HOME}/prog/burner.exe" -F="${ProjDirPath}\Project_Settings\Linker_Files\burner.bbl" -Env"ABS_FILE=${BuildArtifactFileName}"
Post Build Step with the Burner

Post Build Step with the Burner

I use the piper.exe so the burner is running in command line mode. The -F option passes the command file in batch burner language. And the -Env option passes an environment variable I can use as above in my batch burner file.

With this, when I build my application, the binary (or whatever I do with the burner) is created at the end:

Burner Post Build in the Console View

Burner Post Build in the Console View

And for my burner file I have the output (here a binary file) generated in my project:

Burner file and output file in project

Burner file and output file in project

Summary

I’m using the above approach for my S08, ColdFire and Kinetis projects and it works perfectly for me. Especially the flexibility and power of the burner utility is key for me. And it solves the usual build tool limitation that only one format is supported. With the burner I can manipulate the format, produce multiple formats or pretty much do whatever I want.

Happy Burning 🙂

Advertisements

42 thoughts on “S-Record, Intel Hex and Binary Files

  1. I have only a question: i try to burn a binary file from a .afx. I have the same command line of your example, but burner creates an incomplete file, the final part of afx is ignored and I find only FFFFFFFF……. so when I flash the bin on target, obviously, it doesn’t work! Could you help me?

    Like

      • I don’t think so, because the application is about 60 KB and the length parameter is 0x80000. It seems like “burner” can’t see the last part of code. I don’t know why (a bug, is possible?). If I generate s19 file with codewarrior and then convert it to bin it works.

        Like

      • Yes, maybe this is indeed a bug. I suggest you send a service request to Freescale on this so they could look into this. And if you don’t mind: send me your file and burner file to the email address mentioned on the About page. If I have bandwidth, I can look into it.

        Like

  2. Pingback: How (not) to Secure my Microcontroller | MCU on Eclipse

  3. Hi erich, i have one doubt can we convert two types of Motorolla S-records? Ex- S3 to S2 or vice-versa. If we convert it considering all checksum and everything will it work?
    And try to flash it instead of S2 with the converted S2 will it really work?

    Like

    • Hi Ramanujan,
      S2 is using 3 bytes for the address, and S3 4 bytes. So if you convert a S3 S19 record into one with S2, then you will loose the upper address bytes, so this typically will not work for a 32bit address space architecture. But for example is you have an S3 S19 file for a 16bit address architecture, you should be able to convert it into a S2 type file.

      Like

      • Thank you Erich for the fast reply. Ok i got the point imagine i just merge the data from one S-record to another .
        Ex ; if i copy only the data from S3 to S2 not the address and ill take care of the Checksum. So address will be as in S2 but only data will it work?

        Like

      • Hi Erich,
        yes i do know that both adress bytes are different
        Take an example below. One is S2 and other is S3

        S21F”000000″XXXXXXXXXXXXXXX

        S321″00000000″DDDDDDDDDDD

        Resulted Merged file.

        S21F”000000″DDDDDDDDDDD

        Am keeping the address as it is and am copying only the data from S3 to S2.and even checksum is taken care while merging.
        Will this case works?

        And is there any separate length limits to S2 and S3 type records?

        Hope u got the point and scenario exactly.

        Like

      • Hi Ramanujan,
        yes, some tools are limited in the amount of code bytes they can read for each S19 file line. A safe number would be 32 bytes per line.
        If you are using the burner.exe mentioned in this article, you can configure this with an option.
        I suggest as well that you use that burner.exe to merge/convert S19 files, as this would be the most convenient way at least for myself.

        Like

  4. Pingback: Decoding S19 Files | MCU on Eclipse

  5. Pingback: Serial Bootloader for the Freedom Board with Processor Expert | MCU on Eclipse

  6. Is it possible to download the burner utility separately? Or is it only available as part of the (huge) CodeWarrior package?

    Like

    • Hi Allen,
      it is not available separately. It is present as well in the classic (non-Eclipse) CodeWarrior version (e.g. for S08 or S12), but this does not make much difference. Plus the S08/S12 version is an older one, altough I believe not much has been changed (if anything at all).

      Like

  7. Pingback: New P&E OpenSDA Firmware v114 | MCU on Eclipse

  8. Hello Sir,
    I was analyzing my SREC file to look at address 0x40C location which can sometimes secure.
    I was analyzing a file of the SREC ,for e.g – “S1130040C9080000C9080000C9080000C908000068”.
    I saw the wiki article – http://upload.wikimedia.org/wikipedia/commons/f/f1/Motorola_SREC_Chart.png
    which looks at the 4 bytes (bytes 4,5,6,7) for the address –
    In this case address is decoded as – 0040.
    The last 2 bytes are check-sum, which means “C9080000C9080000C9080000C9080000” is the payload data. So how can I fine 0x040C here. Am a bit confused.
    Am I looking at this right 🙂

    Vinod

    Like

  9. Pingback: GNU Additional Tools: Create Flash Image, Print Size and Extended Listing Options | MCU on Eclipse

  10. Hi Erich,

    Is there a standalone Windows utility that can be used to flash ELF or hex files to Kinetis L devices? Or a way for CodeWarrior to flash alternative ELF and hex files to an opened project?

    I ask because we’re trying to use the same binary firmware files across two development teams sharing code using Git. I’ll explain myself. Team A builds the project and the compiler spits out ELF and hex files. They flash them (using CW’s built in tools and a Multilink FX) unto a custom KL46 board. Then Team A uploads the project’s non-derived files to a Git server. Team B then pulls these non-derived files and is forced to run CW’s build process to generate ELF and hex files. These binary and build files generated by team B have a different time stamp than those generated by Team A. In practice, however, both teams have binary files that produce the same behavior on their KL46 boards.

    So this issue is more of a convenience factor to track the project’s development history.

    The only way that I can think around it is to share a Zip folder containing Team A’s binary files and have Team B copy and paste these files unto the project’s FLASH folder. Of course, if Team B adds features and runs CW’s build process then new binary files are generated and thus they would need to be shared back with Team A.

    Thanks in advance!

    Like

  11. Pingback: Recovering the FRDM-K64F Bootloader, or: Cloning the Program of a Microcontroller | MCU on Eclipse

  12. Hi Erich,
    I want to write a 4 bytes value into hex file at a particular location during compiling. Of course, i can follow flash writing routines. But, is it possible to include this in compiler settings so that i can save a few CPU cycles during start-up? BTW i need it on kinetis with CW10.x.

    Thanks,
    Pramod

    Like

    • Hi Pramod,
      as the hex file is generated by the linker, you cannot do this directly in the compiler. But you can have a constant piece of data in your code/compiled, which then will end up in the hex file generated by the linker. You might try out different things, but I think this is very doable.
      Erich

      Like

  13. Hello, Erich

    I have followed your instructions for a MQX 4.2 project, but I failed to generate a .srec file. I got the following error from CodeWarrior 10.6 Builder: “mingw32-make: *** [mfs_usb_twrk20d72m.hex] Error 1.”

    Do you know what could be causing this issue?

    Thanks and regards,

    Marco Coelho

    Like

      • Hi, Erich

        Here it goes:

        **** Build of configuration int flash debug for project mfs_usb_twrk20d72m ****

        “C:\\Freescale\\CW MCU v10.6.4\\gnu\\bin\\mingw32-make” -j8 pre-build main-build
        C:/Freescale/Freescale_MQX_4_2/mfs/examples/mfs_usb/build/cw10gcc/mfs_usb_twrk20d72m/makedir.bat “C:/Freescale/Freescale_MQX_4_2/mfs/examples/mfs_usb/build/cw10gcc/mfs_usb_twrk20d72m/int flash debug”
        ‘ ‘
        ‘Executing target #8 mfs_usb_twrk20d72m.hex’
        ‘Invoking: ARM Ltd Windows GNU Create Flash Image’
        “C:/Freescale/CW MCU v10.6.4/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-objcopy” -O srec mfs_usb_twrk20d72m.elf “mfs_usb_twrk20d72m.hex”
        makefile:112: warning: overriding recipe for target `mfs_usb_twrk20d72m.elf’
        makefile:71: warning: ignoring old recipe for target `mfs_usb_twrk20d72m.elf’
        C:/Freescale/CW MCU v10.6.4/Cross_Tools/arm-none-eabi-gcc-4_7_3/bin/arm-none-eabi-objcopy: ‘mfs_usb_twrk20d72m.elf’: No such file
        mingw32-make: *** [mfs_usb_twrk20d72m.hex] Error 1

        Like

      • Hi Marco,
        the problem is that mfs_usb_twrk20d72m.elf cannot be found. Does that file exist in your FLASH subfolder?
        And why do you have a ‘pre-build’ and a ‘main-build’?
        maybe you simply should delete the output (DEBUG? FLASH?) folder to get a clean state?

        Like

  14. Hello, Erich

    I tried to delete Debugger and Flash Folders and recompile the code as you suggested, but it didn’t work. Every time I enable Flash Image generation in CodeWarrior for any MQX 4.2 demo (I just tested for several other MQX 4.2 demos), I get this error and the *.elf file simply disappears.

    Can you reproduce this problem on your side?

    Marco

    Like

  15. Pingback: Merging S19 Files | MCU on Eclipse

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s