13

痞子衡嵌入式:一次利用IAR自带CRC完整性校验功能的实践(为KBOOT加BCA)

 3 years ago
source link: http://www.cnblogs.com/henjay724/p/14050783.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家分享的是 利用IAR自带CRC完整性校验功能的一次实践(为KBOOT加BCA)

痞子衡之前写过两篇关于IAR中自带CRC校验功能的文章 《在IAR开发环境下为工程开启CRC完整性校验功能的方法》《探析开启CRC完整性校验的IAR工程生成.out和.bin文件先后顺序》 ,算是把这个功能细节介绍得比较清楚了,但是俗话说得好,理论懂得再多,不能用于实践那等于没学。今天痞子衡就利用这个功能来解决一个实际需求:

一、KBOOT中BCA填入CRC校验需求

说起这个需求,记得那是2014年的第一场雪,那时候痞子衡正在飞思卡尔软件组参与Kinetis Bootloader项目(简称KBOOT)的研发,痞子衡为这个项目写过一些文章,详见 《飞思卡尔Kinetis系列MCU开发那些事》 里的启动篇系列,Kinetis是飞思卡尔当时主推的Cortex-M微控制器,KBOOT就是为Kinetis设计的全功能Bootloader,这可能是嵌入式世界里第一个精心设计的通用架构Bootloader。这个Bootloader包含一个用户配置功能(BCA),简单说就是在用户Application的偏移0x3c0 - 0x3ff这16个word存放一些Bootloader配置,当Bootloader运行时会先尝试从Application区域读出这16个word,获取用户配置(超时时间、外设类型、id、速度选项等),然后根据用户配置再去启动或升级用户Application。

CRC完整性校验功能占据了BCA里的12个byte,是一个很重要的Bootloader特性,其完整功能详见 《KBOOT特性(完整性检测)》 ,今天痞子衡要说的需求就是直接在Application工程编译时生成包含正确CRC相关参数的BCA,而不是像以前那样在最终binary文件里二次编辑添加。

我们以MK64FN1M这颗芯片为例,下载它的软件包,软件包里有KBOOT及其示例Application,找到 \SDK_2.8.2_FRDM-K64F\boards\frdmk64f\bootloader_examples\demo_apps\led_demo_freedom_a000\iar 下的Application工程,工程源文件 startup_MK64F12.s 里定义了__bootloaderConfigurationArea,但是CRC区域是全0xFF(即没有使能),编译生成的bin文件里CRC区域也是全0xFF,我们要做的就是填入正确的CRC。

uYBfEn7.png!mobile

二、开始动手实践

2.1 确定匹配的CRC算法参数设置

在KBOOT用户手册里可以找到其CRC具体算法,它使用的是比较主流的CRC32-MPEG2分支,具体参数如下表所示:

IvUJjq6.png!mobile

为了方便核对结果,痞子衡找了一个在线CRC计算的网站,利用这个网站,设置与KBOOT一致的CRC参数(下图红色框内),然后我们选取led_demo_freedom_a000.bin的前16个字节(下图蓝色框内)作为测试数据输入,点击Calculate CRC按钮生成结果0x8D96BDF0(下图紫色框内)。

在线网站: http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

F3IbueV.png!mobile

我们现在回到led_demo_freedom_a000工程,在Linker/Checksum下,使能CRC功能,为了与上述测试一致,CRC计算范围设为 0xa000 - 0xa00f(因为程序起始链接地址是0xa000,所以也就是最终.bin里的前16个字节)。查阅IAR development手册,做了如下CRC算法参数设置,编译工程得到结果也是0x8D96BDF0,因此CRC设置是匹配的。

qqQriy7.png!mobile

2.2 填充BCA的首次尝试

确认了CRC设置,现在就是修改源代码了,在BCA的CRC区域里将初始的0xFF值全部更换为真实的CRC设置值__checksum、__checksum_begin、__checksum_end,代码简单修改如下。重编工程后查看.bin文件,发现起止范围两个参数是对的,但是CRC校验值并不对,填成了0x0000a7fc,查看map文件得知这是__checksum的链接地址,并不是__checksum的值。想想也是,CRC校验值是链接生成bin后才计算的,但源文件是在链接前编译的,不可能在编译时得到链接后的结果。

mYrqay.png!mobile

2.3 填充BCA的最终方案

首次尝试失败,事情远没有想象得那么简单,我们需要在工程链接文件上动心思,要直接把__checksum链接到BCA里的具体偏移位置。因此startup_MK64F12.s 里__bootloaderConfigurationArea从crcExpectedValue及其之后全部去掉,并且__FlashConfig也实际不需要(仅对于链接在0地址才有效,这是Kinetis特性)。

然后我们需要重新在main.c里定义一个bca常量数组,把除crcExpectedValue之外缺失的BCA数据全部放进去。

const uint32_t bca[16] @ ".bca_left" = {0x1388ffff, 0xffffffff, 0xffffffff, 0xffffffff,
                                        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
                                        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
                                        0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};

最后我们需要修改链接文件MK64FN1M0xxx12_application_0xA000.icf如下:

//place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec, readonly section .noinit };
//place in FLASH_region { block ApplicationFlash };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place at address mem:0xa3cc { ro section .checksum };
place at address mem:0xa3d0 { ro section .bca_left };
place in FLASH_region { readonly section .noinit, block ApplicationFlash };

经过这么一番操作,让我们重新编译工程再看bin里结果,哈哈,这次BCA果然是正确的CRC校验值了(这次值是0xf62ce2b6,发生了变化,因为源代码的改动,bin前16个字节内容也相应变化了),大功告成。底下的事情就简单了,在CRC设置界面里调整想要的CRC计算范围即可。

UbuyUfY.png!mobile

至此,利用IAR自带CRC完整性校验功能的一次实践(为KBOOT加BCA)痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

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

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

JbQvMzi.jpg!mobile


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK