IAR之Checksum
生活随笔
收集整理的這篇文章主要介紹了
IAR之Checksum
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
項目需要在IAR生成固件時自動生成校驗碼。網上的一些筆記不詳細,所以總結一些經驗分享。
參考文章
- Cyclic_redundancy_check
- IELFTOOL Checksum
IAR設置
鏈接腳本
/*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x08010000; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x08010000; define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF; define symbol __ICFEDIT_region_CCMRAM_start__ = 0x10000000; define symbol __ICFEDIT_region_CCMRAM_end__ = 0x1000FFFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x400; /**** End of ICF editor section. ###ICF###*/define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define region CCMRAM_region = mem:[from __ICFEDIT_region_CCMRAM_start__ to __ICFEDIT_region_CCMRAM_end__];define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };initialize by copy { readwrite }; do not initialize { section .noinit };place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place at end of ROM_region { readonly section .checksum };place in ROM_region { readonly }; place in RAM_region { readwrite,block CSTACK, block HEAP };關鍵是加入place at end of ROM_region { readonly section .checksum };
編譯驗證
獲取編譯出來Bin文件的存儲的Checksum。
$ xxd -s 0x0006FFFC -o 0x08010000 FirmwareForCrc16Test.bin 0807fffc: ffff a4c4 ...其中0x0006FFFC = ( 0x0807FFFB - 0x08010000 ) + 1。因為STM32是小端對齊,所以Checksum是0xC4A4.
C代碼驗證,讀者可通過鏈接crc16_helper.zip下載代碼測試。
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <stdbool.h> #include <errno.h> #include <string.h> #include <unistd.h>#include "Checksum.c"#define SIZE_MAX_SRC_FILE ( 10 * 1024 * 1024 ) typedef union {uint8_t ucContent[ SIZE_MAX_SRC_FILE ];uint32_t ulContent[ SIZE_MAX_SRC_FILE / 4 ]; } Firmware_t;static size_t ulGetFileContent( char *pucFile, uint8_t *pucContent ) {size_t ulNum;FILE *fIn;fIn = fopen( pucFile, "rb" );if ( fIn == NULL ){printf( "fopen %s failed( %s )!\n", pucFile, strerror( errno ) );return -1;}ulNum = fread( pucContent,sizeof( uint8_t ),SIZE_MAX_SRC_FILE,fIn);fclose( fIn );return ulNum; }static Firmware_t xFirmeware = { .ucContent = { 0 } }; const int zero=0; int main( int argc, char *argv[] ) {uint32_t ulStartAddress = 0x08010000;uint32_t ulEndAddress = 0x0807FFFB;uint32_t ulIndex = 0;size_t ulNum;unsigned short sum=0;// printf( "argv[ 1 ] : %s\n", argv[ 1 ] );ulNum = ulGetFileContent( argv[ 1 ], &( xFirmeware.ucContent[ 0 ] ) );if ( ulNum != ( ( ulEndAddress - ulStartAddress ) + 1 + 4 ) ){printf( "ulNum = %d\n", ulNum );printf( "( ( ulEndAddress - ulStartAddress ) + 1 + 4 ) = %d\n",( ( ulEndAddress - ulStartAddress ) + 1 + 4 ));return -1;}sum = 0;sum = fast_crc16( sum,(unsigned char *)&xFirmeware.ucContent[ ulIndex ],ulNum - 4);printf( "fast sum = %04x\n", sum );sum = 0;sum = slow_crc16( sum,(unsigned char *)&xFirmeware.ucContent[ ulIndex ],ulNum - 4);sum = slow_crc16(sum,(unsigned char *)&zero, 2);printf( "slow sum = %04x\n", sum );sum = 0;sum = sum | xFirmeware.ucContent[ ( ulEndAddress - ulStartAddress ) + 4 ];sum = sum << 8;sum = sum | xFirmeware.ucContent[ ( ulEndAddress - ulStartAddress ) + 3 ];printf( "want sum = %04x\n", sum );return 0; } $ gcc -static crc16_helper.c -o crc16_helper.exe $ ./crc16_helper.exe FirmwareForCrc16Test.bin fast sum = c4a4 slow sum = c4a4 want sum = c4a4總結
以上是生活随笔為你收集整理的IAR之Checksum的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++编程-scanf的用法
- 下一篇: LMD程序