1. Introduction
Cyclic Redundancy Check (CRC) is an error detection method for digital datas based on binary division.
CRC algorithm generates a fixed checksum code length.
2. How is CRC value calculated, how to determine CRC algorithm in embedded applications?
The input parameters of this algorithm are:
• Input data also called “Dividend”
• Generator polynomial or “Divisor” is an algebraic polynomial represented as a bit pattern: the power of each term gives the position on the bit and the coefficient gives the value of the bit.
The order of the generator polynomial must not exceed the CRC length. If we want a CRC with 32 bits for example the highest exponent of the polynomial must be 32.
By default, the standard generator polynomial used in STM32 embedded applications to calculate a CRC-32 is 0x04C11DB7 in hexadecimal, equals to x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 in binary format.
• Initial CRC value
At start up, the algorithm sets CRC to the initial CRC value XOR with the dividend.
Once CRC MSB is equal to one, the algorithm shifts CRC one bit to the left and XORs it with the generator polynomial.
Otherwise, it only shifts CRC one bit to the left.
Figure below describes the algorithm used in STM32 MCUs.
You can refer to AN4187 CRC peripheral overview and its firmware to understand the computation process:
(https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32-standard-peripheral-library-expansion/stsw-stm32an4187.html#overview).
The embedded software gives a computation example of CRC. The algorithm implementation by software is developed in the function CrcSoftwareFunc:
You can also use HAL library to compute CRC by calling functions
• HAL_CRC_Accumulate(): compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer using combination of the previous CRC value and the new one.
• HAL_CRC_Calculate() compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer independently of the previous CRC value.
To determine if your CRC is correct you can calculate it with two different methods and compare the results.
There are different ways to compute CRC:
- With your own algorithm implementation like CrcSoftwareFunc function
- With Hal library
- With an online calculator
3. What are CRC features in STM32 MCUs?
CRC peripheral features vary from one STM32 to another, meanly are listed below:
If the feature “Reversibility option on I/O data” is enabled, each input and/or output byte is reflected before being used in the calculation. Bits of the input or/and output byte are used in reverse order.
See the devices Reference manuals for detailed use of the CRC functionality.
4. About errors detections and collisions
A collision is a CRC similar for two different input datas.
The more bits the CRC value has the less is the probability of a collision.
For CRC-8 there are 2^8 different CRC values --> there is a probability of 1/256 that two different datas have the same CRC.
Increasing the CRC width results in better error protection.
CRC can not correct errors, it only detects errors to send a data again for instance, or only as information.
The generator polynomial must be chosen to maximize the error-detecting capabilities while minimizing overall collision probabilities.
5. Is a CRC a hash?
Both CRCs and hash functions share the property that they take an input value and reduce it to an output value, usually shorter.
Hash is a secure function, used to compare large data sets. It commonly used with cryptographic mechanisms for protecting digital signatures for instance.
CRC is used for smaller data to prevent accidental changes, random error detection when data are sent. It is not adapted to prevent external attack.
6. How to calculate and generate post-build CRC?
IAR EWARM provides a way to generate checksum in Project--> Options:
- With STM32CubeIDE Toolchain
STM32CubeIDE doesn’t have this property as IAR EWARM so we have to use an external tool to generate a post build CRC.
Srec_cat is a tool available in SRecord utility package which is a standalone utility for memory manipulation.
Features:
- load one or multiple BINARY files
- cut out specific address areas
- move them to a new address
- store them to a HEX file
Srec_cat can be used for example to generate a CRC at the end of binary file after build by calling it in your toolchain.
This utility and all information about it are available at Peter Miller’s webpage:
http://srecord.sourceforge.net/.
In the download page in the “SourceForge Downloads” section, select the “1.64 release .zip file” link.
Click on it and download the SRecord 1.64 package.
The downloaded ZIP folder contains these items:
• srec_cat.exe
• srec_cmp.exe
• srec_info.exe
• Reference manual srecord-1.63.pdf
• Readme files
This online workshop gives the process to use srec_cat with STM32CubeIDE:
STM32CubeIDE-Workshop-2019/hands-on/06_F746-DISCO-CRC at master · ethanhuanginst/STM32CubeIDE-Workshop-2019 · GitHub
It is possible to use srec_cat in the same way with Keil MDK.
- Copy srec_cat.exe, srec_cmp.exe, and srec_info.exe files in a new “bin” folder to the root of a Keil project as shown below.
- Enable the option “Create HEX file” in tab “Output” of Options:
- Enable the post-build option
To add a CRC after build, it is necessary to enable option “After Build/Rebuild” in User tab and call Srecord commands:
- Create an empty text file in a text editor
- Copy this command in your file:
.\bin\srec_cat .\Debug\OEM_Dev.hex -intel -crop 0x08000000 0x08002F02 -fill 0xFF 0x08000000 0x08002F10 -CRC16_Little_Endian 0x08002F10 -o .\Debug\OEM_Dev_CRC16.hex -intel
This command isolates section data from address 0x08000000 to 0x08002F02, fill unused datas of this sector with 0xFF, calculate CRC of the isolate section and place it at address 0x08002F10.
These operations are saved in the output hex file: OEM_Dev_CRC16.hex
You can adapt this command to your own usage.
Refer to srecord-1.63.pdf for more information about the Srecord commands.
- Save your file as “post-build.bat”.
- Enable post-build option and call this file:
- The hex file to be used for debug and download must be filled in Debug tab.
The edited hex file generated in post-build step will be then used for programming and debugging.
Create a text file, rename it as “Initialize.ini” for example and save it in the root of the project.
Write this command to the file and save it: LOAD .\debug\ OEM_Dev_CRC16.hex INCREMENTAL
Enter this file in Debug tab:
And in “Utilities” tab: