【问题标题】:Automating linker configuration in IAR Embedded Workbench在 IAR Embedded Workbench 中自动配置链接器
【发布时间】:2012-08-18 18:06:33
【问题描述】:

我正在处理一个固件项目,我必须在其中进行 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
   }

请帮助自动化这个过程!!

【问题讨论】:

    标签: linker embedded msp430 iar crc16


    【解决方案1】:

    您可以尝试在 IAR 中使用 __segment_begin__segment_size__segment_end 内在函数,这些在“C/C++ 编译器参考指南”中进行了说明,您可以从 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 项目。但这看起来很丑陋。

    【讨论】:

    • 感谢 Tinman 关于在函数调用中使用内在函数的建议。我不知道那些。我真正关心的是我只想计算地图文件中的校验和: 1 和 2 。我想排除代码内存中的任何其他段,因为它们有一些需要更改的全局数据,并且我每小时在运行时计算校验和(项目要求)。
    • 这就是为什么我必须在每次下载时手动更改链接器和源中的地址范围。这就是我想要自动化的。即使您可以建议我在 2 之前推送这些 DATA20_C 和 DATA20_ID 对我来说没问题。我只想从 crc 计算中排除! (仅供参考)我图像中的 __checksum 位于末尾。你可以把它放在任何你想要的地方
    【解决方案2】:

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

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

    【讨论】:

    • 会不会影响crc的runtime计算和检查?我需要每小时检查一次。映射文件显示了 DATA20_C 和 DATA20_ID 段中的一些全局数据。
    • 会影响runtime计算时间,但如果你只需要每小时一次,我想应该没问题,但要确保你可以测量duration
    • 对于 922KHz 时钟上的整个 256K 内存,计算需要将近一秒钟的时间。这个应用程序仍然可以。无论如何,感谢您的投入!
    猜你喜欢
    • 2019-02-17
    • 2013-06-21
    • 1970-01-01
    • 2013-10-20
    • 1970-01-01
    • 2011-02-25
    • 2021-01-10
    • 2015-02-01
    • 1970-01-01
    相关资源
    最近更新 更多