1、 文檔目標(biāo)
在嵌入式系統(tǒng)開發(fā)中,HEX文件是程序編譯后生成的一種常見輸出格式,尤其在基于ARM架構(gòu)的開發(fā)環(huán)境中,由Keil MDK工具鏈生成的HEX文件被廣泛用于燒錄和調(diào)試。然而,盡管工程師們對其用途較為熟悉,但對其內(nèi)部結(jié)構(gòu)及數(shù)據(jù)段的具體含義卻往往缺乏深入了解。本文旨在解析由MDK生成的HEX文件中各數(shù)據(jù)段的組成,幫助開發(fā)者理解其內(nèi)部邏輯,并通過校驗和計算驗證文件的完整性。
具體目標(biāo)包括:
● 解析HEX文件中每行數(shù)據(jù)的組成部分及其意義;
● 探討不同數(shù)據(jù)類型(如線性地址、擴(kuò)展段地址等)的作用;
● 提供詳細(xì)的校驗和計算方法,以確認(rèn)HEX文件是否正確生成。
通過本文的解析,讀者將能夠更全面地掌握HEX文件的結(jié)構(gòu)與生成機(jī)制,為后續(xù)的調(diào)試與優(yōu)化提供理論支持。
2、 問題場景
在嵌入式項目開發(fā)過程中,HEX文件通常作為程序燒錄的主要載體。然而,許多工程師在使用HEX文件時,往往只關(guān)注其功能性(如能否正常燒錄或運(yùn)行),而忽視了其內(nèi)部結(jié)構(gòu)的細(xì)節(jié)。例如,在圖2-1所示的HEX文件中,每一行數(shù)據(jù)都包含特定的信息字段,這些字段決定了程序代碼和數(shù)據(jù)如何映射到目標(biāo)硬件的存儲空間中。從圖2-1可以看到,HEX文件的每一行數(shù)據(jù)均遵循嚴(yán)格的格式規(guī)范,包含起始標(biāo)志、數(shù)據(jù)長度、地址偏移量、數(shù)據(jù)類型標(biāo)識、實際數(shù)據(jù)以及校驗碼等字段。如果對這些字段的意義不甚了解,可能會導(dǎo)致在分析或調(diào)試過程中遇到困難。例如,錯誤的地址偏移可能導(dǎo)致程序無法正確加載,而校驗碼的錯誤則可能暗示文件生成過程中存在異常。
因此,深入解析HEX文件的結(jié)構(gòu)不僅有助于理解其生成機(jī)制,還能有效提升開發(fā)過程中的問題定位能力。

圖 2-1
3、軟硬件環(huán)境
1)、軟件版本:Keil MDK 5.38a
2)、電腦環(huán)境:Windows 11
3)、外設(shè)硬件:無
4、解決方法
1)、首先,Intel HEX文件是一個ASCII文本文件,其中的文本行遵循Intel HEX文件格式。Intel 十六進(jìn)制文件中的每一行包含一條十六進(jìn)制記錄。這些記錄由表示機(jī)器語言代碼和/或常量數(shù)據(jù)的十六進(jìn)制數(shù)組成。Intel十六進(jìn)制文件通常用于傳輸將存儲在ROM或EPROM中的程序和數(shù)據(jù)。大多數(shù)EPROM程序員或模擬器可以使用Intel十六進(jìn)制文件。
2)、Hex文件的數(shù)據(jù)格式為:“:LLAAAATTDDDDDDDD...DDCC”
(1)“:”:表示開頭,每一行數(shù)據(jù)都會用冒號進(jìn)行開頭,表示一個新的內(nèi)存地址數(shù)據(jù)開頭
(2)“LL”:表示數(shù)據(jù)長度,L是4位的十六進(jìn)制,LL表示一個字節(jié)。
(3)“AAAA”:表示偏移量,基于起始地址的偏移量是多少
(4)“TT”:表示這一行數(shù)據(jù)類型或數(shù)據(jù)標(biāo)識是什么。
a) 00:表示數(shù)據(jù)標(biāo)識;
b) 01:表示文件結(jié)束標(biāo)識,通常的hex文件的最后一行數(shù)據(jù)中;
c) 02:表示擴(kuò)展段的地址;
d) 04:表示線性地址;
e) 05:表示線性起始地址
(5)“DDD.....DDD”:這里就表示數(shù)據(jù)。每一個數(shù)字都是占4位,2個數(shù)字就是一個字節(jié)。
(6)“CC”:表示校驗碼。校驗碼是通過下面的公式進(jìn)行計算出來的。
CheckSum = 0x100 - (Sum & 0xFF)
其中Sum是由這一行的所有字節(jié)進(jìn)行相加所得,Sum與上0xFF后即保留Sum的后8位數(shù)據(jù),然后再減去0x100。
3)、例子:
(1)、HEX文件的開頭第一行(如圖4-3-1):“:020000040040BA”
(a)、“:”:表示開頭
(b)、“02”:表示數(shù)據(jù)長度,02是十六進(jìn)制,單位的byte,即表示這一行的數(shù)據(jù)長度是2個字節(jié)。
(c)、“0000”:基于起始地址的偏移量是0x0000
(d)、“04”:表示這一行是線性地址
(e)、“0040”:這里就表示段地址信息。每一個數(shù)字都是占4位,這一行中4個數(shù)字,則16位即2bytes,和前面的第二部分的“10”進(jìn)行對應(yīng)。地址是0x0400000,是內(nèi)存的起始地址即基地址
(f)、“BA”:表示校驗碼。校驗和的計算過程如下:
Sum = 0x02+0x00+0x00+0x04+0x00+0x40=0x46
CheckSum = 0x100-0x46&0xFF=0x100-0x46=0xBA

