IAR之Checksum

前言

项目需要在IAR生成固件时自动生成校验码。网上的一些笔记不详细,所以总结一些经验分享。

参考文章

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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值