痞子衡嵌入式:在IAR开发环境下为工程开启CRC完整性校验功能的方法


  你们好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给你们分享的是在IAR开发环境下为工程开启CRC完整性校验功能的方法算法

  CRC校验在嵌入式领域里的应用很是广,好比在通讯领域,CRC检验值能够做为数据包的一部分,用于检查一包数据传输过程当中是否发生了比特错误,若是CRC校验失败,那么接收方能够通知发送方要求该包数据从新传输,这样能大大增长数据传输的可靠性。同时CRC在应用程序完整性验证方面也有普遍应用,相比和检验,CRC校验纠错能力更强;相比签名校验,CRC校验在速度方面又占优点,所以它是一个各方面比较均衡的完整性验证手段。微信

  IAR是个很是老牌的嵌入式开发集成环境,它的功能很是强大,有不少宝藏功能值得咱们去发掘。痞子衡自毕业以后就一直在使用IAR,算是一路看着它从古典画风的v6.50.x升级到如今潮流的v8.50.x,对于经典的CRC校验功能的支持,IAR固然不会放过,今天痞子衡就来介绍IAR下如何使用其自带的CRC校验功能。app

1、ielftool命令行工具

  IAR安装目录下有很是多的命令行小工具,这些小工具其实就是IAR的核心,集成开发环境界面只是提供人机交互,其背后的不少功能都是经过调用这些命令行小工具来实现的。其中用于实现CRC校验的功能就包含在ielftool.exe工具里:ide

  ielftool.exe工具跟CRC相关的一共两个参数选项,一是--fill用于填充,二是--checksum用于设置算法,具体参数使用细节详见 \IAR Systems\Embedded Workbench 8.50.6\arm\doc\EWARM_DevelopmentGuide.ENU手册里的Checksum calculation for verifying image integrity小节。函数

  此处痞子衡仅举一个简单例子,以下命令表示在源可执行文件sourceFile.out中计算范围__checksum_begin - __checksum_end之间的CRC结果,最终校验值__checksum长度为4字节、固定CRC32算法、计算单元为1字节、指定CRC初始值为0xffffffff,其他设置默认,并将结果放在目标可执行文件destinationFile.out中。工具

ielftool --fill="0xFF;__checksum_begin–__checksum_end"
         --checksum="__checksum:4,crc32:p,0xffffffff;__checksum_begin-__checksum_end"
         sourceFile.out
         destinationFile.out

  从上面的命令你应该能知道,sourceFile.out并非任意可执行文件都行的,其必须包含必要的__checksum_begin、__checksum_end、__checksum的定义。假设咱们代码中并无实际使用CRC,那么咱们须要在生成sourceFile.out文件的IAR工程选项里作以下设置:post

注意:__checksum_begin、__checksum_end符号、__checksum变量、.checksum段四个名字,用户均可以自定义的,这里命名成这样主要是为了和IAR默认定义相统一。ui

  让咱们随便找一个嵌入式IAR工程按上面设置生成源hello_world.out文件,并使用ielftool工具执行一次命令看看,能够看到产生了__checksum值,新生成的hello_world_1.out文件里包含了正确的CRC校验结果。.net

2、为工程添加CRC校验

  IAR界面里有两种使用ielftool来生成CRC校验值的方法,痞子衡一一介绍:命令行

2.1 利用Checksum功能

  第一种是直接在IDE界面里配置,咱们随便打开一个嵌入式工程,好比 \SDK_2.8.2_FRDM-K64F\boards\frdmk64f\demo_apps\hello_world\iar\,在工程选项Linker/Checksum下面,勾选Fill unused code memory和Generate checksum便使能了CRC校验,蓝色框里的两个地址用于设置CRC计算范围,绿框里的参数用于设置CRC算法细节,具体每一个配置什么意义能够查看 \IAR Systems\Embedded Workbench 8.50.6\arm\doc\EWARM_DevelopmentGuide.ENU手册里的Checksum一节,痞子衡在这里不予展开。

  下图示例配置中有两点要说明:1、算法选择了CRC32,其多项式系数其实固定为0x04C11BD7;若是想自定义CRC32多项式系数值,可选CRC polynomial;2、由于地址设置的是 0x0 - 0x400,一共1025个字节(包含0x400),因此checksum unit size此处仅能选8-bit,由于IDE强制要求地址对齐。

  设置好以后从新编译工程,此时会报错“ielftool error: The string '__checksum' was not found in the string table ”,由于在程序代码里,咱们彻底没有任何CRC相关的引用,IAR会忽略界面里使能的CRC功能,因此咱们还须要将__checksum强行加入以下选项里(注意__checksum是IAR里默认定义的CRC检验值符号名)。

  这时候再编译工程就能够在生成的.out和.map文件里看到CRC信息了,__checksum被连接器随机放在了0x2844的位置,__checksum_begin和__checksum_end是IAR默认记录CRC计算范围的符号变量名。

  若是你想本身决定__checksum的连接位置,你能够在工程连接文件里添加放置 section .checksum,这个段便对应着__checksum。好比咱们试着将这个段放在0x1000的位置:

  再一次编译工程,查看map文件,此次__checksum被放在了咱们指定的0x1000的位置。

2.2 利用Post-build功能

  第二种方式是利用IDE里的Post-build功能,在第一节的基础上,在工程选项Linker/Extra Options里把ielftool命令加进去,这样在编译工程的时候,IAR会自动跑这个命令:

$TOOLKIT_DIR$\bin\ielftool --fill="0xFF;__checksum_begin-__checksum_end" --checksum="__checksum:4,crc32:p,0xffffffff;__checksum_begin-__checksum_end" --verbose "$TARGET_PATH$" "$TARGET_PATH$"

  上述命令与第一节中命令基本一致,只是用"$TARGET_PATH$" "$TARGET_PATH$"替代了sourceFile.out destinationFile.out,而且加了--verbose显示执行操做信息:

3、在工程中验证CRC校验

  IAR生成的CRC校验值在应用程序里的使用就比较简单了,见以下代码,其中calc_crc()函数需与咱们以前在IAR配置的CRC算法参数相一致,此外代码中的数据类型也是与具体CRC配置有关的。

  另外还有两个注意点:1、CRC计算范围不该包含__checksum存放位置;2、CRC计算范围若是没有按照算法对齐要求,那么实际计算时要相应补上0(使用IDE配置生成是强制对齐的,可是使用命令行没有强制对齐)。

extern uint32_t const __checksum;
extern int32_t __checksum_begin;
extern int32_t __checksum_end;

void TestChecksum()
{
    uint32_t calc = 0;

    // 根据CRC计算范围重算新CRC校验值
    calc = calc_crc(0xFFFFFFFF,
                    (uint8_t *) &__checksum_begin,
                    ((uint8_t *) &__checksum_end - ((uint8_t *) &__checksum_begin) + 1));

    // 比对新CRC校验值与IAR生成的CRC校验值
    if (calc != __checksum)
    {
        printf("Incorrect checksum!\n");
    }
}

  至此,在IAR开发环境下为工程开启CRC完整性校验功能的方法痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到个人 博客园主页CSDN主页知乎主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就能够在手机上第一时间看了哦。

相关文章
相关标签/搜索