Keil5生成BIN文件及HEX文件介绍

时间:2021-06-04 11:47:56

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"