日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

HEX文件格式解析(转)

發(fā)布時(shí)間:2023/12/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HEX文件格式解析(转) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Hex格式文件有兩種,一種是Intel的Intel HEX,另一種是Motorola(摩托羅拉)的SREC(又稱MOT)。


Intel HEX 文件是由一行行符合Intel HEX 文件格式的文本所 構(gòu) 成的ASCII 文本文件。在Intel HEX 文件中,每一行包含一 個(gè) HEX 記錄 。 這 些 記錄 由 對(duì)應(yīng) 機(jī)器 語(yǔ) 言 碼 和/ 或常量 數(shù) 據(jù)的十六 進(jìn) 制 編碼數(shù) 字 組 成。Intel HEX 文件通常用于 傳輸將 被存于ROM 或者EPROM 中的程序和 數(shù) 據(jù)。大多 數(shù) EPROM 編 程器或模 擬器使用Intel HEX 文件。

Hex文件是可以燒寫(xiě)到單片機(jī)中,被單片機(jī)執(zhí)行的一種文件格式,生成Hex文件的方式由很多種,可以通過(guò)不同的編譯器將C程序或者匯編程序編譯生成hex。

一般Hex文件通過(guò)記事本就可以打開(kāi)。可以發(fā)現(xiàn)一般Hex文件的記錄格式如下:

Intel HEX 由任意數(shù)量的十六 進(jìn) 制 記錄組 成。每 個(gè)記錄 包含5 個(gè) 域, 它們按以下格式排列:

每一組字母 對(duì)應(yīng) 一 個(gè) 不同的域,每一 個(gè) 字母 對(duì)應(yīng) 一 個(gè) 十六 進(jìn) 制 編碼 的 數(shù) 字。每一 個(gè) 域由至少 兩個(gè) 十六 進(jìn)制 編碼數(shù) 字 組 成, 它們構(gòu) 成一 個(gè) 字 節(jié) ,就像以下描述的那 樣:

(1):(冒號(hào))每個(gè)Intel HEX 記錄 都由冒 號(hào)開(kāi)頭 ;

(2)LL 是 數(shù) 據(jù) 長(zhǎng) 度域, 它 代表 記錄當(dāng) 中 數(shù) 據(jù)字 節(jié) (dd) 的 數(shù)量 ;

(3)aaaa 是地址域, 它代表 記錄當(dāng) 中 數(shù)據(jù)的起始地址;

(4)TT是代表HEX 記錄類 型的域 , 它 可能是以下 數(shù) 據(jù) 當(dāng) 中的一 個(gè):
00 – 數(shù) 據(jù) 記錄(Data Record)
01 – 文件結(jié) 束 記錄(End of FileRecord)
02 – 擴(kuò)展段地址 記錄(ExtendedSegment Address Record)
03 – 開(kāi)始段地址 記錄(Start Segment Address Record)
04 – 擴(kuò)展 線 性地址 記錄(Extended Linear Address Record)
05 – 開(kāi)始線性地址 記錄(Extended Segment Address Record)

(5)dd 是數(shù) 據(jù)域 , 它 代表一 個(gè) 字 節(jié) 的 數(shù) 據(jù). 一 個(gè)記錄 可以有 許 多 數(shù) 據(jù)字 節(jié) . 記錄當(dāng) 中 數(shù) 據(jù)字 節(jié) 的 數(shù) 量必 須 和數(shù) 據(jù) 長(zhǎng) 度域(ll) 中指定的 數(shù)字相符.

(6)cc 是校驗(yàn) 和域 , 它 表示 這個(gè)記錄 的校 驗(yàn) 和. 校 驗(yàn) 和的 計(jì) 算是通 過(guò)將記錄當(dāng) 中所有十六 進(jìn) 制 編碼數(shù) 字 對(duì) 的 值相加, 以256 為 模 進(jìn) 行以下 補(bǔ) 足.

表示為:“:[1字節(jié)長(zhǎng)度][2字節(jié)地址][1字節(jié)記錄類型][n字節(jié)數(shù)據(jù)段][1字節(jié)校驗(yàn)和] ”


(TT)具體根據(jù)記錄類型分析如下:

(1)數(shù)據(jù)記錄”00”

