在很多复杂的系统中,或者多人参与设计的系统中,程序分区必不可免。 就拿最简单的IAP升级来说,包含两个程序区,BOOT区和APP区。其中,BOOT区的主要职责是引导代码进去APP区执行目标功能,但在下载的时候,往往提供一个hex文件即可。 当然,提供两个分别下载也可行,但生产过程中增加一个工序就是一个工序的价格。再说了,完全没必要,这就涉及到了本章介绍的hex文件合并(BIN文件当然OK的)。 一、什么是hex文件? hex文件格式是可以烧写到单片机中,被单片机执行的一种文件格式,生成Hex文件的方式有很多种,可以通过不同的编译器将C程序或者汇编程序编译生成hex。 Hex文件格式: 先来看一下hex文件,主要截取了三部分,开头1行。
中间数据,这里只截取了一部分作为表示。
结尾2行:
数据少不了数据格式(协议),先来看一看hex文件的数据格式,以第一行数据(020000040002f8)为例,看一看hex文件的每一字段数据是什么意思: 020000040002f8可以分解为: 0x02 0x00 0x00 0x04 0x02 0x02 0xf8,前面4个字节和最后一个字节是有特殊含义的,中间为数据,每个字段的具体含义如下: 1. 第一字节0x02:数据长度,即该行有多少个数据; 2. 第二、三字节0x00、0x00:表示本行数据的起始地址位; 3. 第四个字节有0x00 0x01 0x02 0x03 0x04 0x05,分别有以下含义: - '00’Data Rrecord:用来记录数据,HEX文件的大部分记录都是数据记录
- '01’文件结束记录:用来标识文件结束,放在文件的最后,标识HEX文件的结尾
- '02’扩展段地址记录:用来标识扩展段地址的记录
- '03’开始段地址记录:开始段地址记录
- '04’扩展线性地址记录:用来标识扩展线性地址的记录
- '05’开始线性地址记录:开始线性地址记录
最后一个字节0xf8为校验和:校验和= 0x100 - 累加和。 单纯看上面的介绍,好像也看不出和MCU的FLASH地址如何联系起来,接下来看看是如何跟FLASH地址对应的。
第一字节表示该行的数据字节数;如第1行只有 0x08 0x00 两个字节的数据,类型是 04 ,即该行记录的是一个拓展地址(0x08 0x00 是地址信息,用法是将该地址(0x0800<<16) 后作为基地址。并且表示在下一个04类型行出现之前都要使用该地址。 例如第2行的地址信息是 0x0000,则表示该行数据从0x08000000( (0x0800<<16) | 0x0000 )开始记录。 第3行则从 0x08000010 ( (0x0800<<16) | 0x0010 )开始记录。 另外最后一个字节的校验和 0xD2 = 0xff & ( 0x100- (0x10+4*(0x00)+0x38+0x05+…+0x00+0x08) ) = 0xff & (0x100-0x2E); 然后再看结尾部分:类型是05,有4字节数据,从上面的介绍可以知道,05是指“开始线性地址记录”,什么意思呢? 其实就是函数入口地址,从编译产生的.map文件中,可以看到Image Entry point后面跟的就是这个值。 例如,第2行的地址信息是 0x0000,则表示该行数据从0x08000000( (0x0800<<16) | 0x0000 )开始记录; 而第3行则从 0x08000010 ( (0x0800<<16) | 0x0010 )开始记录。 另外,最后一个字节的校验和 0xD2 = 0xff & ( 0x100- (0x10+4*(0x00)+0x38+0x05+…+0x00+0x08) ) = 0xff & (0x100-0x2E); 然后再看结尾部分:类型是05,有4字节数据,从上面的介绍可以知道,05是指“开始线性地址记录”,什么意思呢? 其实就是函数入口地址,从编译产生的.map文件中,可以看到Image Entry point后面跟的就是这个值。
最后的一行,01代表文件结束,以上就是关于hex文件的简单介绍。 二、合并hex文件的几种方法1、传统而不优雅的直接合并法打开我们的hex文件,就以BOOT和APP代码为例,用记事本或者其他的软件(notepad++等)打开。
从上面的介绍我们可以知道,hex文件最后一行是代表文件的结束,那么我们只需要删除boot文件的最后一行代码,然后把APP的代码直接拷贝过来。
这样我们就得到了最终的hex文件,直接烧录进去MCU即可。
|