Integrity checks with the new SEGGER Linker

With the latest Embedded Studio update to version 5 the SEGGER Linker also received new features. One of these features is the new integrity check functionality which I would like to focus on in this article. Supported are numerous CRC and message digest algorithms (e.g. MD5 and SHA).

What is new?

The new SEGGER Linker V3.0 supports Firmware integrity checks now without the need for external tools. This massively simplifies setups where such integrity checks are needed as everything can be done natively within the Embedded Studio toolchain.

Currently 39 different algorithms are supported, e.g. CRC, MD5, SHA and many more, making this feature a great fit for any setup. You can find more information in the SEGGER Linker User Guide.

Example

The following example will show you how simple it is to use the new feature. We will show how to calculate the CRC over the complete target application. For verification we will compare the result with the hardware implementation of the CRC peripheral in the STM32 family from STMicroelectronics.

As the target hardware we will be using a Cortex-M Trace Reference Board based on a ST STM32F407VE target device and the new SEGGER Embedded Studio V5.10. Furthermore as the debug probe I will be using the latest J-Link Plus model with a 19-Pin Cortex-M Adapter.

You can find the example project here for reference.

Additionally you can find a more technical description of the feature in our Wiki.

Linker script

First we need to define regions where the application and where the calculated CRC value should be placed:

define region CRC = [end(FLASH)-4 size 4];
define region APPLICATION = FLASH - CRC;

After placing the application sections in the corresponding APPLICATION region we can execute the integrity check. In addition the result will be placed in the region CRC:

place in CRC {
integrity check of APPLICATION with algorithm="CRC-32/STM32" fill=0xFF
};

fill APPLICATION with 0xFF;

The last line is optional but makes sure that all empty areas of Flash memory are filled with the same value used to calculate the CRC.

In this example the algorithm used was CRC-32/STM32 as this is the same algorithm used by the target processor from this example which we will verify in the section below. Further if you are looking to use the SEGGER Linker calculation only then you are already done.

Target application

The target application from the example will calculate the CRC over the application region using the STM32 CRC peripheral and then compare it with the CRC calculated by the linker.

First we need to enable the CRC peripheral. When using the ST CMSIS files (e.g. from the Embedded Studio package manager) you can do this with the following lines:

RCC->AHB1ENR |= RCC_AHB1ENR_CRCEN;  // Enable CRC clock
CRC->CR |= CRC_CR_RESET;            // Reset peripheral

To calculate the CRC the data is written to the CRC data register word wise:

do {
  CRC->DR = __REV(*pData);  // Calculate CRC
  pData++;
} while (NumItems--);       
CRCResultHW = CRC->DR;      // Save CRC result

Keep in mind that the STM32 CRC peripheral expects the values in reverse order. For this we simply use the Embedded Studio intrinsics function __REV().

If you run the application you will see that the SEGGER Linker CRC and the STM32 CRC are a match.