Intel HEX文件由任意數(shù) 量以回車換行符結(jié)束的數(shù)據(jù)記錄組成數(shù)據(jù)記錄外觀如下:
:10246200464C5549442050524F46494C4500464C33
其中:10 是這個(gè)記錄當(dāng)中 數(shù) 據(jù)字 節(jié) 的 數(shù)量.即0x10 ;
2462 是數(shù)據(jù) 將 被下 載 到存 儲(chǔ) 器 當(dāng)中的地址.即0x2462 ;

00 是記錄類型( 數(shù) 據(jù) 記錄).即0x00 ;
464C…464C是 數(shù)據(jù).分別代表0x46,0x4C… ;
33 是這個(gè)記錄的校 驗(yàn)和即0x33;計(jì)算方法如下:256D-(10H+24H+62H+00H+46H+4CH+55H+49H+44H+20H+50H+52H+4FH+46H+49H+4CH+45H+00H+46H+4CH)/100H=33H;

(2)文件結(jié)束(EOF)”01”

Intel HEX文件必須以文件結(jié)束(EOF) 記錄結(jié)束這個(gè)記錄的記錄類的值必須是01.EOF 記錄 外 觀總是如下:
:00000001FF
其中:00 是記錄當(dāng)中 數(shù) 據(jù)字 節(jié) 的 數(shù)量.
0000 是數(shù)據(jù)被下載到存儲(chǔ)器當(dāng)中的地址. 在文件結(jié)束記錄當(dāng)中地址是沒(méi)有意義,被忽略的.0000h 是典型的地址;
01 是記錄類型 01( 文件 結(jié) 束 記錄)
FF 是 這個(gè)記錄 的校 驗(yàn) 和, 計(jì)算方法如下: 256D-(00H+00H+00H+01H)=FFH;

(3)擴(kuò)展線性地址記錄(HEX386) ”04”

由于每行標(biāo)識(shí)數(shù)據(jù)地址的只有2Byte,所以最大只能到64K,為了可以保存高地址的數(shù)據(jù),就有了Extended Linear AddressRecord。如果這行的數(shù)據(jù)類型是0x04,那么,這行的數(shù)據(jù)就是隨后數(shù)據(jù)的基地址。

擴(kuò)展線性地址記錄也叫作32位地址記錄或HEX386記錄.這些記錄含數(shù)據(jù)的高16位擴(kuò)展線性地址記錄總是有兩個(gè)數(shù)據(jù)字節(jié),外觀如下:
:02000004FFFFFC

其中:02 是這個(gè)記錄當(dāng)中 數(shù) 據(jù)字 節(jié) 的 數(shù)量.
0000 是地址域, 對(duì)于 擴(kuò) 展 線 性地址 記錄 , 這個(gè) 域 總是0000.
04 是記錄類型 04( 擴(kuò) 展 線 性地址 記錄)
FFFF 是地址的高16 位.
FC 是這個(gè)記錄的校 驗(yàn) 和, 計(jì)算如下: 256D-(02H+00H+00H+04H+FFH+FFH)/100H=FCH;

當(dāng)一 個(gè)擴(kuò)展 線 性地址記錄被讀 取, 存 儲(chǔ)于數(shù)據(jù)域的擴(kuò)展線性地址被保存,它被應(yīng)于

從 Intel HEX 文件 讀取 來(lái) 的 隨 后的 記錄 . 線 性地址保持有效, 到 它 被另外一 個(gè)擴(kuò)址記錄 所改 變。

通 過(guò) 把 記錄當(dāng) 中的地址域 與 被移位的 來(lái) 自 擴(kuò) 展 線 性地址 記錄 的地址 數(shù) 據(jù)相加

獲 得 數(shù) 據(jù) 記錄 的 絕對(duì) 存 儲(chǔ)器地址。

以下的例子演示了這個(gè)過(guò) 程:

:0200000480007A //數(shù)據(jù)記錄的絕對(duì)存儲(chǔ)器地址高16位為0x8000

:100000001D000A00000000000000000000000000C9

:100010000000000085F170706F0104005D00BD00FC

第一行,是Extended Linear Address Record,里面的數(shù)據(jù),也就是基地址是0x8000,第二行是DataRecord,里面的地址值是0x0000。那么數(shù)據(jù)1D000A00000000000000000000000000(共16個(gè)字節(jié))要寫(xiě)入FLASH中的地址為 (0x8000<< 16)| 0x0000,也就是寫(xiě)入FLASH的0x80000000這個(gè)地址;第三行的數(shù)據(jù)寫(xiě)入地址為0x80000010.當(dāng)一個(gè)HEX文件的數(shù)據(jù)超過(guò)64k的時(shí)候,文件中就會(huì)出現(xiàn)多個(gè)Extended Linear Address Record。

