Keil5默认只生成 HEX 文件, HEX 文件为文本文件, 有其特定的格式。 我们在做固件自动更新的时候, 希望下载的是一个完整的BIN文件。 当然了,我们也可以按照HEX的格式自己提取数据, 不过这样的话, 你要自己计算CODE SECTION 和 DATA SECTION 的偏移, 所以我个人觉得还是自动生成比较好。
我Keil里设置的偏移地址:
--------------------------------------------------------
| | Start | Size |
--------------------------------------------------------
IROM1 | 0x8008000 | 0x26000 |
--------------------------------------------------------
先介绍一下HEX文件与BIN文件的对比:
这是原始的HEX文件头5行:
:020000040800F2
:1080000030CF002045810008DD1E01086D0E0108FB
:10801000011E0108E1AD00083D61010800000000FB
:10802000000000000000000000000000854601087C
:1080300025D2000800000000AB8100080D550108A2
为了方便阅读,我分割如下:
02 0000 04 0800 F2
10 8000 00 30CF002045810008DD1E01086D0E0108 FB
10 8010 00 011E0108E1AD00083D61010800000000 FB
10 8020 00 00000000000000000000000085460108 7C
10 8030 00 25D2000800000000AB8100080D550108 A2
其中 : 冒号被我去掉了, 第一个Byte为数据长度, 第二第三两个Byte代表地址偏移量, 第四个Byte代表数据类型, 下来是数据区, 最后一个Byte是校验码。
数据类型只有可能是如下6种:
00-数据记录
01-文件结束记录
02-扩展段地址记录
03-开始段地址记录
04-扩展线性地址记录
05-开始线性地址记录
BIN文件头
30 cf 00 20 45 81 00 08 dd 1e 01 08 6d 0e 01 08
01 1e 01 08 e1 ad 00 08 3d 61 01 08 22 55 f9 af
00 00 00 00 00 00 00 00 00 00 00 00 85 46 01 08
25 d2 00 08 00 00 00 00 ab 81 00 08 0d 55 01 08
很显然,第一行的数据类型是04,代表地址记录, 并不是数据,没有放入BIN文件。
在Hex文件中间位置有如下数据类型为04的行:
10 FFC0 00 A0F8C410641D295D80F8C610241D295D A9
10 FFD0 00 601C285C01EB002081B20F48A0F8CC10 17
10 FFE0 00 0E480D49C1F8C0000846B0F8C400B0F5 8D
10 FFF0 00 805F0FDA084690F8C60020280ADC0021 4E
02 0000 04 0801 F1
10 0000 00 054880F8CE1080F8CF1080F8C7100020 87
10 0010 00 FFF770FF70BD000070BA002000F00020 F4
10 0020 00 2DE9F84305460E46A6F10308284890F8 46
10 0030 00 C74090F8C600401EA04216DD2449D1F8 02
该行出现的原因是因为 偏移地址占用2个Byte, 当这两个字节都已经为FFFF时,需要重头开始偏移,所以每当地址为FFF0时,就会出现一行04的线性地址记录,
要么就是程序CODE SECTION区结束也会有这样一行。
10 90D0 00 9A300C9A320C9A7CF01113225072019A 39
10 90E0 00 010C9AB4D89A7E307C70224C0C9A8018 6D
08 90F0 00 9ABC18AA7860B100 D7
02 0000 04 0802 F0
10 E000 00 750320314F42445F48445F3231000000 C5
10 E010 00 00000000000000004431323038313341 4C
10 E020 00 303030310000000000000000535F4844 F1
上面的这行04,代表数据结束了,在BIN文件中接下来的内容全是FF填充,一直填充到Size指定的尺寸,0x26000为止,原因就是Keil里设置了Size=0x26000 ;
Map文件如下:
Load Region LR_IROM1 (Base: 0x08008000, Size: 0x000115f0, Max: 0x00026000, ABSOLUTE, COMPRESSED[0x000110f8])
从0x26000地址开始, 下来的数据内容才是 :
750320314F42445F48445F3231000000
HEX文件尾部:
10 E6D0 00 00000000000000000000000000000000 3A
10 E6E0 00 00000000000000000000000000000000 2A
10 E6F0 00 00000000000000000000000000000000 1A
10 E700 00 00000000000000000000000000000000 09
04 E710 00 00000000 05 写入BIN文件的最后一行
04 0000 05 08008131 3D 线性地址记录,不会写入BIN文件
00 0000 01 FF 文件结束行,不会写入BIN文件
自动生成BIN文件,需要在Keil里 Options for Target 的 User 选项卡里设置编译后的执行命令 :
After Build/Rebuild
RUN #1 $KARM\BIN\ELFDWT.EXE "#L" BASEADDRESS(0x8008000)
RUN #2 $KARM\ARMCC\BIN\fromelf.exe --bin --bincombined --output "#L.bin" "#L"
如果不加 BASEADDRESS ,会生成个文件夹,不会生成BIN文件,里面有两个文件 ER$$.ARM.__AT_0x0802E000 和 ER_IROM1,
其中 ER_IROM1 文件的内容正好是BIN文件的 CODE SECTION 的内容。
ER$$.ARM.__AT_0x0802E000 这个文件的内容正好是 DATA SECTION 的内容。
加上中间用FF填充到 0x26000 地址的所有FF区, 正好是自动生成的 完整的BIN文件。
RUN #1 $KARM\BIN\ELFDWT.EXE "#L" BASEADDRESS(0x8008000)RUN #2 $KARM\ARMCC\BIN\fromelf.exe --bin --bincombined --output "#L.bin" "#L"