打印
[APM32F4]

使用HEX文件进行IAP升级

[复制链接]
327|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 宫影空明人不往 于 2024-7-30 15:35 编辑

#申请原创#
前言
HEX文件和BIN文件是常用来进行IAP升级的文件格式。BIN文件就是简单的数据文件,可以直接将其内容烧录到芯片FLASH相应的地方,而HEX文件则会带有一些其他属性相关信息。本篇帖子将讲解下如何提取HEX文件的信息并将内容烧录到FLASH中。

HEX文件介绍
Hex文件是一种十六进制文本格式,通常用于描述固件或程序的二进制数据。它是一种常见的用于烧录程序到嵌入式系统中的文件格式。下面是Hex文件的基本结构和一些重要的信息:
Hex文件可由五部分组成,分别如下:
  • 起始符号:记录以一个冒号(:)开头,表示记录的起始。
  • 字节数:表示接下来的数据字节数目,以两位十六进制数表示。最多可以传输255字节的数据。
  • 地址:描述数据的起始地址,通常为目标设备的存储器地址。地址字段的长度取决于Hex文件类型(16位地址或32位地址)。
  • 记录类型:指定记录的类型,包括数据记录、结束记录等。
    • 00:数据记录(Data Record),描述要写入目标设备的数据。
    • 01:结束记录(End Of File Record),表示文件结束。
    • 04:扩展地址,也可以理解为基地址。
    • 05:程序的入口地址。
    • 等等
  • 数据(Data):实际的数据以十六进制形式出现,长度由字节数字段决定。
  • 校验和(Checksum):用于检测数据在传输过程中的错误。校验和是记录中所有字节的和(不包括起始符号)的二进制补码的低字节(即取低8位的结果),并且其值应为0。

根据上面HEX的结构,下面对Hex文件进行分析,使用的例子为IAP的APP1升级程序的HEX文件。
:020000040800F2
:1040000010040020B14100080B4C0008074C0008C8
:10401000094C0008BD420008954C00080000000053

我们可以看到,一开始字段的数据长度为0x02,地址为0x0000,类型为0x04,数据为0x0800,校验值为0XF2.
紧接着就是长度为0x10,地址为0x4000,类型为0x00,数据为…,以及校验值为0Xc8。
从上面两段可以看出该第二段的数据需要烧录的地址为0x0800 << 16| 0x4000。第三段则为0x0800 << 16 | 0x4010。后续数据一次类推。
:040000050800419915
:00000001FF

结束的两个字段就表示程序的入口地址为0x08004199,以及该HEX文件传输完毕。

代码编写
这里借用APM32F4xx_SDK_V1.4版本的SDK进行开发,使用的是串口轮询例程。

1.数据收集
在收到':'数据时判断是HEX文件传下来,进行原始数据接收,当接收到的数据长度符合预期时,进行数据处理并退出相应循环。具体如下:
while(1)
    {
        /* Wait until end of reception */
        while(USART_ReadStatusFlag(F4COM1, USART_FLAG_RXBNE) == RESET);
        temp = USART_RxData(F4COM1);
                //检测到‘:’
                if(temp == (uint8_t)':')
                {
                        //重置状态
                        state = 0;
                        count = 0;
                        while(state == 0)
                        {
                                while(USART_ReadStatusFlag(F4COM1, USART_FLAG_RXBNE) == RESET);
                                temp = USART_RxData(F4COM1);
                                
                                hex_buf[count] = temp;
                                count++;
                                if(count == HEXtoASCII(hex_buf[0], hex_buf[1])*2+10)
                                {
                                        //单字段完成
                                        state = 1;
                                }
                        }
                        //数据处理
                        DataProcess();
                }
    }

2.数据转换
我们看到的HEX16进制数据使用ASCII表示的,比如说数据长度进行0x02,传输的是0x30,0x32,因此需要对其进行数据处理。
具体处理代码如下:
#define ASCIItoHEX(x) (x>0x39?(x-0x40+9):(x-0x30))
#define HEXtoASCII(x,y) (ASCIItoHEX(x)*16 + ASCIItoHEX(y))
首先对单个ASCII转换个16进制的值,然后将两个8位数据合并成16位数据储存,方便后续处理。

3.数据处理
对转换后的16进制数据进行处理,主要是将一些信息提取出来,比如说扩展地址,当前地址,数据等等,然后针对不同的数据类型进行不同的操作,主要如下:
void DataProcess(void)
{
        uint8_t i = 0;
        uint8_t len = 0;
        //获取16位数据数量
        process_buf[0] = HEXtoASCII(hex_buf[0], hex_buf[1]);
        //加上其他数据
        len =  process_buf[0] + 5;
        //数据转换
        for(i = 1; i <len ;i++)
        {
                process_buf[i] = HEXtoASCII(hex_buf[2*i], hex_buf[2*i+1]);
        }
        //提取信息
        DATANUM = process_buf[0];
        ODDESTADDR = process_buf[1]<<8 | process_buf[2];
        DATATYPE = process_buf[3];
        CHECKNUM = process_buf[len-1];
        //数据处理
        switch(DATATYPE)
        {
                case 0X00://数据段
                        for(i = 0; i < DATANUM/4; i++)
                        {
                                DATABUF[i] = process_buf[4+4*i]| process_buf[5+4*i]<<8 | process_buf[6+4*i]<<16 | process_buf[7+4*i]<<24;
                        }
                        Flash_Program();
                        break;
                case 0X04://扩展地址
                        BASEADDR = process_buf[4]<<8 | process_buf[5];
                        break;
                case 0X01://结束段
                        Jump_to_APP1();
                        break;
                default:
                        break;
        }
}
功能检验
使用串口助手工具将APP程序传给单片机,单片机正常运行跳转程序。

本次对HEX文件的传输仅进行简单的处理,实际开发中还需要加上校验的确认,错误处理等等。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

11

帖子

0

粉丝