1. 程式人生 > >hex檔案格式學習記錄

hex檔案格式學習記錄

.hex檔案

.hex檔案是什麼

它是由一行行符合Intel HEX 檔案格式的文字所構成的ASCII 文字檔案。每一行包含一 個 HEX 記錄 ,由對應機器語言碼和/或常量資料的十六進位制編碼數字組成。Hex檔案通常用於傳輸將被存於ROM 或者EPROM 中的程式和數 據。大多數EPROM 程式設計器或模擬器使用Intel HEX 檔案。Hex檔案是可以燒寫到微控制器中,被微控制器執行的一種檔案格式,生成Hex檔案的方式由很多種,可以通過不同的編譯器將C程式或者彙編程式編譯生成hex。

.hex檔案的資料結構

Hex檔案的記錄格式如下:
Hex檔案的記錄格式
Intel HEX 由任意數量的十六進位制記錄組成。每個記錄包含5個域,每一組字母 對應一個不同的域,每一個字母對應一個十六進位制編碼的數字。每一個域由至少兩個十六進位制編碼數字組成,它們構成一個位元組。

  • :(冒號)每個Intel HEX 記錄都由冒號開頭;
  • LL 是資料長度域, 它代表記錄當中資料位元組 (D…D) 的數量;
  • aaaa 是地址域, 它代表記錄當中資料的起始地址;
  • TT是代表HEX 記錄型別的域 , 它可能是以下資料當中的一 個:
    00:資料記錄(Data Record)
    01:檔案結束記錄(End of FileRecord)
    02
    :擴充套件段地址記錄(ExtendedSegment Address Record)
    03:開始段地址記錄(Start Segment Address Record)
    04:擴充套件線性地址記錄(Extended Linear Address Record)
    05:開始線性地址記錄(Start Linear Address Record)
  • D…D是資料域,它代表一個位元組的資料。一個記錄可以有許多資料位元組。記錄當中資料位元組的數量必須和資料長度域(LL)中指定的數字相符。
  • CC是校驗和域,它表示這個記錄的校驗和。校驗和的計算是通過將記錄當中所有十六進位制編碼數字對的值相加,以256為模進行以下補足。

(CheckSum: two’s complement of length,address,record type and data fields module 256.)

記錄格式可表示為:“[1位元組長度][2位元組地址][1位元組記錄型別][n位元組資料段][1位元組校驗和]

關於位、位元組、二進位制、十六進位制:
二進位制,是計算機為了快速方便而採用的一種記數方式,十六進位制也是一種常用的記數方式。位(bit)就是一個二進位制位,即可表示0和1,而位元組(Byte)是計算機更通用的計算單位,1位元組等於8位,可以代表256個數字(在程式設計中可以通過這些數字作為判斷),int型別一般為4位元組,即32位。一個十六進位制數,如0xf,代表16個數字,2的4次方,即4位,所以兩個十六進位制數如0xff就是一個位元組。

按照記錄型別具體分析

  1. 資料記錄”00”
    Intel HEX檔案由任意數量以回車換行符結束的資料記錄組成,資料記錄外觀如下:
    :10246200464C5549442050524F46494C4500464C33
    其中,10 是這個記錄當中資料位元組的數量,即0x10 ;2462 是資料將被下載 到儲存器當中的地址,即0x2462;00 是記錄型別(資料記錄),即0x00;464C…464C是資料,分別代表0x46,0x4C…注意hex中的資料域是小端序的,即按照先低位位元組後高位位元組的方式記錄的;33 是這個記錄的校驗和,即0x33;計算方法如下:
    256D-(10H+24H+62H+00H+46H+4CH+55H+49H+44H+20H+50H+52H+4FH+46H+49H+4CH+45H+00H+46H+4CH)%256D=33H。

各種進位制數的字尾字母分別為:
B :二進位制數。
Q :八進位制數。
D :十進位制數。
H :十六進位制數。
關於%是取餘和取模:
在JAVA、C、C++裡,%是取餘運算,英文remainder;
在Python裡,%號是取模運算,英文modulus;
取餘運算的除法是向零舍入,取模運算的除法是向小值舍入;
取餘運算結果的符號與被除數相同,取模運算結果的符號與除數相同。

  1. 檔案結束(EOF)”01”
    Intel HEX檔案必須以檔案結束(EOF)記錄結束這個記錄的記錄類的值必須是01.EOF記錄外觀總是如下:
    :00000001FF
    其中,00 是記錄當中資料位元組的數量;
    0000 是資料被下載到儲存器當中的地址,在檔案結束記錄當中地址是沒有意義、被忽略的。0000h 是典型的地址;
    01 是記錄型別 01(檔案結束記錄);
    FF 是這個記錄的校驗和,計算方法如下: 256D-(00H+00H+00H+01H)=FFH。
  2. 擴充套件線性地址記錄(HEX386) ”04”
    由於每行標識資料地址的只有2Byte,所以最大隻能到64K,為了可以儲存高地址的資料,就有了Extended Linear AddressRecord。如果這行的資料型別是0x04,那麼,這行的資料就是隨後資料的基地址。擴充套件線性地址記錄也叫作32位地址記錄或HEX386記錄,這些記錄含資料的高16位擴充套件線性地址記錄總是有兩個資料位元組,外觀如下:
    :02000004FFFFFC
    其中,02 是這個記錄當中資料位元組的數量;
    0000 是地址域,對於擴充套件線性地址記錄,這個域總是0000;
    04 是記錄型別04( 擴充套件線性地址記錄);
    FC 是這個記錄的校驗和, 計算如下: 256D-(02H+00H+00H+04H+FFH+FFH)/256D=FFH。

當一個擴充套件線性地址記錄被讀取,儲存於資料域的擴充套件線性地址被儲存,它被用於從 Intel HEX 檔案讀取來的隨後的記錄。線性地址保持有效,直到它被另外一個擴充套件地址記錄所改變。通過把記錄當中的地址域與被移位的來自擴充套件線性地址記錄的地址資料相加獲得資料記錄的絕對儲存器地址。

以下的例子演示了這個過 程:

:0200000480007A //資料記錄的絕對儲存器地址高16位為0x8000

:100000001D000A00000000000000000000000000C9

:100010000000000085F170706F0104005D00BD00FC

第一行,是擴充套件線性地址記錄,裡面的資料、也就是基地址是0x8000,第二行是資料記錄,裡面的地址值是0x0000。那麼資料1D000A00000000000000000000000000(共16個位元組)要寫入FLASH中的地址為 (0x00008000<< 16)| 0x0000,也就是寫入FLASH的0x80000000這個地址;第三行的資料寫入地址為0x80000010。當一個HEX檔案的資料超過64k的時候,檔案中就會出現多個擴充套件線性地址記錄。

左移運算子(<<):
將一個運算物件的各二進位制位全部左移若干位(左邊的二進位制位丟棄,右邊補0)。
例:a = a << 2 將a的二進位制位左移2位,右補0,
左移1位後a = a * 2;
若左移時捨棄的高位不包含1,則每左移一位,相當於該數乘以2。

按位或運算子(|):
參加運算的兩個物件,按二進位制位進行“或”運算。
運算規則:0|0=0; 0|1=1; 1|0=1; 1|1=1;
即 :參加運算的兩個物件只要有一個為1,其值為1。
例如:3|5 即 0000 0011 | 0000 0101 = 0000 0111 因此,3|5的值得7。 
另,負數按補碼形式參加按位或運算。
“或運算”特殊作用:
常用來對一個數據的某些位置1。
方法:找到一個數,對應X要置1的位,該數的對應位為1,其餘位為零。此數與X相或可使X中的某些位置1。
例:將X=10100000的低4位置1 ,用 X | 0000 1111 = 1010 1111即可得到。

  1. 擴充套件段地址記錄(HEX86)“02“
    擴充套件段地址記錄也叫HEX86 記錄 , 它包括4-19 位資料地址段。擴充套件段地址記總是有兩個數 據位元組 , 外觀如下:
    :020000021200EA
    其中,02 是記錄當中資料位元組的數量;
    0000 是地址域。對於擴充套件段地址記錄,這個域總是0000;
    02 是記錄型別 02( 擴充套件段地址記錄);
    1200 是地址段;
    EA 是這個記錄的校驗和。

當一個擴充套件段地址記錄被讀取,儲存於資料域的擴充套件段地址被儲存, 它被應用於 從 Intel HEX 檔案讀取來的隨後的記錄。段地址保持有效, 直到它被另外一 個擴充套件地址記錄所改變。通過把記錄當中的地址域與被移位的來自擴充套件段地址記錄的地址資料相加獲得資料記錄的絕對儲存器地址。

以下的例子演示了這個過程:

來自資料記錄地址域的地址 2462
擴充套件段地址記錄資料域 + 1200
---------
絕對儲存器地址 00014462


2018年12月29日15:17:45

Mermaid

編譯連線示意:

專案相關需求:


2018年12月29日15:20:33

Flowchart

具體流程細節