4-3-1
(2)、HEX文件的中間的數(shù)據(jù)行(如圖4-3-2):“:1000A0009B0340009B0340009B0340009B034000D8”
(a)、“:”:表示開頭
(b)、“10”:表示數(shù)據(jù)長度,這一行的數(shù)據(jù)長度是16個字節(jié)。
(c)、“00A0”:基于起始地址的偏移量是0x00A0
(d)、“00”:表示這一行是數(shù)據(jù)
(e)、“9B03......4000”:這里就表示數(shù)據(jù)。每一個數(shù)字都是占4位,這一行中32個數(shù)字,則128位即16bytes,和前面的第二部分的“10”進(jìn)行對應(yīng)。
(f)、“D8”:表示校驗碼。校驗和的計算過程如下:
Sum = 0x10+0x00+0xA0+0x00+0x9B+0x03+0x40+0x00+0x9B+0x03+0x40+0x00+0x9B+0x03+0x40+0x00+0x9B+0x03+0x40+0x00=0x428
CheckSum = 0x100-0x428&0xFF=0x100-0x28=0xD8

圖 4-3-2
(4)、Hex文件的倒數(shù)第二行數(shù)據(jù)(如圖4-3-3-2):“:040000050040014175”
(a)、“:”:表示開頭
(b)、“04”:表示數(shù)據(jù)長度,這一行的數(shù)據(jù)長度是4個字節(jié)。
(c)、“0000”:基于起始地址的偏移量是0x0000,這個偏移地址是無效數(shù)據(jù),無需關(guān)注
(d)、“05”:表示這一行是線性起始地址
(e)、“00400141”:這里就表示線性起始地址。地址為0x00400141,是指令集執(zhí)行的起始地址,這個地址指向的是__scatterload函數(shù),該函數(shù)用于將程序代碼和數(shù)據(jù)從鏈接文件中加載到內(nèi)存中,是由編譯器提供的。(如圖4-3-3-1)

圖4-3-3-1
(f)、“75”:表示校驗碼。校驗和的計算過程如下:
Sum = 0x04+0x00+0x00+0x05+0x00+0x40+0x01+0x41= =0x8B
CheckSum = 0x100-0x428&0xFF=0x100-0x8B=0x75

圖4-3-3-2
(5)、Hex文件的最后一行數(shù)據(jù):“:00000001FF”
(a)、“:”:表示開頭
(b)、“00”:表示數(shù)據(jù)長度。
(c)、“0000”:基于起始地址的偏移量是0x0000,這個偏移地址是無效數(shù)據(jù),無需關(guān)注
(d)、“01”:表示文件結(jié)束標(biāo)識
(e)、“FF”:校驗和

圖4-3-4

首頁 > 資源中心 > FAQ