(4)擴(kuò)展段地址記錄(HEX86)“02“

擴(kuò)展段地址記錄也叫HEX86 記錄 , 它包括4-19 位數(shù)據(jù)地址段. 擴(kuò)展段地址記總是有兩

個(gè)數(shù) 據(jù)字節(jié) , 外觀如下:
:020000021200EA
其中:02 是記錄當(dāng)中 數(shù) 據(jù)字 節(jié) 的 數(shù)量;
0000 是地址域. 對(duì)于 擴(kuò) 展段地址 記錄 , 這個(gè) 域 總是0000;
02 是記錄類型 02( 擴(kuò) 展段地址 記錄);
1200 是地址段;
EA 是這個(gè)記錄的校 驗(yàn) 和;

當(dāng)一 個(gè)擴(kuò) 展段地址 記錄 被 讀 取, 存 儲(chǔ) 于 數(shù) 據(jù)域的 擴(kuò) 展段地址被保存, 它 被 應(yīng) 用于 從 Intel HEX 文件 讀 取 來(lái)的 隨 后的 記錄 . 段地址保持有效, 直到 它 被另外一 個(gè)擴(kuò) 展地址 記錄 所改 變。

通 過(guò) 把 記錄當(dāng) 中的地址域 與 被移位的 來(lái) 自 擴(kuò) 展段地址 記錄 的地址 數(shù) 據(jù)相加 獲 得 數(shù) 據(jù) 記錄 的 絕對(duì) 存 儲(chǔ)器地址。
以下的例子演示了這個(gè)過(guò) 程…
來(lái)自 數(shù) 據(jù) 記錄地址域的地址 2462
擴(kuò)展段地址 記錄數(shù)據(jù)域 + 1200
---------
絕對(duì)存 儲(chǔ) 器地址 00014462

Intel HEX 文件例子:
下面是一個(gè) 完整的Intel HEX 文件的例子:
:10001300AC12AD13AE10AF1112002F8E0E8F0F2244
:10000300E50B250DF509E50A350CF5081200132259
:03000000020023D8
:0C002300787FE4F6D8FD7581130200031D
:10002F00EFF88DF0A4FFEDC5F0CEA42EFEEC88F016
:04003F00A42EFE22CB
:00000001FF


SREC
SREC全稱Motorola S-record,一種文件格式,由摩托羅拉創(chuàng)建的,該文件使用ASCII HEX文件格式表達(dá)二進(jìn)制信息。這種格式也叫做SRECORD, SREC, S19, S28, S37。通常用于微控制器編程,EPROMs和其他可編程的邏輯器件。在通常的應(yīng)用中,編譯器或匯編器將程序的源代碼(如C語(yǔ)言或匯編語(yǔ)言)轉(zhuǎn)換成機(jī)器代碼,并將其輸出到一個(gè)HEX文件。然后這個(gè)HEX文件被程序員燒寫(xiě)到ROM中,或者轉(zhuǎn)移到目標(biāo)系統(tǒng)用于裝載和執(zhí)行。
//SREC格式

//第一行數(shù)據(jù)
S0 0F 0000 636B3631302D6C2E73686578 0C
//行數(shù)據(jù)
S2 08 010000 FFFFFFFF FA
S3 15 08640000 6C0264086C0264086C0264086C026408 16
S5 03 0002 FA
S7 05 08640214 78

SREC文件一行為單位,分為5個(gè)部分。分別是記錄類型域、字節(jié)數(shù)域、地址域、數(shù)據(jù)域、校驗(yàn)域。

第一部分類型域是SREC文件的起始標(biāo)志,代表該行的類型,必須已S開(kāi)始,值可以是從S0到S9;


第二部分字節(jié)數(shù)域是每行記錄的長(zhǎng)度,地址域、數(shù)據(jù)域、校驗(yàn)域三個(gè)域的長(zhǎng)度,單位為字節(jié)數(shù)。

第三部分地址域,該域的長(zhǎng)度取決于第一部分類型域。

