Hex文件解读
在實際工作中會遇到.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文件一樣,都是按二進制來查看的,是我想太簡單了。
總結
- 上一篇: Excel 使用小妙招之解决“##”显示
- 下一篇: String Hex互相转换