This article shows how to create an absolutely placed library (functions and data), that can be integrity-checked using a checksum. The included example uses IAR Embedded Workbench for MSP430.
This article shows how to create an absolutely placed library (functions and data), that can be integrity-checked using a checksum. The idea is that the library can be separately verified, and possibly certified, once, and later on used by other applications. The library is compiled and linked in a separate IAR Embedded Workbench project, and later on used by an application project, using function pointers.
The image below shows how the library is placed in ROM and RAM, and how it is separated from the application. This example is created for a MSP430F449 device, but can be ported to other devices.
1. Create a project for the library (functions and data). Note that Options -> Output should be set to “Executable” (i.e. this is not a Library project).
2. Configure the target device (MSP430F449).
3. Configure the linker to use an address range separate from the application. In this example project, the library uses the range 0x8870 to 0xFFDF. See the linker configuration file “lnk430f449_lib.xcl”.
4. Select General Options -> Library Configuration -> Library: None. Note that if you wish to use the runtime library in the library project, skip this step.
5. Create a lib_init() function, for the C initialization. This function will copy the initial values for static and global initialized variables from ROM (DATA16_ID) to RAM (DATA16_I). In the example code, see the file “lib_func.c”.
6. Set the default program entry to "lib_init" in Linker -> Config options.
7. To suppress the automatic initialization made by the C-startup code, add a symbol definition “?cstart_init_copy=0” to Options -> Linker -> #define.
8. Make sure to add the “__root” keyword to the library functions, so that they are not removed from the linked output file (since the functions are not used by the library itself). In this example project, see the file “lib_func.c”.
9. Enable the checksum option in the linker options (CRC16).
10. Place the checksum at the start of the ROM region (i.e. address 0x8870), using "-Z(CONST)CHECKSUM=8870" in the linker configuration file.
11. Create a “library entry” structure (a collection of library function pointers) in the library. Place this library entry structure at an absolute address (in this case 0x8872). This enables the application to call the library functions, using this “entry structure”. In the library code:
1. Create a project for the application.
2. Configure the target device (MSP430F449).
3. Configure the linker to use an address range separate from the address range of the library. In this example project, the application uses the range 0x1100 to 0x886F. See the linker configuration file “lnk430f449_app.xcl”.
4. In the application’s main function, add function pointers, one for each library function. In this example project, see the “main.c” file.
5. In the application's main function, check the value of the linker-calculated checksum that is stored in the library. In this example project, see the “main.c” file.
6. In the application’s main function, use the “library entry structure” to gain access to the functions in the library (function pointers). In the application code:
7. In the application's main function, make sure to call "lib_init" to initialize the data in the library. In the application code:
8. If the flash (where the library is located) is supported by a EW430 flash loader, you can download the library to the target device (needed at least once) by adding the output file to Options -> Debugger -> Images -> Download extra image -> Path: $PROJ_DIR$\..\library\Debug\Exe\library.d43
Note that for some devices, you may need to download the library output file separately.
Using the settings above, and the example project called “app”, it is now possible to debug the application and library using the C-SPY Debugger. The linker map file for the library shows the location (and value) of the __checksum variable (0x8870), and also the library functions and data. Verify that the library functions are separated from the application (using the address range 0x8870 to 0xFFDF).
After verification and certification of the library has been performed, the checksum ensures that the exact same library code is used (by possibly different applications).
Disclaimer: This article uses an example to illustrate the topic. If you are using another device, you might need to make adaptions to the example implementation.
This article is written by Niklas Källman, Technical Support Engineer at IAR Systems.