CRC Checksum Generation with ‘SRecord’ Tools for GNU and Eclipse

One of the things missing for Embedded in the GNU linker is that it cannot generate a CRC checksum. Luckily, there is the solution of using SRecord:

SRecord 1.64 Web Page
SRecord 1.64 Web Page

Outline

Because the GNU (e.g. GNU ARM Embedded/launchpad) toolchain does not include a CRC checksum calculation function, I’m showing how the SRecord utility can be used for this. The SRecord tool is an open source project on SourceForge (http://srecord.sourceforge.net/). It is a command line utility which runs on many platforms. I’m using it in this post with Eclipse (e.g. Freescale Kinetis Design Studio, or any other Eclipse based toolchain using the GNU ARM Embedded (Liviu) with GNU for ARM (GNU for ARM Embedded (Launchpad): https://launchpad.net/gcc-arm-embedded). It goes through the steps to create a checksum, add it to the binary image and checking that checksum in the application.

💡 As the name ‘SRecord’ suggests it deals with S-Records (or S19) files. This is just the default format. SRecord can read and generate pretty much any file format which is used for programming memory devices or microcontroller.

Installation

Go to http://srecord.sourceforge.net/ and download the binaries of your choice from http://srecord.sourceforge.net/download.html. Of course you can as well download the sources and build it yourself. That site hosts as well a lot of good documentation, but if you are a (mostly) Windows user as I am, then be prepared for some Windows user bashing ;-).

SRecord comes with three utilities:

  1. srec_info: used to retrieve basic information about the file. It reports things like start address.
  2. srec_cmp: used to compare two files. This utility only tells you if two files are (memory-wise) different or not, but not more.
  3. srec_cat: This tool is used to extract/add/create/merge/etc files.

All the three tools are command line tools and have extensive support for options. So they easily can be used with make files, scripts or from IDEs as Eclipse. See http://srecord.sourceforge.net/man/index.html for the online manual.

💡 The cool part is that they support ‘input generators’ and ‘filters’, see http://srecord.sourceforge.net/man/man1/srec_input.html

Generating S-Record Files

Usually the linker main output file is an ELF/Dwarf file which has both code and debug information. The ELF/Dwarf file is used for debugging. All toolchains I’m aware of are able to generate more output files beside of the ELF/Dwarf: S-Record (S19), Intel Hex, etc files. For example in Kinetis Design Studio use the ‘Create flash image’ option in the project settings and press ‘Apply’:

Create Flash Image
Create Flash Image

Then you can select the ‘Motorola S-record’ option in the project settings:

Motorola-s Record Option
Motorola-s Record Option

The generated S19 file can be found in the Debug output folder:

S19 File
S19 File

srec_info

srec_info gives basic information about the file:

srec_info Debug\FRDM-KL25Z_CRC.srec

gives

Format: Motorola S-Record
Header: "FRDM-KL25Z_CRC.srec"
Execution Start Address: 000007CD
Data:   0000 - 00BF
        0400 - 0C3B

See http://srecord.sourceforge.net/man/man1/srec_info.html for further information

srec_cmp

srec_cmp is a program which can compare two files. Unlike a normal diff, it compares two ‘memory’ files. For example

srec_cmp app1.srec app2.srec

gives

srec_cmp: files "app1.srec" and "app2.srec" differ

See http://srecord.sourceforge.net/man/man1/srec_cmp.html for further information.

srec_cat

srec_cat is the ‘main’ program of the suite. As the name indicates it can concatenate multiples files. But it can do much more:

  • Converting files
  • Inserting or removing data
  • Joining/splitting files
  • Moving data
  • Fill in patterns or fill the blanks
  • Creating data
  • Changing data
  • and of course creating multiple kinds of checksums 🙂

There are many good examples how to use it here: http://srecord.sourceforge.net/man/man1/srec_examples.html

Crop and Generating a Hex Dump

One thing I’m using often is to do a memory dump of my s-record. I can do this with the -hex-dump option:

srec_cat -crop -Output - -hex-dump

💡 After the -Output option there is usually a file name. Using ‘-‘ as file name will write the output to the console.

For example

srec_cat FRDM-KL25Z_CRC.srec -crop 0x500 0x530 -Output - -hex-dump

produces

00000500: BD 46 80 BD B0 B5 82 B0 00 AF 78 60 39 60 10 4C  #=F.=05.0./x`9`.L
00000510: 00 25 15 E0 23 1C 1B 02 9A B2 23 0A 9B B2 19 1C  #.%.`#....2#..2..
00000520: 7B 68 58 1C 78 60 1B 78 5B B2 59 40 FF 23 19 40  #{hX.x`.x[2Y@.#.@

I use that approach to quickly inspect or dump content of my image (.elf/.s19) file. Additionally, this allows me to inspect the memory of the target and compare it with what I have in my file.

💡 The -crop command crops (or cuts) everything out of the data except the range specified (the end address not included).

Filling Memory

Typically a data file as the Motorola S19/SRecord only describes the bytes to be programmed, but not the ‘holes’ or gaps in the memory map. If building a CRC over a memory area with gaps, I need to define it first. For this I can use the  -fill command:

-fill  [ ]

To fill multiple areas, e.g. to fill 0x100-0x1FF and 0x300-0x3FF with 0xFF, I could use

-fill 0xFF 0x100 0x200 -fill 0xFF 0x300 0x400

Or I could use a list of <start>…<end> addresses:

-fill 0xFF 0x100 0x200 0x300 0x400

For the microcontroller on the FRDM-KL25Z board (a KL25Z128) I have the following memory map:

MEMORY {
  m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000000C0
  m_text      (RX) : ORIGIN = 0x00000410, LENGTH = 0x0001FBF0
  m_data      (RW) : ORIGIN = 0x1FFFF000, LENGTH = 0x00004000
  m_cfmprotrom  (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
}

To fill the interrupt table (m_interrupts) and the code (m_text) with 0xFF and dump it, I can use

-fill 0xFF 0x0000 0x00C0 0x0410 0x20000

Generating CRC

srec_cat supports many checksums. The challenge for me was to match the srec_cat way of generating the checksum with the right algorithm and polynom. An online CRC calculation utility on http://www.lammertbies.nl/comm/info/crc-calculation.html helped me to identify the matching CRC polynom and algorithm. In my applications I’m using the Big Endian CCITT CRC16. To generate it, use the following command:

-CRC16_Big_Endian 0x1FFFE -CCITT

-CRC16_Big_Endian or -crc16-b-e is used to store the CRC is stored in Big Endian format.

CRC16 Source Files

http://www.menie.org/georges/embedded/crc16.html is a great source for a CRC16 calculation function. Another even better one is on http://www.sunshine2k.de/coding/javascript/crc/crc_js.html. I have updated the source to match the 0x1D0F starting point which is used for -CRC16_Big_Endian. I changed the implementation to use a defined starting point: The interface file:

/*
 * Copyright 2001-2010 Georges Menie (www.menie.org)
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University of California, Berkeley nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _CRC16_H_
#define _CRC16_H_

#define CRC16_START_VAL  0x1D0F /* start value which is used by SRecord tool for -CRC16_Big_Endian */

unsigned short crc16_ccitt(const void *buf, int len, unsigned short start);

#endif /* _CRC16_H_ */

The implementation file:

/*
 * Copyright 2001-2010 Georges Menie (www.menie.org)
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the University of California, Berkeley nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "crc16.h"

/* CRC16 implementation according to CCITT standards */

static const unsigned short crc16tab[256]= {
	0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
	0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
	0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
	0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
	0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
	0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
	0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
	0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
	0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
	0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
	0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
	0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
	0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
	0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
	0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
	0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
	0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
	0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
	0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
	0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
	0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
	0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
	0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
	0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
	0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
	0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
	0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
	0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
	0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
	0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
	0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
	0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0
};

unsigned short crc16_ccitt(const void *buf, int len, unsigned short start)
{
	register int counter;
	register unsigned short crc = start;

	for( counter = 0; counter < len; counter++) {
		crc = (crc<<8) ^ crc16tab[((crc>>8) ^ *(char *)buf++)&0x00FF];
	}
	return crc;
}

Checking CRC in the Application

Below is a piece of code in the application which checks the CRC:

/*
 * Application.c
 *
 *  Created on: 16.04.2015
 *      Author: Erich Styger
 */

#include "Application.h"
#include "crc16.h"

#define CRC_RANGE_START_ADDR    0x00410 /* start addr */
#define CRC_RANGE_END_ADDR      0x1FFFE /* end addr, this one will not be counted */
#define CRC_VALUE_ADDR          0x1FFFE /* address of CRC (16bits) */

void APP_CheckCRC(void) {
  unsigned short crc;

  crc = crc16_ccitt((void*)CRC_RANGE_START_ADDR, CRC_RANGE_END_ADDR-CRC_RANGE_START_ADDR, CRC16_START_VAL);
  if (crc!=*((unsigned short*)CRC_VALUE_ADDR)) {
    for(;;) {} /* error! CRC does not match! */
  }
}

The above code assumes that the 16bit CRC is stored at address 0x1FFFE. The application checks the CRC for the code space from address 0x410 up to 0x1FFFD (which does *not* include the CRC itself which is at 0x1FFFE-0x1FFFF).

Using Command Files

Instead passing everything on the command line, I can call the SRecord tool suite programs with the options in an external file. The syntax is

<SrecordProgram> @filename

For example

srec_cat @crc_cmd.txt

Dumping the CRC for a memory range

Using the ‘@’ syntax, I can execute a script which calculates the CRC and dumps it for me so I can manually check it. For this I use the following content of a command file:

# srec_cat command file to dump the CRC for a code area
# Usage: srec_cat @filename
FRDM-KL25Z_CRC.srec          # input file
-fill 0xFF 0x0410 0x20000          # fill code area with 0xff
-crop 0x0410 0x1FFFE               # just keep code area for CRC calculation below (CRC will be at 0x1FFFE..0x1FFFF)
-CRC16_Big_Endian 0x1FFFE -CCITT   # calculate big endian CCITT CRC16 at given address.
-crop 0x1FFFE 0x20000              # keep the CRC itself
-Output                            # produce output
-                                  # '-' is special 'file': use console output
-hex-dump                          # dump in hex format

That way I can have things commented (comments start with ‘#’) and keep things readable. The above program calculates the CRC over a given range, stores the value at the artificial address 0x20000 (outside of the code area) and dumps the 16bit value on the console:

executing script to dump CRC value
executing script to dump CRC value

Incorporating the CRC Value into the Application

Knowing the CRC, I need to incorporate the CRC value itself into my application. One way would be to do this in the GNU linker script itself (see “FILLing unused Memory with the GNU Linker“). However, that would be a manual process:

  1. Determine the CRC value with SRecord and dump it
  2. Enter the CRC value into the linker script

Another approach would be:

  1. Generate the CRC with SRecord and produce the S19 file which only has the CRC in it (CRC S19 file)
  2. Merge the application S19 file with the CRC S19 file

This approach works very well, as srec_cat (as the name indicates) is excellent to concatenate files :-). To produce the CRC S19 file I can use the following command file:

FRDM-KL25Z_CRC.srec                # input file
-fill 0xFF 0x0410 0x20000          # fill code area with 0xff
-crop 0x0410 0x1FFFE               # just keep code area for CRC calculation below (CRC will be at 0x1FFFE..0x1FFFF)
-CRC16_Big_Endian 0x1FFFE -CCITT   # calculate big endian CCITT CRC16 at given address.
-crop 0x1FFFE 0x20000              # keep the CRC itself
-Output                            # produce output
FRDM-KL25Z_CRC.srec                # S19 with CRC only

With this, I have only the CRC in FRDM-KL25Z_CRC.srec.

Then I need to fill the unused areas in the application file. Here again, I can generate a ‘filled’ file:

srec_cat FRDM-KL25Z_CRC.srec -fill 0xFF 0x0410 0x1FFFE -Output FRDM-KL25Z_CRC_Filled.srec

Finally, concatenate the two files with

srec_cat FRDM-KL25Z_CRC_Filled.srec FRDM-KL25Z_CRC.srec -Output Debug\FRDM-KL25Z_CRC_Added.srec

However, this involves using temporary files which is not ideal. A better approach is to do everything in one step, with a single command file like this:

# srec_cat command file to add the CRC and produce application file to be flashed
# Usage: srec_cat @filename

#first: create CRC checksum
FRDM-KL25Z_CRC.srec                # input file
-fill 0xFF 0x0410 0x20000          # fill code area with 0xff
-crop 0x0410 0x1FFFE               # just keep code area for CRC calculation below (CRC will be at 0x1FFFE..0x1FFFF)
-CRC16_Big_Endian 0x1FFFE -CCITT   # calculate big endian CCITT CRC16 at given address.
-crop 0x1FFFE 0x20000              # keep the CRC itself

#second: add application file
FRDM-KL25Z_CRC.srec                # input file
-fill 0xFF 0x0410 0x1FFFE          # fill code area with 0xff

#finally, produce the output file
-Output                            # produce output
FRDM-KL25Z_CRC_Added.srec

To me, this is really a cool thing of the SRecord tool: the ability to line up files and content and then merge it 🙂

And as expected: the application image file has the CRC added:

CRC Added to the Application Image File
CRC Added to the Application Image File

Adding CRC as Post-Build Step

Now I have the ability to add the CRC to my application file. It would be great if this could be part of my build process? Using normal make files, I simply would call srec_cat after linking. The same thing can be done with Eclipse as ‘Post-Build-Step’. For example to dump the CRC value, I can have this in the project settings:

Post Build Step to Dump CRC
Post Build Step to Dump CRC

💡 Keep in mind that the ‘current directory’ for the build process is the output folder, usually the ‘Debug’ folder.

And it will dump the CRC at the end of the build process:

srec_cat as post-build step in the Eclipse Console View
srec_cat as post-build step in the Eclipse Console View

The same way I can add the CRC to the application:

Adding CRC to Application
Adding CRC to Application

However, this will fail for a clean build:

Error while adding CRC
Error while adding CRC

The reason is that the post build step is executed *before* the S19 file is generated. The solution is to add the generation of the S19 file to the post build step too. It is possible to execute multiple post-build steps (see “Executing Multiple Commands as Post-Build Steps in Eclipse“), just be aware that the separator on Windows is ‘@’ and it is ‘;’ on Linux:

💡 One strange thing I noticed: as soon as I had multiple commands, I had to use ‘/’ instead of ‘\’ on Windows.

Generating S19 and CRC
Generating S19 and CRC

With this, everything works as expected:

Console Output generating S19 file and adding CRC
Console Output generating S19 file and adding CRC

Summary

Generating a CRC is not possible directly with the GNU linker. But this is not a problem, as there is an even more powerful way with the ‘SRecord’ utilities: with the SRecord utilities I can almost any manipulation of the output files I need, plus best of all: it is open source too 🙂

I have put my project used in this post on GitHub here: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/FRDM-KL25Z/FRDM-KL25Z_CRC

Links

56 thoughts on “CRC Checksum Generation with ‘SRecord’ Tools for GNU and Eclipse

  1. Nice writeup.
    I’ve used this in the past but never spent the time to integrate it with Eclipse.
    Another tool I’ve found quite handy is Srecordizer (srecordizer.com/). It allows you to browse and edit Srecord files. Worth a look.

    Like

  2. Great Post Erich,
    S-record is going to become one of my best programming tools !
    Many thanks also for having found an excellent crc16 source code.
    About this code : i’ ve seen that the parameter len for the function crc16_ccitt is ‘int’ type .
    This limit the checksum range to 32767 bytes. Since in my implementation, i needed to calculate the crc16 on a larger memory size ( 80 KB ) I’ve modified this parameter in ‘unsigned long’ type.
    It is obvious that more the range is increased and more possibilities exist for the crc16 to not detect an error ..
    Does exist some figures about this matter ? (i.e. : for a 32 KB of datas the probability to not detect an error is of xx % ) ..

    Like

  3. Pingback: Aligning S19 Records to 64-bit Boundaries | MCU on Eclipse

  4. What I haven’t solved yet is getting the checksum into the debugger; I think the debugger does not use the SREC file, so this would not work?

    Like

      • Thanks! Couldn’t replace the “application” with srec instead of elf because then no debugging – but found I could specify an additional ELF file, and specify it as an srec file containing the checksum.

        Like

  5. Pingback: Merging S19 Files | MCU on Eclipse

  6. CRC’s checking properties only apply over a given block size. While my math skills are a bit fuzzy as reading the many papers and books about CRCs tend to make my eyes glaze over from things like Syndrome Lengths of Galois fields. It is my understanding that a 16 bit CRC’s properties only hold over a block size of 4096 bytes minus one bit.

    Therefor a 32 bit CRC is needed for anything larger than 4K -1 bit.

    Perhaps you can find a math wiz in one of your students to turn all of this Galois crap into a real world paper that us in the Embedded world would actually understand. We don’t care about the polynomials, I accept the Math Gurus figured those out, etc. We want to known the formula for CRC5/8/16/32/64 is good for X number of bits, real world kind of stuff we need to know.

    Like

  7. Hi Eric,
    i try to use your program, bu the result of crc from s record and from the application it’is dfferent and i dont’ understand why. Do you have any suggest? Thank you, Anna

    P.S. : I use a STM8.

    Like

    • Hi Anna,
      if the result is not the same, the issue is most likely
      a) you are not calculating the same bytes/memory areas
      b) you are not using the same polynom and start value
      Are you using the CRC method I have presented with the same settings?
      I hope this helps,
      Erich

      Like

      • Thank you for the faster answer,
        i need to calculate the crc in the flash area memory.
        I use the some polynom and start value, even if i read in the s record manual that the start point id 0xFFFF. Itry change it but the value is different.

        thabks,
        Anna

        Like

        • Hi Anna,
          to verify the polynom, start value and memory area is correct, I recommend that you calculate the CRC over a small memory area (e.g. from 0x1000 to 0x100F). Verify that what you have in memory matches what you have in the S-Record.
          It could be that your debugger is writing values differently e.g. to special configuration data, e.g. to prevent you permanently locking your device.
          I hope this helps,
          Erich

          Like

      • Hi Eric,
        for the small area falsh it worksss!!! Why if i extend my area there is a problem? It’s necesessary for me to calculate the crc for a lenght of 8k.

        Like

  8. Pingback: MCUXpresso IDE: S-Record, Intel Hex and Binary Files | MCU on Eclipse

  9. Pingback: Using Eclipse to Program Binary Files to an Embedded Target | MCU on Eclipse

  10. Thanks for the informative writeup.
    I have created a script to…
    1. Fill 0xFF at unused spaces in Bootloader (format S31)
    2. Fill 0xFF at unused spaces in Application (format S31)
    3. Merge Bootloader and Application into 1 hex file (s19) (format S31)

    Here is the script…
    #PART 1
    D:\Debug\Bootloader1KSeries.srec
    -fill 0xFF 0x00 0x7800
    -address-length=4
    -line-length=46
    -o D:\Hex\BootLong.hex

    #PART 2
    D:\FLASH\App.hex
    -fill 0xFF 0x7800 0x40000
    -address-length=4
    -line-length=46
    -o D:\Hex\AppLong.hex

    #PART 3
    D:\Hex\BootLong.hex
    D:\Hex\LT500Long.hex
    -o D:\Hex\Final.hex
    -address-length=4
    -line-length=46

    If any one of these parts is executed (with other two parts commented) then the script runs nicely. I run it using “srec_cat @script.txt”

    However, if I try to run all the above parts (1, 2 and 3) then I get following message…
    Usage: srec_cat […] filename…
    srec_cat Help
    srec_cat VERSion
    srec_cat LICense

    And no output file is generated in the Hex folder (destination folder)

    Please tell me, how to resolve this issue.

    Like

      • Thank you for the reply, Erich.

        I am new to the cmd line scripting. I have been through the links you have shared. (sorry, but I really could not find anything there that would solve my problem).

        Please make a note, all the above steps that I mentioned in my first post work ok when run alone (i.e. by commenting the other two). However clubbing them together has a problem.

        Do you mean to say that I have to create three different script.txt file, for three steps and call them in post build steps in the Eclipse settings?
        Or is there any command available that closes the generated/opened output file?

        Like

        • Yes, I meant that there shall be three different calls/scripts to the srecord utility. This is how I would do it. You can combine the three steps into a single command/batch file.

          Like

        • Hello Erich,
          I created three commands separately in a batch file. This is how my batch file look like…

          D:\Tools\srecord-1.63-win32\srec_cat D:\Hex\Boot.srec -fill 0xFF 0x00 0x7800 -address-length=4 -line-length=46 -o D:\Hex\BootLong.hex
          D:\Tools\srecord-1.63-win32\srec_cat D:\Hex\App.hex -fill 0xFF 0x7800 0x40000 -address-length=4 -line-length=46 -o D:\Hex\AppLong.hex
          D:\Tools\srecord-1.63-win32\srec_cat D:\Hex\BootLong.hex D:\Hex\AppLong.hex -o D:\Hex\Final.hex -address-length=4 -line-length=46

          I ran it by double clicking on .bat file and it was generating the expected output. Thanks for suggesting this method. 🙂

          Now, to automate the process I added it into Postbuild commands of ECLIPSE based Codewarrior like this…
          In Post-Build Steps -> Command->
          D:\Tools\srecord-1.63-win32\script_Trial2.bat

          When I try to compile, the Codewarrior generates .hex, .elf and displays the code and data size and then nothing happens. no message is displayed in console window of Codewarrior and expected files are also not generated.

          Please tell me where am I failing.

          Like

        • The post build step is only executed if there is previously a link phase (calling the linker). Otherwise, I suggest that you try to call the batch file in the post build step from a new/clean project, as some custom file options might prevent executing a post build step. If it works for you on a clean project, than the batch file is working fine and it must be a problem of your actual project.

          Like

  11. Very helpful as always! FWIW, there’s a small formatting issue near the first mention of “CRC16_Big_Endian” — it appears that some pointy-bracket enclosed text got swallowed as HTML directives. But easy enough to figure out by context and subsequent examples…

    Like

  12. I was having a devil of a time figuring out what CRC32 algorithm the KL27 hardware uses for the KL Bootloader 2.0 protocol. Although the site you cite (https://www.lammertbies.nl/comm/info/crc-calculation.html) was useful, it only had one CRC32 algorithm.

    I found a more comprehensive online CRC calculator at http://www.sunshine2k.de/coding/javascript/crc/crc_js.html that helped me identify the KL27 CRC32 used by the bootloader as CRC32_MPEG2.

    As an aside, I have referred to this blog entry more times than I can count. Many thanks (again!).

    Like

    • Hi Robert,
      thank you so much for sharing that link for this CRC calculator, very useful! I have added that one to the article too. And thanks for identifying the CRC the Kinetis Bootloader is using, I was wondering about this too. I have not seen that documented anywhere 😦

      Like

    • Thanks for asking that question in that forum. But I have no advise here as well, except maybe this:
      a) export the data of the range using SRecord to a file
      b) call a program to calcualate the CRC with the desired method and put it into another file
      c) combine/merge the data using SRecord
      Above could be done in a script/batch file, but requires to implement the CRC somehow.

      Like

      • To elaborate on this, the SRecord tool uses a *reversed* polynomial of 0xedb88320. Furthermore, when it calculates the CRC, it uses the following function:
        table[(crc ^ octet) & 0xFF] ^ (crc >> 8);
        Which is apparently a little backwards from the “standard” way – as explained in the comment above the polynomial. Thus, even if you change your polynomial to match, the checksum still won’t be the same.

        To fix this, you can either use Robert’s posted solution to get back to the standard computation and polynomial, or edit the SRecord code and re-compile it on your system

        Like

  13. Pingback: Adding a Delay to the ARM DAPLink Bootloader | MCU on Eclipse

  14. Hey Erich/ all, it looks like the the sourceforge site for srecord is down while they migrate, and has been for at least the past two days. Does anyone have a comparable tool?

    Like

    • Hi Andrew,
      in my view, there is really other alternative (at least not with all the functionalites).
      I have emailed the SRecord to your gmail email address, so hopefully this gets you started.
      Erich

      Like

  15. Pingback: Tutorial: CRC32 Checksum with the KBOOT Bootloader | MCU on Eclipse

  16. ‘srec_cat’ can’t not find this file[..\..\Debug\s32k118_GCC_base.srec]

    srec_cat: ..\..\Debug\s32k118_GCC_base.srec: open: No such file or directory

    Like

  17. Hi Erich,
    Do you know how to correct the checksum for every line in intel hex file because I am changing the four digits address field.
    So from range 8000 – FFFF to 0000-7FFF
    Thanks

    Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.