第四部分?jǐn)?shù)據(jù)域,該自動(dòng)長(zhǎng)度=字節(jié)數(shù)域的值-地址域長(zhǎng)度-1(校驗(yàn)域長(zhǎng)度)

第五部分校驗(yàn)域,該域長(zhǎng)度為1byte(16-bit),校驗(yàn)方法是:除了類型域的值其他十六進(jìn)制值每?jī)蓚€(gè)一組相加結(jié)果末兩位為0xFF。


讀取代碼:
QT語(yǔ)言

#include<stdio.h> #include<stdlib.h> #include<QDebug> #include<QString> #include<QByteArray> #include<QDebug> #include<QFile> #include<QDataStream>static char pq=9; //規(guī)范代碼/****16進(jìn)制的數(shù)據(jù)類型*****/ const QString HexTypeTable[6] = {"00","01","02","03","04","05", };/****配套數(shù)據(jù)類型使用的枚舉變量*****/ typedef enum __tagHexType {RECORD_DATA = 0,RECORD_END_OF_FILE,RECORD_EXTENDED_SEGMENT_ADDRESS,RECORD_START_SEGMENT_ADDRESS,RECORD_EXTENDED_LINEAR_ADDRESS,RECORD_START_LINEAR_ADDRESS,RECORD_HEX_MAX, }emHexType;typedef enum Boolsymbol {DATA_Flase = 0,DATA_Ture }BoolTureFlase;//定義字符串的類型格式 typedef struct StringTypes {char Firstsymbolis;char StringCrcis;char StringSizeis;char StringResultis;char StringType;//QString BaseAddress; }StringType;static StringType StringTypeLine={DATA_Ture,DATA_Ture,DATA_Ture,DATA_Ture,RECORD_DATA}; //定義字符串的類型格式/****函數(shù)聲明*********/ QString AnalyseHEX(QByteArray dest); int mystrlen(const char *StrDest); int HexToDec(char *src); QString QStringLeftBit(QString src,int num); QString QStringToAdd(QString dest,QString src); StringType FormatHexjudge(QByteArray src); QString BaseAddjudge(QByteArray src); void ReadWrite(QString filenameread,QString filenameWrite);/****計(jì)算字符串長(zhǎng)度*****/ int mystrlen(const char *StrDest) {int i;i=0;while((*StrDest++)!='\0'){i++;}//這個(gè)循環(huán)體意思是從字符串第一個(gè)字符起計(jì)數(shù),只遇到字符串結(jié)束標(biāo)志'\0’才停止計(jì)數(shù)return i; }/****16進(jìn)制轉(zhuǎn)換10進(jìn)制*****/ int HexToDec(char *src) {//將src中的無(wú)符號(hào)十六進(jìn)制字符串轉(zhuǎn)為十進(jìn)制數(shù)//如src="001A",則返回26//字符串src需要以'\0'作為結(jié)束標(biāo)志int value=0,srclen=mystrlen(src);int i;for(i=0;i<srclen;i++){if(src[i]<='9'&&src[i]>='0'){value=value*16+(int)(src[i]-'0'); //'0'}else if(src[i]<='f'&&src[i]>='a'){value=value*16+(int)(src[i]-'a'+10);}else{value=value*16+(int)(src[i]-'A'+10);}}return value;//返回轉(zhuǎn)換后的數(shù)值 }/****字符串效驗(yàn)*返回效驗(yàn)的十進(jìn)制數(shù)用來(lái)與字符串后兩位做比較****/ QString AnalyseHEX(QByteArray dest) {unsigned char i=1;int tempsum=0; //必須初始化,否則亂碼QString stype;QString ZERO="0";QString Date0x100="100";QString result;do{stype = dest.mid(i,2); //轉(zhuǎn)換成10進(jìn)制運(yùn)算后,再轉(zhuǎn)換成十六進(jìn)制printf(" %d",HexToDec(stype.toLatin1().data()));tempsum+=HexToDec(stype.toLatin1().data());i+=2;} while (i<(mystrlen(dest)-2));/***HEX計(jì)算公式(0x100-(16進(jìn)制數(shù)據(jù)和后兩位))再取后兩位=字符串后兩位*****/result=QString::number((HexToDec(Date0x100.toLatin1().data())-HexToDec(QString::number(tempsum,16).right(2).toLatin1().data())),16);if(result.size()<2){int count=2-result.size();//printf("count=2-result.right(2).size()=%d\n",count);while(count-->0){result.insert(0,ZERO);}}//qDebug()<<"result.right(2).toUpper()"<<result.right(2).toUpper();return result.right(2).toUpper();}/***0613*****字符串左移num位*****************/QString QStringLeftBit(QString src,int num) //{QString zero="0";while(num-->0){src.insert(src.size()-2,zero); //末尾位加零src.remove(0,1); //刪除起始位}return src;}/***0613*****字符串以十六進(jìn)制的形式轉(zhuǎn)換成十進(jìn)制相加,然后轉(zhuǎn)換成十六進(jìn)制的字符串形式輸出*****/QString QStringToAdd(QString dest,QString src){QString ResultDate;QString ZERO="0";int num1,num2,ans;int count;bool ok;num1=dest.toInt(&ok,16); //轉(zhuǎn)換成10進(jìn)制num2=src.toInt(&ok,16);ans=num1+num2;ResultDate=QString::number(ans,16);/**判斷結(jié)果字符串與輸入的兩個(gè)字符串的最大差值,用于給結(jié)果字符串補(bǔ)零***/(dest.size()-ResultDate.size()>src.size()-ResultDate.size())?count=dest.size()-ResultDate.size():count=src.size()-ResultDate.size();while(count-->0){ResultDate.insert(0,ZERO);}return ResultDate.toUpper();//十進(jìn)制轉(zhuǎn)換成Qstring的形式輸出 toUpper() //轉(zhuǎn)換成大寫(xiě)字母}/****文件格式類型判斷,有錯(cuò)誤打印,返回值為基地址******/ StringType FormatHexjudge(QByteArray src) //QString *resultBaseAddres {QByteArray resultString=":00000001FF";static uint32_t count_num=0;count_num++;/******驗(yàn)證一下傳入的數(shù)據(jù)***********/char *pcdata = src.data();//printf("Length of src:%d\n",mystrlen(src)); //打印傳入數(shù)據(jù)大小while(*pcdata){//printf("%c",*pcdata); //打印原始數(shù)據(jù)++pcdata;}//printf("\n");if(src.left(1)!=":"){//不是以":"開(kāi)始StringTypeLine.Firstsymbolis=DATA_Flase;printf("Format FirstSymbol wrong!\n");system("Pause");}else{StringTypeLine.Firstsymbolis=DATA_Ture;}if(strlen(src)<11){//字符串長(zhǎng)度小于11printf("Format length wrong!\n");system("Pause");}else{StringTypeLine.StringSizeis=DATA_Flase;}if(strcmp(src,resultString)==0){//結(jié)束標(biāo)志StringTypeLine.StringResultis=DATA_Ture;printf("End of file\n");}else{StringTypeLine.StringResultis=DATA_Flase;}if(src.right(2)!= AnalyseHEX(src)) //字符效驗(yàn){StringTypeLine.StringCrcis=DATA_Flase; //字符效驗(yàn)失敗printf("\nSerialcount is wrong in Address=%d\n",count_num);printf("XiaoYan_cc:%c%c\n",*src.right(2).data(),*(src.right(2).data()+1));printf("\nXiaoYan_calcu_int:%d\n",AnalyseHEX(src).toInt());printf("XiaoYan_read_int:%d\n",HexToDec(src.right(2).data())); //讀出來(lái)的效驗(yàn)值system("Pause"); //如果效驗(yàn)值錯(cuò)誤,暫停界面}else{StringTypeLine.StringCrcis=DATA_Ture; //字符效驗(yàn)正確//printf("\nFormat Effect Vaild!!!!!\n");while(mystrlen(src)-2>pq) //打印完所有的數(shù)據(jù){QString st = src.mid(pq,2);pq+=2;printf("%c%c ",*st.toLatin1().data(),*(st.toLatin1().data()+1));}}/****判斷數(shù)據(jù)類型****/QString stringtype = src.mid(7,2);//printf("\nstringtype: %c%c\n",*stringtype.toLatin1().data(),*(stringtype.toLatin1().data()+1));if(stringtype==HexTypeTable[RECORD_DATA]){ //00正常數(shù)據(jù)類型StringTypeLine.StringType=RECORD_DATA;QString styadd = src.mid(3,4);/****只是分割字符串****/// printf("styadd:%c%c%c%c\n",*styadd.toLatin1().data(),*(styadd.toLatin1().data()+1),*(styadd.toLatin1().data()+2),*(styadd.toLatin1().data()+3));}else if (stringtype==HexTypeTable[RECORD_END_OF_FILE]){ //01 用來(lái)標(biāo)識(shí)文件結(jié)束StringTypeLine.StringType=RECORD_END_OF_FILE;printf("RECORD_END_OF_FILE\n ");}else if (stringtype==HexTypeTable[RECORD_EXTENDED_LINEAR_ADDRESS]) //TODO:只需要判斷一次{ //04 擴(kuò)展線性地址記錄StringTypeLine.StringType=RECORD_EXTENDED_LINEAR_ADDRESS;printf("RECORD_EXTENDED_LINEAR_ADDRESS \n");QString styadd = src.mid(3,4);QString styaddsub = src.mid(9,4); //字符串拼接styadd.insert(0,styaddsub);//printf("StyaddSub04:%c%c%c%c%c%c%c%c\n",*styadd.toLatin1().data(),*(styadd.toLatin1().data()+1),// *(styadd.toLatin1().data()+2),*(styadd.toLatin1().data()+3),*(styadd.toLatin1().data()+4),*(styadd.toLatin1().data()+5),*(styadd.toLatin1().data()+6),*(styadd.toLatin1().data()+7));//system("Pause");}else if(stringtype==HexTypeTable[RECORD_EXTENDED_SEGMENT_ADDRESS]){ //02 擴(kuò)展段地址記錄StringTypeLine.StringType=RECORD_EXTENDED_SEGMENT_ADDRESS;printf("RECORD_EXTENDED_SEGMENT_ADDRESS\n");}else if(stringtype==HexTypeTable[RECORD_START_LINEAR_ADDRESS]){ //05 開(kāi)始線性地址記錄StringTypeLine.StringType=RECORD_START_LINEAR_ADDRESS;printf("RECORD_START_LINEAR_ADDRESS\n");}else if(stringtype==HexTypeTable[RECORD_START_SEGMENT_ADDRESS]){ //03 開(kāi)始段地址記錄StringTypeLine.StringType=RECORD_START_SEGMENT_ADDRESS;printf("RECORD_START_SEGMENT_ADDRESS\n");system("Pause"); //如果遇到03則暫停,預(yù)留處理03的代碼 (0613/還未遇到)}return StringTypeLine; }/******判斷基地址**如果數(shù)據(jù)類型為04調(diào)用*******/ QString BaseAddjudge(QByteArray src) {QString resultBaseAddres;QString stringtype = src.mid(7,2); /****判斷數(shù)據(jù)類型****/if (stringtype==HexTypeTable[RECORD_EXTENDED_LINEAR_ADDRESS]) //TODO:只需要判斷一次RECORD_EXTENDED_LINEAR_ADDRESS{ //04 擴(kuò)展線性地址記錄QString styadd = src.mid(3,4);QString styaddsub = src.mid(9,4); //字符串拼接styadd.insert(0,styaddsub);printf("StyaddSub04:%c%c%c%c%c%c%c%c\n",*styadd.toLatin1().data(),*(styadd.toLatin1().data()+1),*(styadd.toLatin1().data()+2),*(styadd.toLatin1().data()+3),*(styadd.toLatin1().data()+4),*(styadd.toLatin1().data()+5),*(styadd.toLatin1().data()+6),*(styadd.toLatin1().data()+7));return styadd;}if (stringtype==HexTypeTable[RECORD_EXTENDED_SEGMENT_ADDRESS]) //TODO:只需要判斷一次RECORD_EXTENDED_LINEAR_ADDRESS{ //02 擴(kuò)展段地址記錄QString Basezer0 = "0000";QString styaddsub = src.mid(9,4); //字符串拼接Basezer0.insert(4,styaddsub);Basezer0=QStringLeftBit(Basezer0,1);printf("StyaddSub02:%c%c%c%c%c%c%c%c\n",*Basezer0.toLatin1().data(),*(Basezer0.toLatin1().data()+1),*(Basezer0.toLatin1().data()+2),*(Basezer0.toLatin1().data()+3),*(Basezer0.toLatin1().data()+4),*(Basezer0.toLatin1().data()+5),*(Basezer0.toLatin1().data()+6),*(Basezer0.toLatin1().data()+7));return Basezer0; //在02數(shù)據(jù)類型的方式下需要左移一位}return resultBaseAddres; }/****新字符串拼接*****/ QString FormatTranQARRYbyte(QByteArray src) {char count=9;char newcount=10;QString ResultDate;static QString resultBaseAddress="00000000"; //static 修飾只初始化一次 //0x08000000QString space=" ";StringTypeLine=FormatHexjudge(src);if(StringTypeLine.StringCrcis==DATA_Ture) //如果效驗(yàn)碼正確{if(StringTypeLine.StringType==RECORD_EXTENDED_LINEAR_ADDRESS) //如果是擴(kuò)展性數(shù)據(jù)類型 04{resultBaseAddress=BaseAddjudge(src); //接收擴(kuò)展地址qDebug()<<"resultBaseAddress"<<resultBaseAddress;}if(StringTypeLine.StringType==RECORD_EXTENDED_SEGMENT_ADDRESS) //如果是段數(shù)據(jù)類型 02{resultBaseAddress=BaseAddjudge(src);qDebug()<<"resultBaseAddress"<<resultBaseAddress;}ResultDate=resultBaseAddress; //第一個(gè)是地址ResultDate=QStringToAdd(ResultDate,src.mid(3,4)); //基地址和絕對(duì)地址相加if(StringTypeLine.Firstsymbolis==DATA_Ture) //如果字符串的第一個(gè)符號(hào)是“:”{ResultDate.insert(8,src.left(1)); //插入符號(hào)ResultDate.insert(9,space);}while(mystrlen(src)-2>count) //打印完所有的數(shù)據(jù){ResultDate.insert(newcount,src.mid(count,2));newcount=newcount+3;ResultDate.insert(newcount,space);count=count+2;}if(StringTypeLine.StringType==RECORD_DATA) //當(dāng)數(shù)據(jù)類型為00的時(shí)候才打印{printf("\n");qDebug()<<"ResultDate "<<ResultDate<<endl<<endl<<endl;}}return ResultDate; }#if 0 /***按行讀取HEX文件并進(jìn)行處理*****/ void read(QString filename){QFile file(filename);if(!file.open(QFile::ReadOnly | QFile::Text)){qDebug() << " Could not open the file for reading";return;}QTextStream in(&file);while(!in.atEnd()){QString myText = in.readLine();QString str(myText);QByteArray bytes = str.toLatin1(); //Qstring 轉(zhuǎn) QByteArrayqDebug() << bytes;FormatTranQARRYbyte(bytes);printf("\n\n\n");}file.close();}/***按行讀取HEX文件并進(jìn)行處理*****/ void Write(QString filename) {QFile file(filename);if(!file.open(QFile::WriteOnly | QFile::Text)){qDebug() << " Could not open the file for reading";return;}//QTextStream stream(&file);//stream.seek(file.size());QString resultString=":00000001FF\n";QString EnterResul="\n";QByteArray AER=":10246200464c5549442050524f46494c4500464c33";file.write(FormatTranQARRYbyte(AER).toUtf8());file.write(EnterResul.toUtf8());file.write(resultString.toUtf8());file.close();return; } #endif/***按行讀取HEX文件并進(jìn)行處理*****/ void ReadWrite(QString filenameread,QString filenameWrite){QString EnterResul="\n";QFile fileread(filenameread);if(!fileread.open(QFile::ReadOnly | QFile::Text)){qDebug() << " Could not open the file for reading";return;}QFile filewrite(filenameWrite);if(!filewrite.open(QFile::WriteOnly | QFile::Text)){qDebug() << " Could not open the file for reading";return;}QTextStream in(&fileread);while(!in.atEnd()){QString myText = in.readLine();QString str(myText);QByteArray bytes = str.toLatin1(); //Qstring 轉(zhuǎn) QByteArrayqDebug() << bytes;QString ResultText;ResultText=FormatTranQARRYbyte(bytes);if(StringTypeLine.StringType==RECORD_DATA) //只將數(shù)據(jù)類型為 00 的字符串寫(xiě)入{filewrite.write(ResultText.toUtf8()); //寫(xiě)入數(shù)據(jù)filewrite.write(EnterResul.toUtf8()); //寫(xiě)入回車}printf("\n");}fileread.close();filewrite.close();}/**0613生成成功**/ int main() {QString filename = "C:/Users/Administrator/Desktop/HEX2/VCU_S32K14X.hex";//QString filename = "C:/Users/Administrator/Desktop/HEX2/Projec.hex";QString filewritename = "C:/Users/Administrator/Desktop/HEX2/Pro1.hex";//QByteArray AER=":020000040800F2";// QByteArray AER=":105CC00010831C46234618465DF8044B704708B500";//FormatTranQARRYbyte(AER);ReadWrite(filename,filewritename);}

