将HEX文件读写成地址加数据的格式,HEX文件格式可以参考
https://blog.csdn.net/a1037488611/article/details/43340055
文档中有关与效验算法方面的有点问题,可以参考本人效验代码
以下是我在Qt上实现的完整代码
#include<stdio.h>
#include<stdlib.h>
#include<QDebug>
#include<QString>
#include<QByteArray>
#include<QDebug>
#include<QFile>
#include<QDataStream>
static char pq=9; //规范代码
/****16进制的数据类型*****/
const QString HexTypeTable[6] =
{
"00","01","02","03","04","05",
};
/****配套数据类型使用的枚举变量*****/
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}; //定义字符串的类型格式
/****函数声明*********/
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);
/****计算字符串长度*****/
int mystrlen(const char *StrDest)
{
int i;
i=0;
while((*StrDest++)!='\0')
{
i++;
}//这个循环体意思是从字符串第一个字符起计数,只遇到字符串结束标志'\0’才停止计数
return i;
}
/****16进制转换10进制*****/
int HexToDec(char *src)
{
//将src中的无符号十六进制字符串转为十进制数
//如src="001A",则返回26
//字符串src需要以'\0'作为结束标志
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;//返回转换后的数值
}
/****字符串效验*返回效验的十进制数用来与字符串后两位做比较****/
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); //转换成10进制运算后,再转换成十六进制
printf(" %d",HexToDec(stype.toLatin1().data()));
tempsum+=HexToDec(stype.toLatin1().data());
i+=2;
} while (i<(mystrlen(dest)-2));
/***HEX计算公式(0x100-(16进制数据和后两位))再取后两位=字符串后两位*****/
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*****字符串以十六进制的形式转换成十进制相加,然后转换成十六进制的字符串形式输出*****/
QString QStringToAdd(QString dest,QString src)
{
QString ResultDate;
QString ZERO="0";
int num1,num2,ans;
int count;
bool ok;
num1=dest.toInt(&ok,16); //转换成10进制
num2=src.toInt(&ok,16);
ans=num1+num2;
ResultDate=QString::number(ans,16);
/**判断结果字符串与输入的两个字符串的最大差值,用于给结果字符串补零***/
(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();//十进制转换成Qstring的形式输出 toUpper() //转换成大写字母
}
/****文件格式类型判断,有错误打印,返回值为基地址******/
StringType FormatHexjudge(QByteArray src) //QString *resultBaseAddres
{
QByteArray resultString=":00000001FF";
static uint32_t count_num=0;
count_num++;
/******验证一下传入的数据***********/
char *pcdata = src.data();
//printf("Length of src:%d\n",mystrlen(src)); //打印传入数据大小
while(*pcdata)
{
//printf("%c",*pcdata); //打印原始数据
++pcdata;
}
//printf("\n");
if(src.left(1)!=":")
{//不是以":"开始
StringTypeLine.Firstsymbolis=DATA_Flase;
printf("Format FirstSymbol wrong!\n");
system("Pause");
}
else
{
StringTypeLine.Firstsymbolis=DATA_Ture;
}
if(strlen(src)<11)
{//字符串长度小于11
printf("Format length wrong!\n");
system("Pause");
}
else
{
StringTypeLine.StringSizeis=DATA_Flase;
}
if(strcmp(src,resultString)==0)
{//结束标志
StringTypeLine.StringResultis=DATA_Ture;
printf("End of file\n");
}
else
{
StringTypeLine.StringResultis=DATA_Flase;
}
if(src.right(2)!= AnalyseHEX(src)) //字符效验
{
StringTypeLine.StringCrcis=DATA_Flase; //字符效验失败
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())); //读出来的效验值
system("Pause"); //如果效验值错误,暂停界面
}
else
{
StringTypeLine.StringCrcis=DATA_Ture; //字符效验正确
//printf("\nFormat Effect Vaild!!!!!\n");
while(mystrlen(src)-2>pq) //打印完所有的数据
{
QString st = src.mid(pq,2);
pq+=2;
printf("%c%c ",*st.toLatin1().data(),*(st.toLatin1().data()+1));
}
}
/****判断数据类型****/
QString stringtype = src.mid(7,2);
//printf("\nstringtype: %c%c\n",*stringtype.toLatin1().data(),*(stringtype.toLatin1().data()+1));
if(stringtype==HexTypeTable[RECORD_DATA])
{ //00正常数据类型
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 用来标识文件结束
StringTypeLine.StringType=RECORD_END_OF_FILE;
printf("RECORD_END_OF_FILE\n ");
}
else if (stringtype==HexTypeTable[RECORD_EXTENDED_LINEAR_ADDRESS]) //TODO:只需要判断一次
{ //04 扩展线性地址记录
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 扩展段地址记录
StringTypeLine.StringType=RECORD_EXTENDED_SEGMENT_ADDRESS;
printf("RECORD_EXTENDED_SEGMENT_ADDRESS\n");
}
else if(stringtype==HexTypeTable[RECORD_START_LINEAR_ADDRESS])
{ //05 开始线性地址记录
StringTypeLine.StringType=RECORD_START_LINEAR_ADDRESS;
printf("RECORD_START_LINEAR_ADDRESS\n");
}
else if(stringtype==HexTypeTable[RECORD_START_SEGMENT_ADDRESS])
{ //03 开始段地址记录
StringTypeLine.StringType=RECORD_START_SEGMENT_ADDRESS;
printf("RECORD_START_SEGMENT_ADDRESS\n");
system("Pause"); //如果遇到03则暂停,预留处理03的代码 (0613/还未遇到)
}
return StringTypeLine;
}
/******判断基地址**如果数据类型为04调用*******/
QString BaseAddjudge(QByteArray src)
{
QString resultBaseAddres;
QString stringtype = src.mid(7,2); /****判断数据类型****/
if (stringtype==HexTypeTable[RECORD_EXTENDED_LINEAR_ADDRESS]) //TODO:只需要判断一次RECORD_EXTENDED_LINEAR_ADDRESS
{ //04 扩展线性地址记录
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 扩展段地址记录
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数据类型的方式下需要左移一位
}
return resultBaseAddres;
}
/****新字符串拼接*****/
QString FormatTranQARRYbyte(QByteArray src)
{
char count=9;
char newcount=10;
QString ResultDate;
static QString resultBaseAddress="00000000"; //static 修饰只初始化一次 //0x08000000
QString space=" ";
StringTypeLine=FormatHexjudge(src);
if(StringTypeLine.StringCrcis==DATA_Ture) //如果效验码正确
{
if(StringTypeLine.StringType==RECORD_EXTENDED_LINEAR_ADDRESS) //如果是扩展性数据类型 04
{
resultBaseAddress=BaseAddjudge(src); //接收扩展地址
qDebug()<<"resultBaseAddress"<<resultBaseAddress;
}
if(StringTypeLine.StringType==RECORD_EXTENDED_SEGMENT_ADDRESS) //如果是段数据类型 02
{
resultBaseAddress=BaseAddjudge(src);
qDebug()<<"resultBaseAddress"<<resultBaseAddress;
}
ResultDate=resultBaseAddress; //第一个是地址
ResultDate=QStringToAdd(ResultDate,src.mid(3,4)); //基地址和绝对地址相加
if(StringTypeLine.Firstsymbolis==DATA_Ture) //如果字符串的第一个符号是“:”
{
ResultDate.insert(8,src.left(1)); //插入符号
ResultDate.insert(9,space);
}
while(mystrlen(src)-2>count) //打印完所有的数据
{
ResultDate.insert(newcount,src.mid(count,2));
newcount=newcount+3;
ResultDate.insert(newcount,space);
count=count+2;
}
if(StringTypeLine.StringType==RECORD_DATA) //当数据类型为00的时候才打印
{
printf("\n");
qDebug()<<"ResultDate "<<ResultDate<<endl<<endl<<endl;
}
}
return ResultDate;
}
#if 0
/***按行读取HEX文件并进行处理*****/
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 转 QByteArray
qDebug() << bytes;
FormatTranQARRYbyte(bytes);
printf("\n\n\n");
}
file.close();
}
/***按行读取HEX文件并进行处理*****/
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文件并进行处理*****/
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 转 QByteArray
qDebug() << bytes;
QString ResultText;
ResultText=FormatTranQARRYbyte(bytes);
if(StringTypeLine.StringType==RECORD_DATA) //只将数据类型为 00 的字符串写入
{
filewrite.write(ResultText.toUtf8()); //写入数据
filewrite.write(EnterResul.toUtf8()); //写入回车
}
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);
}
以下为Notepad++打开的原Hex文件
经过代码(以上代码C语言)读取生成的文件
通过软件转换的文件