Hex文件解读

来源:互联网 发布:淘宝小号怎么快速上心 编辑:程序博客网 时间:2024/06/05 11:45

在实际工作中会遇到.bin/.par/.hex类型的文件。并不是说如何使用,只是对于文件本身进行解读而已。

前面两种总体来说就是简单的二进制文件,其中.bin文件是大家在使用,通用的二进制文件,而.par文件是华为使用的,不知道为什么他们要用.par为文件类型,并且也好像就他们在使用而已,跟.bin文件差别。

今天主要讲将对于.hex文件的理解,其实网上到处都是说的,有的说的简单,有的说的复杂。整理一下资料与思路。

定义:Intel HEX 文件是遵循 Intel HEX 文件格式的 ASCII 文本文件。在 Intel HEX 文件的每一行都包含了一个 HEX 记录。这些记录是由一些代表机器语言代码和常量的16进制数据组成的。Intel HEX 文件常用来传输要存储在 ROM 或者 EPROM 中的程序和数据。大部分的 EPROM 编程器能使用 Intel HEX 文件。Intel HEX由任意数量的十六进制记录组成。

每个hex文件使用二进制打开后,是需要转义成ascii字符的,每行以冒号为开始符,回车与换行为结束符。

比如:

:1000000018F09FE518F09FE518F09FE518F09FE5C0\r\n

拆分成:

:+10+0000+00+18F09FE518F09FE518F09FE518F09FE5+C0+\r\n

Start Code+Byte count +Address +Record type +Data +Checksum+endline

Start 

Code

 

 

每个

 

Intel 

HEX 

记录都由冒号开头

 

Byte 

count

 

是数据长度域,它代表记录当中数据字节的数量

 

Address

 

是地址域,它代表记录当中数据的起始地址

 

Record 

type

 

是代表

HEX

记录类型的域,它可能是以下数据当中的一个:

 

 

 

00-

数据记录

 

 

 

01-

文件结束记录

 

 

 

02-

扩展段地址记录

 

 

 

03-

开始段地址记录

 

 

 

04-

扩展线性地址记录

 

 

 

05-

开始线性地址记录

 

Data

 

是数据域,一个记录可以有许多数据字节

.

记录当中数据字节的数量必须和数据长度域中

指定的数字相符

 

Checksum

 

是校验和域,它表示这个记录的校验和

.

校验和的计算是通过将记录当中所有十六

进制编码数字对的值相加,以

256

为模进行以下补足。

其中:
Byte count 是数据长度域,它代表记录当中数据字节的数量 Address 是地址域,它代表记录当中数据的起始地址 
Record type 是代表HEX记录类型的域,它可能是以下数据当中的一个:   00-数据记录   01-文件结束记录   02-扩展段地址记录   03-开始段地址记录   04-扩展线性地址记录   05-开始线性地址记录 
Data 是数据域,一个记录可以有许多数据字节.记录当中数据字节的数量必须和数据长度域中指定的数字相符 
Checksum 是校验和域,它表示这个记录的校验和.校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足。


介绍完了这些基本信息,代码的实现也简单了。以c#为例:

1、读取hex文件,按二进制的方式。hexPath为文件的绝对路径。

 byte[] hexBytes = File.ReadAllBytes(hexPath);

2、将二进制转成文本

string hexStr = ASCIIEncoding.ASCII.GetString(hexBytes);

3、将文本进行拆分,并去掉开始符、结束符,创建一个List来放数据

char[] Delimiters = new char[3] { '\r', '\n', ':' };
string[] lines = hexStr.Split(Delimiters, StringSplitOptions.RemoveEmptyEntries);//分隔后去掉空行

List<byte> hexList = new List<byte>();

4、循环读取每行的信息

 foreach (string line in lines)
{

...

}

5、针对每行进行处理

a、首先看每行的长度

  int lenline = line.Length;
                if ((lenline % 2) != 0)//如果取出来长度不是2的倍数,说明有问题
                {
                    MessageBox.Show("此行长度有问题");
                    return;
                }
                lenline = lenline / 2;

b、将整行的文本按每两个字符一组拆分,每组为一个16进制的数,并计算校验和

byte[] tem = new byte[lenline];
                int checksum = 0;
                for (int i = 0; i < lenline; i++)
                {
                    tem[i] = Convert.ToByte(line.Substring(2 * i, 2), 16);
                    if (i < lenline - 1) { checksum = checksum + tem[i]; }//计算校验和                   
                }
                checksum = (checksum ^ 255) + 1;
                checksum = checksum & 255;
                if (checksum != tem[lenline - 1])
                { 
                    MessageBox.Show("校验和检查失败");
                    return;
                }

c、检查Record type,数据才是我们需要的,其他的都不需要

if (tem[3] == 1 || tem[3] == 4 || tem[3] == 5) {continue; }

d、检查地址是不正确

int address = tem[1] * 256 + tem[2];
                if (address != hexList.Count) {
                    MessageBox.Show("地址异常");
                    return;       
                }

f、将实际数据取出来放在List中去

  for (int i = 4; i < lenline - 1; i++)
                {
                    hexList.Add(tem[i]);
                }


这样就完成了。

我之前一直以为hex文件跟bin文件一样,都是按二进制来查看的,是我想太简单了。

0 0
原创粉丝点击