4

我正在做一个固件项目,我必须对闪存完整性进行 crc16 检查。

crc 使用 IAR Xlink 链接器计算并保存在闪存的末尾。再次在运行时从代码计算 crc,并与闪存中存储的值进行比较以检查完整性。但是,我们只能在闪存的代码段上计算 crc。每当我们对代码进行一些更改时,它的大小可能会发生变化。我可以自动化我现在手动执行的这个过程吗?

从 .xcl 链接器文件:

// ---------------------------------------------------------
// CRC16 Essentials: -H for fill,-J for checksum calculation
// ---------------------------------------------------------

-HFF         

-J2,crc16,,,CHECKSUM2,2=(CODE)5C00-FF7F;(CODE)10000-0x20A13

在这里,我现在需要更改第二个代码段的结束值,即 0x20A13。我从 .map 文件中得到这个值,即我的代码在闪存内的内存范围。这是我做的第一个改变。

在这里,我需要对代码进行第二次更改:

  sum = fast_crc16(sum, 0x5C00, 0xFF7F-0x5C00+1);

  sum = fast_crc16(sum, 0x10000,0x20A13-0x10000+1); 

  //Check the crc16 values 
   if(sum != __checksum)
   {
    // Action to be taken if checksum doesn't match
   }

请帮助自动化此过程!

4

2 回答 2

2

您可以尝试使用“C/C++ 编译器参考指南”中解释的 IAR 中的__segment_beginand__segment_size__segment_end内部函数,您可以从 IAR EW430 的“帮助”菜单中获得该指南。该手册说他们使用链接器文件中定义的段,并且互联网上的很多人似乎都在使用它,但我尝试并得到编译器错误(IAR EW430 5.40.7)。如果它以某种方式损坏,您可能需要将其报告给 IAR 并进行修复(假设您有支持合同)。

你可以像这样使用它们:

sum = fast_crc16(sum, __segment_begin("CODE"), __segment_size("CODE"));

我不知道拆分段会发生什么。但是为什么要从校验和计算中排除重置向量呢?您可以从 CODE 的开头到结尾并包含重置向量。

我想你可以像这样构造你的代码:

sum = fast_crc16(sum, __segment_begin("CODE"), (char *)__segment_begin("INTVEC") - (char *)__segment_begin("CODE") + 1);

sum = fast_crc16(sum, 0x10000, (char *)__segment_end("CODE") - 0x10000);

此外,您可能注意到也可能没有注意到该__checksum变量被放入内存中任何合适的位置。我发现它潜伏在我的DATA16_ID段之后,它正好位于我校验和代码范围的中间,而且我不知道有一种方法可以自动跳过内存部分以进行校验和计算。我所做的是__checksum通过为前两个字节定义一个段并将其放入闪存中的前两个字节。

编辑:错过了第一个变化。如果您手动调整 IAR 链接器校验和例程的范围,那么为了能够使用编译器中的段内在函数,您需要在链接器中定义一个使用代码结尾的自定义段。

我不知道是否有任何方法可以自动化。你可能需要编译你的代码两次(呃)一次,段无限以获得代码的结尾,然后使用脚本来提取代码的结尾,然后更新链接描述文件。您可能会在预构建命令行事件上运行初始构建,然后使用不受限制的链接器文件构建 IAR 项目。但这似乎很丑陋。

于 2012-08-23T11:22:14.367 回答
2

也许您也可以更改您的解决方案,在为应用程序保留的完整闪存上构建 crc,而不仅仅是为使用过的部分。

然后,您无需更改链接器文件或 c 代码,甚至引导加载程序也可以在不了解应用程序实际大小的情况下计算 crc。

于 2012-08-24T11:04:13.667 回答