Intel Hex 文件格式
簡介
這種文件格式一般是以hex為后綴名,在嵌入式MCU程序開發(fā)中,經(jīng)常編譯鏈接后生成一個(gè)這樣文件,然后將這個(gè)文件燒寫到MCU的ROM中。
所以,這個(gè)是開發(fā)工程的輸出文件類型的一種。
發(fā)明這種文件格式的目的就是存儲最終的二進(jìn)制程序和數(shù)據(jù),然后使用這種文件來傳輸程序和數(shù)據(jù),然后燒寫到ROM里。
所以很多燒寫器或調(diào)試模擬器都支持IntelHex這種類型的文件進(jìn)行芯片的程序燒寫。
比如,使用IAR EWARM開發(fā)工具開發(fā)STM32系列Cortex-M4的某款芯片,創(chuàng)建工程,編寫代碼后,在工程構(gòu)建成功后,就可以輸出一個(gè)hex文件。
此hex文件就是最終程序文件,最為軟件的可用發(fā)布成果物。
Hex文件類型全名:Intel hexadecimal object file format, Intel hex format or Intellec Hex。
實(shí)際上是將二進(jìn)制文件轉(zhuǎn)換成了ASCII碼形式的文本文件,我們用文本編輯器打開hex文件,就可以看到里面的內(nèi)容。
這種文件類型的目的就是為了燒寫microcontroller, EPROMs和其他一些可編程邏輯器件。
本來目標(biāo)文件里面的內(nèi)容,應(yīng)該是源代碼編譯后得到的機(jī)器碼。
然后將機(jī)器碼的二進(jìn)制文件轉(zhuǎn)換為hex文件。
此文件格式,顧名思義,是Intel公司發(fā)明的。在1973年,紙片打孔輸入時(shí)就開始使用。
為了能夠加載和運(yùn)行程序,要通過打孔紙片把數(shù)據(jù)信息傳給ROM的生產(chǎn)環(huán)節(jié)。
具體來說就是把一個(gè)字節(jié)的數(shù)據(jù)的16進(jìn)制的表示,轉(zhuǎn)換成字符。
比如,一個(gè)字節(jié)是‘A’,值為0x41,那就用"41"表示這個(gè)字節(jié)。
這樣做的好處,不但接收方能得到正確的數(shù)據(jù),發(fā)送發(fā)使用這種表達(dá)方式,用可打印字符來統(tǒng)一表示所有數(shù)據(jù),更方便編輯和操作。
舉個(gè)例子打開一個(gè)hex文件看一下:
:020000040800F2:20000000F0A10520C9AD030849AA03084BAA03084DAA03084FAA030851AA0308000000009F:20002000000000000000000000000000C598010853AA0308000000006D98010855AA03083A:200040003DAE030841AE030845AE030849AE03084DAE030851AE030855AE030859AA030884:2000600059AE03085DAE030861AE030865AE030869AE03086DAE030871AE030875AE030880:2000800079AE03087DAE030881AE030885AE030889AE03088DAE030891AE030895AE030860還有一種情況,當(dāng)傳輸或存儲可燒寫的程序文件時(shí),如果單純使用二進(jìn)制bin文件,如果文件較大或者地址不連續(xù)時(shí)就比較麻煩,因?yàn)閎in文件是純粹的鏡像image文件。這時(shí)使用hex文件就能更好的處理這些情況。舉個(gè)例子,我們主控芯片如果有需要燒寫外部另一個(gè)MCU固件程序的功能,則主控芯片就要事先存儲固件程序的數(shù)據(jù),這時(shí)如果用bin文件,那就要定義一個(gè)很大的數(shù)組,而使用hex文件格式,在代碼中只要定義一行行的字符串?dāng)?shù)據(jù),這樣更容易管理和操作。
比如對于賽普拉斯的藍(lán)牙芯片,更新驅(qū)動程序的話把程序文件放在源文件里的話:
BTCypress_fw_hex.cpp:/* Cypress Mini Driver */const char * minidriver = ":02000004000DED\n\:10020000F8B5664800F0CEF8654C0025E561E5627A\n\:1002100000F0D2FC01F0A1F810B10120A07001E0C3\n\:1002200000F038FD00F046FD01F066FF00F0A5FC8F\n\:100230005B4FA5627F1C07F12F06207840F001007C\n\:10024000207001F0F6FFE07021780D2801F08001A8\n\:1002500021702581F1D00A28EFD03A2812D04C28FD\n\:1002600013D04D2814D04E2815D0CE2816D05E2895\n\:1002700017D0E52818D0CC2819D018281AD057281C\n\:100280001ED050E000F0E7FB16E000F0BDFB13E0ED\n\:1002900000F08EFB10E000F0F5FA0DE000F0AFFA90\n\......:10C6D000000000000000000000000000000000005A\n\:10C6E000000000000000000000000000000000004A\n\:10C6F000000000000000000000000000000000003A\n\:10C700000000000000000000000000000000000029\n\:10C710000000000000000000000000000000000019\n\:10C7200000000000281F38A138AD823586A04313D1\n\:10C730005C471E5DAE03283802FF1B666C080A5773\n\:10C740008E83994EA7F7BF50DDA302290328080561\n\:10C75000FF26FE2EE709244FB7914061D97A6CE895\n\:10C76000A203280207FF4BDEC4EDD4753B91EB47D3\n\:10C770002D2E08767FA40002120012000002150080\n\:10C780001500018900000000000A040002000002F8\n\:10C7900015001500018900000000000215001500B9\n\:10C7A0000182000000000806090B0A092B282D034E\n\:10C7B0000B2C092B030000802622000806090B0A17\n\:10C7C0000000000B0000000044000001000000FF1A\n\:10C7D0000000000100000002000000011100000044\n\:10C7E0000000000000000000000000FFFFFFFFFF4E\n\:10C7F000FF0000AA55F00F68E597D2000000000A7C\n\:10C8000050007CC722000B480C4908B5884202D072\n\:10C810000B4A05F698FB0A4A00210A4805F697FBE1\n\:10C82000F4F71BF9094B094A23F00F031360BDE825\n\:10C830000840F4F7A0B89026220090262200740B3E\n\:10C84000000078950000043222007CCB22001C24DA\n\:0CC8500020000B04007DC72200FE000049\n\:00000001FF\n";格式
1,每個(gè)hex文件內(nèi)容是以行為單位,也就是說以換行符為分隔符。Windows系統(tǒng)每行以回車換行結(jié)尾CR(carriage return)+ LF(line feed),linux系統(tǒng)只有一個(gè)換行符。LF是0x0A,CR是0x0D。。
2,每條記錄的內(nèi)容是由十六進(jìn)制字符組成,比如要表示一個(gè)字節(jié)的數(shù)據(jù)值為0x3F,那在hex里要用2個(gè)字符,“3F”來表示這個(gè)字節(jié)的數(shù)據(jù)。
3,每一行是一條記錄,包含6個(gè)字段。一個(gè)hex文件可以包含任意數(shù)量的記錄。參照下面內(nèi)容:
:10010000214601360121470136007EFE09D2190140
??Start code???Byte count???Address???Record type???Data???Checksum
第一個(gè)冒號是固定的開始字符,每一行HEX記錄的開始。
第二個(gè)是表示數(shù)據(jù)字段的長度,常用的是10和20,16進(jìn)制表示,長度是16或32個(gè)字節(jié)數(shù)據(jù)一行。最大是FF,255個(gè)。
第三個(gè)是偏移地址,4位十六進(jìn)制數(shù),表示本行數(shù)據(jù)的起始地址。偏移地址要加上基地址才是真正的物理地址。
確定了物理地址,相應(yīng)的數(shù)據(jù)在燒寫時(shí)就會被放置在芯片的對應(yīng)地址空間內(nèi)。
4位偏移地址,最大能表示64KB。超過64KB就需要使用不同的基地址來表示。
基地址如果不指定,默認(rèn)位0。后面有介紹指定基地址的方法,使用不同的記錄類型來表示。
注意,這里使用的都是大端表示法。比如偏移地址4個(gè)數(shù)字0100,表示的就是地址0x0100,閱讀起來比小端方便一些。
第四個(gè)是記錄類型,除了純數(shù)據(jù)類型還有其他類型來表示更多信息。00 - 05,共有五種類型。
不同類型的數(shù)據(jù)字段部分的內(nèi)容含義不同。參見后面記錄類型的說明。
第五個(gè)是數(shù)據(jù)字段,是一個(gè)字節(jié)序列,多個(gè)字節(jié),長度由第二個(gè)字段byte count決定。字節(jié)長度為n,則數(shù)據(jù)字段長度就是2n,每個(gè)字節(jié)2個(gè)16進(jìn)制字符表示。
第六個(gè)是checksum,2位16進(jìn)制數(shù),一個(gè)字節(jié)。用來驗(yàn)證本條記錄的數(shù)據(jù)正確性。
Checksum計(jì)算方法
:10000000F0A10520B1FD030889EB03088BEB030881
以上面這行數(shù)據(jù)舉例:
1,先把前面的每個(gè)字節(jié)數(shù)據(jù)相加。
10+00+00+00+F0+A1+05+20+B1+FD+03+08+89+EB+03+08+8B+EB+03+08 = 67F
2,取最低位字節(jié):7F
3,取反碼:0x100 - 0x7F = 0x81
最后的這個(gè)checksum字節(jié),就是這一行編碼后的數(shù)據(jù)的和,取LSB最低有效字節(jié),然后取補(bǔ)碼(按位取反再加1)。
這樣驗(yàn)證這一行數(shù)據(jù)的方法就是所有數(shù)據(jù)相加的和的最低有效字節(jié)為0,就表示數(shù)據(jù)正確。
記錄類型
00:數(shù)據(jù)
如上面解釋的數(shù)據(jù)記錄格式。
01:文件結(jié)束
hex文件的最后一行,表示文件結(jié)束。字節(jié)長度是0,偏移地址為0(忽略),數(shù)據(jù)部分為空,最后有一個(gè)check sum字節(jié)。
舉例::00000001FF
02:擴(kuò)展記錄類型:段地址
對于80x86處理器,指定16bit的段基地址,所以字節(jié)長度總是2。
舉例: :020000021200EA
字節(jié)長度2,偏移地址固定為0x0000(忽略),記錄類型0x02,段基地址為0x1200,checksum為0xEA。
段基地址的使用方法,在出現(xiàn)了這條段基地址指定的record后,后面的數(shù)據(jù)類型記錄的起始數(shù)據(jù)的偏移地址要和段基地址一起運(yùn)算,知道出現(xiàn)下一個(gè)段基地址。
運(yùn)算方法:段基地址乘以16,然后和數(shù)據(jù)記錄偏移地址相加。這樣整個(gè)hex文件的最大尋址空間可以達(dá)到1MB,單個(gè)記錄最大只能尋址64KB。
段基地址是16bit,乘以16相當(dāng)于增加4個(gè)bit,所以就是20bit的地址,10 bit為1KB,再10bit為1MB。
03:起始段地址
對于80x86處理器,指定CS:IP寄存器的初始值,程序的起始運(yùn)行地址,CS是代碼段 code segment,IP是指令寄存器, instruction pointer。
舉例: :0400000300003800C1
字節(jié)長度固定是4,偏移地址為0(忽略),數(shù)據(jù)字段前兩個(gè)字節(jié)是CS的值,后兩個(gè)是IP的值。
04:擴(kuò)展記錄類型:線性地址(Linear Address)
這個(gè)記錄類型是針對32 bit的地址空間,最大4GB,
舉例: :02000004FFFFFC
字節(jié)長度固定2,偏移地址0(忽略),類型04,地址0xFFFF,checksum是FC。
地址內(nèi)容也是大端表示。
在后面出現(xiàn)的數(shù)據(jù)記錄的偏移地址要和這個(gè)地址組合起來作為真正的絕對地址,知道出現(xiàn)新的04類型記錄。
地址計(jì)算方法:數(shù)據(jù)記錄的地址作為低16位,04記錄的地址作為高16位。
舉例:
:020000040800F2
:1000300093EB0308000000003D46010895EB030820
上面先指定基地址位0x0800,下面的數(shù)據(jù)記錄的偏移地址是0x0030,所以這條數(shù)據(jù)記錄的最終數(shù)據(jù)起始地址是0x08000030.
如果沒有指定04記錄,則基地址位0.
05:起始線性地址
:04000005000000CD2A
長度0x04,偏移地址0x0000(無用),類型0x05,32 bit地址:0x000000CD,checksum:2A。
在80386和更高類型CPU上,這個(gè)32位的big endian地址會被載入EIP寄存器。
這個(gè)寄存器是處理器開始讀取指令的地址,extend instruction pointer。
總結(jié)
在使用IAR EWARM給項(xiàng)目設(shè)定輸出文件類型時(shí),就有一個(gè)Intel?Extended Hex選項(xiàng),這個(gè)就是指支持?jǐn)U展記錄類型的Hex文件。
一般就是使用00,01,04,05四個(gè)記錄類型。
截取實(shí)際生成的hex文件舉例:
:020000040800F2:10000000F0A10520B1FD030889EB03088BEB030881:100010008DEB03088FEB030891EB03080000000051:106EA0001C6014605C6021462B68104810229847D3:106EB0002B680F482146102298472B680D48214621。。。。。。:10C2E000FFF0FFF0FFF0FFF0FFF0FFF0FFF00000C5:10C2F000F0F000000000000000000000000000005E:0AC300000000000000000000000033:040000050803F8E113:00000001FF------------------------------------------------------------------------------------
數(shù)據(jù)分析舉例:
Record Format
An Intel HEX file is composed of any number of HEX records. Each record is made up of five fields that are arranged in the following format:
:llaaaatt[dd...]ccEach group of letters corresponds to a different field, and each letter represents a single hexadecimal digit. Each field is composed of at least two hexadecimal digits-which make up a byte-as described below:
* : is the colon that starts every Intel HEX record.
* ll is the record-length field that represents the number of data bytes (dd) in the record.
* aaaa is the address field that represents the starting address for subsequent data in the record.
* tt is the field that represents the HEX record type, which may be one of the following:
00 - data record
01 - end-of-file record
02 - extended segment address record
04 - extended linear address record
05 - start linear address record (MDK-ARM only)
* dd is a data field that represents one byte of data. A record may have multiple data bytes. The number of data bytes in the record must match the number specified by the ll field.
* cc is the checksum field that represents the checksum of the record. The checksum is calculated by summing the values of all hexadecimal digit pairs in the record modulo 256 and taking the two's complement.
Data Records
The Intel HEX file is made up of any number of data records that are terminated with a carriage return and a linefeed. Data records appear as follows:
:10246200464C5549442050524F46494C4500464C33This record is decoded as follows::10246200464C5549442050524F46494C4500464C33|||||||||||??????????????????????????????CC->Checksum|||||||||DD->Data|||||||TT->Record Type|||AAAA->Address|LL->Record Length:->Colonwhere:
* 10 is the number of data bytes in the record.
* 2462 is the address where the data are to be located in memory.
* 00 is the record type 00 (a data record).
* 464C...464C is the data.
* 33 is the checksum of the record.
Extended Linear Address Records (HEX386)
Extended linear address records are also known as 32-bit address records and HEX386 records. These records contain the upper 16 bits (bits 16-31) of the data address. The extended linear address record always has two data bytes and appears as follows:
:02000004FFFFFCwhere:
* 02 is the number of data bytes in the record.
* 0000 is the address field. For the extended linear address record, this field is always 0000.
* 04 is the record type 04 (an extended linear address record).
* FFFF is the upper 16 bits of the address.
* FC is the checksum of the record and is calculated as
01h + NOT(02h + 00h + 00h + 04h + FFh + FFh).
When an extended linear address record is read, the extended linear address stored in the data field is saved and is applied to subsequent records read from the Intel HEX file. The linear address remains effective until changed by another extended address record.
The absolute-memory address of a data record is obtained by adding the address field in the record to the shifted address data from the extended linear address record. The following example illustrates this process..
Address from the data record's address field??????2462Extended linear address record data field?????FFFF--------Absolute-memory address???????????????????????FFFF2462Extended Segment Address Records (HEX86)
Extended segment address records-also known as HEX86 records-contain bits 4-19 of the data address segment. The extended segment address record always has two data bytes and appears as follows:
:020000021200EAwhere:
* 02 is the number of data bytes in the record.
* 0000 is the address field. For the extended segment address record, this field is always 0000.
* 02 is the record type 02 (an extended segment address record).
* 1200 is the segment of the address.
* EA is the checksum of the record and is calculated as
01h + NOT(02h + 00h + 00h + 02h + 12h + 00h).
When an extended segment address record is read, the extended segment address stored in the data field is saved and is applied to subsequent records read from the Intel HEX file. The segment address remains effective until changed by another extended address record.
The absolute-memory address of a data record is obtained by adding the address field in the record to the shifted-address data from the extended segment address record. The following example illustrates this process.
Address from the data record's address field?????2462Extended segment address record data field??????1200--------Absolute memory address??????????????????????00014462Start Linear Address Records (MDK-ARM only)
Start linear address records specify the start address of the application. These records contain the full linear 32 bit address. The start linear address record always has four data bytes and appears as follows:
:04000005000000CD2Awhere:
* 04 is the number of data bytes in the record.
* 0000 is the address field. For the start linear address record, this field is always 0000.
* 05 is the record type 05 (a start linear address record).
* 000000CD is the 4 byte linear start address of the application.
* 2A is the checksum of the record and is calculated as
01h + NOT(04h + 00h + 00h + 05h + 00h + 00h + 00h + CDh).
The Start Linear Address specifies the address of the __main (pre-main) function but not the address of the startup code which usually calls __main after calling SystemInit(). An odd linear start address specifies that __main is compiled for the Thumb instruction set.
The Start Linear Address Record can appear anywhere in hex file. In most cases this record can be ignored because it does not contain information which is needed to program flash memory.
End-of-File (EOF) Records
An Intel HEX file must end with an end-of-file (EOF) record. This record must have the value 01 in the record type field. An EOF record always appears as follows:
:00000001FFwhere:
* 00 is the number of data bytes in the record.
* 0000 is the address where the data are to be located in memory. The address in end-of-file records is meaningless and is ignored. An address of 0000h is typical.
* 01 is the record type 01 (an end-of-file record).
* FF is the checksum of the record and is calculated as
01h + NOT(00h + 00h + 00h + 01h).
Example Intel HEX File
Following is an example of a complete Intel HEX file:
:10001300AC12AD13AE10AF1112002F8E0E8F0F2244:10000300E50B250DF509E50A350CF5081200132259:03000000020023D8:0C002300787FE4F6D8FD7581130200031D:10002F00EFF88DF0A4FFEDC5F0CEA42EFEEC88F016:04003F00A42EFE22CB:00000001FF--------------------------------------------------------------------------------------?
在IAR-ARM工程(比如STM32L4芯片,Cortext-M4)里輸出程序文件的格式選項(xiàng)里是:Intel Extended Hex,就是Extended Linear Address Records (HEX386),里面有type 04的記錄,能夠表示的更大程序。
在Keil C51工程里,程序文件的輸出格式是: HEX-80。這種程序較小,里面可能沒有基地址設(shè)置命令。
遇到不同的HEX文件類型,是之里面的基地址設(shè)置方式不同,這只是Intel Hex文件格式的擴(kuò)展。
"Intel Hex" is the name. "Hex-80" indicates that none of the extensions introduced for the 8086 (20-bit addresses) and/or the 386 (32-bit addresses) are used.
與Intel 32不同,由于Hex-80用于64K地址范圍以內(nèi)的系統(tǒng),所以沒有基址設(shè)定的指令。如果在Keil-51中,用跨BANK的方式超過了64K,編譯器會產(chǎn)生多個(gè)HXX文件來標(biāo)識BANK。如:
test.h00
test.h01
test.h02
分別在每個(gè)bank的視角來產(chǎn)生64K代碼空間。對于Common Bank由于其在每個(gè)Bank的視角中都存在,所以在幾個(gè)文件中都有同樣的存在,這點(diǎn)要求編程人員注意。
參考:
https://developer.arm.com/documentation/ka003292/latest
總結(jié)
以上是生活随笔為你收集整理的Intel Hex 文件格式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: excel运行python自定义函数_终
- 下一篇: 计算机网络技术用i3可以吗,买电脑避坑第