IAR中使用IELFTOOL进行软件代码checksum的生成和添加


前言

我写这篇文章的初衷是为了做部门内部的分享,如果能帮到更多的人,那就更好了,所以欢迎也期待你们的转载和收藏!

IAR是常用于单片机代码开发,里面有很多实用的工具,比如ielftool.exe,这个工具可以根据你的配置来生成软件代码的checksum。如下图这个工具:
ELF工具位置

checksum的直接的应用之一就是,做UL或者CE认证的时候,会要求你提供某些代码段的checksum来进行软件管控。

我在工作中就有这个应用需求,但是苦于网上的资料比较杂,很多都是用的Keil,而且很多的方法我实际使用了以后觉得并不是特别方便,所以我在这里提供一种我个人认为比较方便的方法,可以生成任意段代码checksum,并可以把这些生成的checksum放在任意位置。

另外,因为IAR每次编译只能单独生成.bin或者.hex文件而不能同时生成,所以我也会利用ielftool,提供一种同时生成bin和hex的方法。


一、配置你的开发环境

1.IAR准备

我这里使用的是IAR 9.10.1版本,IAR和KEIL都有32k的免费版license,能够满足一般产品的应用。

2.普通工程准备

弄一个文件含有main.c能编译就行了,我这里使用的是GD32E230C8T6这个芯片,也是目前我个人用的比较多的M0芯片,基础的软件就是跑个时钟中断而已,简单易用,看的更清楚。

3.ICF文件准备

这里先添加个基础的icf文件,后续会对这个进行修改。

4.BAT文件准备

先创建个HexCRC.bat.txt的空白文件,可以利用记录本来进行编辑,后续给IAR调用的时候要将.txt的后缀删掉。这个文件就是专门用来放ielftool的执行代码的。

5.别急,兄嘚

东西是不是要准备很多?别急,我在最后将提供整个项目的压缩包供你们下载,不要钱。里面包含了以上提到的文件。


二、任务目标

1.ROMs生成任务

我们有三段ROMs,第一个ROM地址从0x08000000到0x08005FFF,用来存放应用层的代码,我们把这段ROM取名为ROM_region。
第二个ROM地址从0x08008000到0x0800F6FF,用来存放UL认证代码,我们把这段ROM取名为ROMUL_region;
第三段ROM地址从0x08000000到0x0800F7FF,代表了总的代码,我们把这段ROM取名为ROMall_region;
你们是不是注意到了,第三段比一二两段的总和还多出了0x00000100的大小,而且他们之间不连续。我这么分区的原因是让你们了解,我这方法可以生成任意段的Checksum,并把任意的Checksum结果放在任意地址,不管你的地址是不是连续的。

2.Checksums生成的任务

首先,我们要为第一、二段生成他们各自的Checksum,并将Checksum放在每段ROM的最后。
然后,我们要在包含第一、二段Checksum的情况下,对整个代码段(即ROMall_region),再次进行一次整体的Checksum计算,并把结果放在ROMall_region的最后。
这么描述可能有点抽象了,我画个图给你们展示下:
ROM分配
我来简单解释下,三个红色涂满的小方框代表的是存放各个ROM生成的CRC,两个黄色框代表我的两个ROM分区(ROM_region和ROMUL_region),外围最大的红色框代表整体的ROM分区(ROMall_region)。
尤其需要注意的是,其中ROMall_region存放的Checksum,是要在ROM_region和ROMUL_region已经存放了Checksum以后,再进行整体计算的Checksum。
所以我们要生成一共3个Checksum。


三、开始干活

1.准备好你的工程

代码如下(没错,就是一个delay延时1ms程序,没了):

int main(void)
{
    /* configure systick */
    systick_config();
    while(1){
            delay_1ms(500);
        }
}

2.修改icf文件

这个icf文件的作用就是分配ROM和RAM的空间,还可以让一些东西放在固定的位置。
那么要对这个文件做几个修改,在原有的ROM下进行增加,这里列出了所有要增加的项目:

(1)增加申明地址

添加ROMUL和ROMall的地址

define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__  = 0x08005FFF;
define symbol __ICFEDIT_region_ROMUL_start__ = 0x08008000;
define symbol __ICFEDIT_region_ROMUL_end__ = 0x0800F6FF;
define symbol __ICFEDIT_region_ROMall_end__ = 0x0800F7FF;

(2)增加定义region

利用刚刚定义的地址,定义ROMUL和ROMall的ROM范围

define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
define region ROMUL_region   = mem:[from __ICFEDIT_region_ROMUL_start__   to __ICFEDIT_region_ROMUL_end__];
define region ROMall_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROMall_end__];

(3)对外申明地址

这个是我对他的命名,因为刚刚定义的地址,需要加上这个对外申明才能让IAR引用,如果不加,会报错。这个export关键字和C中的extern有点像,这么说应该比较好理解。