C#語(yǔ)言
頭文件

#ifndef CHEX_H #define CHEX_H#include <QFile>const quint8 MIN_HEX_LINE_COUNT_LENGHT = 12;typedef enum __tagHexErrorCode {HEX_NO_ERROR = 0,HEX_FORMAT_ERROR,HEX_VERIFY_ERROR,HEX_LENGHT_ERROR,HEX_USERPAPR_EEROR, }EHexErrorCode;typedef enum __tagHexType {RECORD_DATA = 0,RECORD_END_OF_FILE,RECORD_EXTENDED_SEGMENT_ADDRESS,RECORD_START_SEGMENT_ADDRESS,RECORD_EXTENDED_LINEAR_ADDRESS,RECORD_START_LINEAR_ADDRESS,RECORD_HEX_MAX, }emHexType;typedef struct __tagHexLineData {emHexType type;quint8 count;quint32 address;quint8 data[80];quint8 checksum;quint8 datalen; }stHexLineData;class CHex { public:CHex();EHexErrorCode getHexLineData(QByteArray bydata,stHexLineData *p); private:char ConvertHexChar(char ch); };#endif // CHEX_H

源文件

#include "chex.h"const QString HexTypeTable[6] = {"00","01","02","03","04","05", };CHex::CHex() {}char CHex::ConvertHexChar(char ch) {if((ch >= '0') && (ch <= '9'))return (ch-0x30);else if((ch >= 'A') && (ch <= 'F'))return ((ch-'A')+10);else if((ch >= 'a') && (ch <= 'f'))return ((ch-'a')+10);else return (-1); }EHexErrorCode CHex::getHexLineData(QByteArray bydata,stHexLineData *p) {quint8 i = 0;quint8 cs_temp = 0;QString str(bydata);char *pcdata = bydata.data();quint32 linelen = str.size();if((linelen < MIN_HEX_LINE_COUNT_LENGHT)) {return HEX_LENGHT_ERROR;}if(*pcdata != 0x3A) {return HEX_FORMAT_ERROR;}//必須以":"號(hào)開(kāi)始//獲取TypeQString stype = str.mid(7,2);for(i = 0; i < RECORD_HEX_MAX; i++){if(stype == HexTypeTable[i]){p->type = (emHexType)i;break;}}if(i == RECORD_HEX_MAX) {qDebug("HEX_FORMAT_ERROR");return HEX_FORMAT_ERROR;}cs_temp += (ConvertHexChar(*(pcdata + 7)) << 4) | ConvertHexChar(*(pcdata + 8));//獲取countp->count = (ConvertHexChar(*(pcdata + 1)) << 4) | ConvertHexChar(*(pcdata + 2));cs_temp += p->count;if(p->count != (((linelen - 2) / 2) - 5)) {qDebug("HEX_FORMAT_ERROR");return HEX_FORMAT_ERROR;}//獲取addressp->address = (ConvertHexChar(*(pcdata + 3)) << 12) | (ConvertHexChar(*(pcdata + 4)) << 8) | (ConvertHexChar(*(pcdata + 5)) << 4) | ConvertHexChar(*(pcdata + 6));cs_temp += (p->address >> 8) & 0xFF;cs_temp += p->address & 0xFF;//獲取datafor(i = 0; i < p->count; i++){p->data[i] = (ConvertHexChar(*(pcdata + 2*i + 9)) << 4) | ConvertHexChar(*(pcdata + 2*i + 10));cs_temp += p->data[i];}p->checksum = (ConvertHexChar(*(pcdata + 2*i + 9)) << 4) | ConvertHexChar(*(pcdata + 2*i + 10));if(p->checksum != ((0x100 - cs_temp) & 0xFF)){qDebug("HEX_VERIFY_ERROR");return HEX_VERIFY_ERROR;}p->datalen = p->count;return HEX_NO_ERROR; }

總結(jié)

以上是生活随笔為你收集整理的HEX文件格式解析(转)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。