export symbol __ICFEDIT_region_ROM_start__;
export symbol __ICFEDIT_region_ROM_end__;
export symbol __ICFEDIT_region_ROMUL_start__;
export symbol __ICFEDIT_region_ROMUL_end__;
export symbol __ICFEDIT_region_ROMall_end__;

(4)定义checksum值的存放位置

在icf文件中,place at end of A{B}代表将B中的东西放在A内存的尾部。{}中的ro代表readonly只读,不能改。section .checksumUL代表叫.checksumUL的一个内存单元。这个整体意思就是将.checksumUL放在ROMUL_region 内存区域的最后。这两个数值就是我们的checksum最终的计算值。这三个checksum值在第4步会有配置。

place at end of ROM_region { ro section .checksum };
place at end of ROMUL_region { ro section .checksumUL };
place at end of ROMall_region { ro section .checksumall };

(5)将.icf放在指定位置方便IAR调用

存放在如下图的位置,为IAR的调用做准备。
icf存放位置

3.添加HexCRC.bat文件

这个文件用来存放ielftool的执行命令,也有很多会告诉你在post-build command line中输入命令,但是那个真的太长了,这点IAR做的很不方便,只适合短的命令。如下图,就是一根线的长度。所以我使用.bat文件来存放文件,在post-build command line中输入调用这个.bat文件,这样就方便多了。
postinit

(1)定义.out .bin .hex文件

这里是.bat文件的语法,不用深究,依葫芦画瓢就行。这里定义了三个文件,.out .bin .hex,这个1%就是外部引用的时候用的文件名,引用这个bat文件会跟上IAR生成的名字。
比如$TARGET_DIR$\HexCRC.bat $TARGET_BPATH$,这句话就是说引用HexCRC.bat文件,输入的文件名就是IAR生成的文件名$TARGET_BPATH$,对应的就是里面的1%。
再举个例子,比方说你的工程叫Project.eww,那么你生成的就是Project.out Project.bin Project.hex

set OUT=%1.out
set BIN=%1.bin
set HEX=%1.hex

(2)ielftool语法

我们主要就是用这个工具来生成我们的checksum先拿出基本命令语法,我们逐段解析。

ielftool --fill="0xFF;ROM_Start-ROM_End" --checksum="__checksumall:4,crc32,0xffffffff;ROM_Start-ROM_End" --verbose %OUT1% %OUT2%

这里是三个命令,还是老规矩依葫芦画瓢,详细的解释可以直接去IAR官方help里面查,讲的晦涩难懂,我这里用通俗的话来解释。
ielftool 是代表调用IAR中的ielftool.exe
--fill="0xFF;ROM_Start-ROM_End"是代表没有用到的ROM使用0xFF填满,后面代表ROM的起始和结束地址范围。整句话的意思就是,在ROM_Start到ROM_End范围里,将没有用到的ROM使用0xFF来填满。
--checksum="__checksumall:4,crc32,0xffffffff;ROM_Start-ROM_End"是说给checksum预留4byte的位置,使用固定CRC32算法,计算单元为1字节(这个在IAR中有说明,没有指定的时候就是默认1字节),指定CRC初始值为0xffffffff。整句话的意思就是,现在使用CRC32给我计算指定ROM的checksum,结果要放在一个4byte的叫__checksumall的东西中。
--verbose 是表示记录所执行的操作,在build窗口输出
%OUT1% %OUT2%表示的是将.out1文件中的ROM来做我们之前提到的那一堆操作:fill,checksum,verbose,将这些做完以后,放进out2中。聪明的人就发现了,我们编译完成以后,IAR都是生成.out文件作为可执行文件,而且只有一个,所以这个out1是可以等于out2的。这样可以让.out文件的末尾直接加上checksum。
在这个项目中,根据这个语法,为了同时生成两段ROMs的checksum并放在他们各自的末尾,我们的代码应该是:

ielftool --fill="0xFF;__ICFEDIT_region_ROM_start__-__ICFEDIT_region_ROM_end__" --fill="0xFF;__ICFEDIT_region_ROMUL_start__-__ICFEDIT_region_ROMUL_end__" --checksum="__checksum:4,crc32,0xffffffff;__ICFEDIT_region_ROM_start__-__ICFEDIT_region_ROM_end__" --checksum="__checksumUL:4,crc32,0xffffffff;__ICFEDIT_region_ROMUL_start__-__ICFEDIT_region_ROMUL_end__" --verbose %OUT% %OUT%

这里面连续跟了两个–fill和–checksum,是为了分别对.out文件中的ROM进行操作,生成__checksum和__checksumUL。
ielftool支持同时多段的checksum操作,这点非常灵活和方便,所以可以鼓掌点赞了。
最后,我们来个生成整个代码段__checksumall的代码:

ielftool --fill="0xFF;__ICFEDIT_region_ROM_start__-__ICFEDIT_region_ROMall_end__" --checksum="__checksumall:4,crc32,0xffffffff;__ICFEDIT_region_ROM_start__-__ICFEDIT_region_ROMall_end__" --verbose %OUT% %OUT%

注意,这里的地址都是我们在icf文件中设置的名称。ICFEDIT_region_ROM_start-__ICFEDIT_region_ROMall_end__表示的就是整个代码段。
兄弟们,这段是核心,所以贼罗嗦,我搜了好多篇文章和自己的实践才搞定的。

(3)最后就是同时生成bin和hex文件

在IAR中,你可以使用IAR配置中的config进行配置来生成bin和hex文件,如下图:
hexgenerate
但是这里每次只能点一个,就是说你每次只能生成一个hex或者bin,我在日常的应用中就是这样,生产那里同时要bin和hex,我每次都要先生成bin再生成hex,很不方便。
这里其实是IAR用了ielftool.exe工具进行的生成。这里生成的顺序是,先由IAR编译生成可执行文件.out,再由ielftool.exe将.out文件生成.bin文件或者是.hex文件。那么既然如此,我们就可以利用这个特性来用.bat帮我们同时生成.bin和.hex。
第一步,要将上图配置中的generate additional output的勾勾弄掉,避免他重复为我们生成.bin文件。
第二步,编写如下代码:

:: get bin file
ielftool --bin --verbose %OUT% %BIN%
:: get hex file
ielftool --ihex --verbose %OUT% %HEX%

这里就是利用刚生成的.out文件,生成bin和hex的全部过程,编译以后,就可以在文件夹里看到如下图三个文件:
output2
最后,贴上整个的.bat代码段给你们,并将做好的.bat文件放在上图的路径中,方便IAR调用:

:: set BIN and HEX file for getting them in the same time
set OUT=%1.out
set BIN=%1.bin
set HEX=%1.hex

:: this is for two ROMs fill and calculate the ROMs' CRC.
:: fill and calculate CRC for two ROMs 
ielftool --fill="0xFF;__ICFEDIT_region_ROM_start__-__ICFEDIT_region_ROM_end__" --fill="0xFF;__ICFEDIT_region_ROMUL_start__-__ICFEDIT_region_ROMUL_end__" --checksum="__checksum:4,crc32,0xffffffff;__ICFEDIT_region_ROM_start__-__ICFEDIT_region_ROM_end__" --checksum="__checksumUL:4,crc32,0xffffffff;__ICFEDIT_region_ROMUL_start__-__ICFEDIT_region_ROMUL_end__" --verbose %OUT% %OUT%

:: calculate all ROMs CRC
ielftool --fill="0xFF;__ICFEDIT_region_ROM_start__-__ICFEDIT_region_ROMall_end__" --checksum="__checksumall:4,crc32,0xffffffff;__ICFEDIT_region_ROM_start__-__ICFEDIT_region_ROMall_end__" --verbose %OUT% %OUT%

:: get bin file
ielftool --bin --verbose %OUT% %BIN%
:: get hex file
ielftool --ihex --verbose %OUT% %HEX%

4.配置IAR来调用上面两个文件:

(1)调用icf文件

没啥可说的,看图~~

文件要放在指定的位置~~
icf文件位置
配置中填写$PROJ_DIR$\..\GD32E230x8.icf
geticf

(2)调用bat文件

也没啥可说的,看图~~

文件也要放在指定的位置~~
bat文件
配置中填写$TARGET_DIR$\HexCRC.bat $TARGET_BPATH$
在这里插入图片描述

(3)添加特殊语句

在extra options中填入如图:
eo配置
这里做个简要的说明,附上整个代码段:

--keep __checksum
--keep __checksumUL
--keep __checksumall
--place_holder __checksum,4,.checksum,4
--place_holder __checksumUL,4,.checksumUL,4
--place_holder __checksumall,4,.checksumall,4

其中–keep 命令用于强制保留定义的符号__checksum,指示链接器不要进行优化而将其丢弃。
其中–place_holder 命令在Flash中预留位置,用于存放生成的checksum。
他的详细语法,如果是CRC32,就按照我的这个配置就好了:
–place_holder symbol[,size[,section[,alignment]]]
symbol:要创建的符号名称;
size:要保留的字节数;
section:使用的section名;
alignment:section对齐字节;


总结

自此,你编译工程,就可以啦!
我们通过STM32 ST-LINK Utility来看看生成的结果:
开头:
在这里插入图片描述
第一个checksum:
在这里插入图片描述
第二个checksum:
在这里插入图片描述
总体的checksum:
在这里插入图片描述
可以看到,没用到的ROM都是用F来填充的,说明了fill命令的作用!
最后附上整个工程给你们~~

可以直接在https://gitcode.net/weixin_42744495/iar-ielftool-checksum 下载相关工程包~~

That’s all~~
拜咦~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值