一:前言
在实际开发过程中,经常需要对固件文件转换、修改、删除等工作。对于优秀工程师遇事不求人的原则,当然需要自己开发工具或脚本实现转换。在实际开发过程中有遇到生成的固件文需要加密、增加文件校验码等内容。这种任务最好做成脚本,通过编译器的后处理命令行实现加工。“Post-build command line”本文实现固件文件行长度修改作为一个抛砖引玉。
二:上位机界面
对应固件文件的解析请看:
固件解析-S19文件:固件解析-S19文件-CSDN博客
固件解析-HEX文件:
本文是对这上述的实际使用:
两个按键实现的内容如下。
//文件选择获取文件路径并显示在前面编辑框内。
void MainWindow::on_GetFile_clicked()
{
QString qstr = QFileDialog::getOpenFileName(this,"open file dialog","/","S19 Files(*.s19);;hex Files(*.hex)");
ui->lineEdit->setText(qstr);
}
//创建文件
//1:根据选择的文件的后缀自动识别文件类型,
//2:调用文件解析获取文件数据
//3:根据用户选择单行数据长度对文件创建
void MainWindow::on_CreateFile_clicked()
{
QString suffix;
S19Parse S19;
HexParse hex;
int lenght;
QString qstr = ui->lineEdit->text();
lenght = ui->comboBox->currentText().toInt();
if(lenght>0 && (!qstr.isEmpty()))
{
suffix = qstr.right(3);
suffix = suffix.toUpper();//大写
if(suffix=="S19")
{
QList<S19RecordBlock> hexBlockList;
int ret = S19.ParseFile(qstr, hexBlockList);
if(ret == 0)
{
//
qstr += ".s19";
ui->lineEdit_2->setText(qstr);
S19.CreateFile(qstr,hexBlockList,lenght);
}
else
{
qDebug()<<"ret="<<ret;
QMessageBox::information(NULL, "错误", "文件内容有错误");
}
}
else if(suffix=="HEX")
{
QList<HexRecordBlock> hexBlockList;
int ret = hex.ParseFile(qstr, hexBlockList);
if(ret == 0)
{
qstr += ".hex";
ui->lineEdit_2->setText(qstr);
hex.CreateFile(qstr,hexBlockList,lenght);
}
else
{
qDebug()<<"ret="<<ret;
QMessageBox::information(NULL, "错误", "文件内容有错误");
}
}
}
}
三:固件文件创建
3.1:Hex文件创建:
int HexParse::CreateFile(QString path, QList<HexRecordBlock> BlockList ,int lineNumber)
{
QString HLineStr;
QByteArray HLineArray;
QByteArray HLine;
unsigned int ExtendedAddr = 0xffffff;
unsigned int address;
unsigned int highAdr;
unsigned int lowAdr;
int count;
char ChSum;
QFile aFile(path);
// if (!aFile.exists()) //文件不存在
// return -1;
if (!aFile.open(QIODevice::WriteOnly | QIODevice::Text)) //打开失败
return -2;
//RECORD MARK":"(1) + LENGTH(1) + LOAD OFFSET(2) + RECTYPE(1) + INFO or DATA(n) + CHKSUM(1)
for(int i = 0;i<BlockList.size();i++)
{
HLineArray = BlockList.at(i).data;
address = BlockList.at(i).address;
count = HLineArray.size();
while(count)
{
highAdr = address>>16;//高地址
lowAdr = address&0xffff;
if(highAdr != ExtendedAddr)
{
ExtendedAddr = highAdr;
//需要添加 用来标识扩展线性地址的记录
//:02 0000 04 xx xx cc
HLine.clear();
HLineStr = ":";
HLine.append((char)2);
HLine.append((char)0);
HLine.append((char)0);
HLine.append((char)4);
HLine.append((char)(ExtendedAddr>>8));
HLine.append((char)(ExtendedAddr&0xff));
ChSum = checkSum(HLine);
HLine.append(ChSum);
HLineStr += HLine.toHex();
HLineStr = HLineStr.toUpper(); //大写
HLineStr +="\n";
aFile.write(HLineStr.toLatin1());
}
if(count > lineNumber)
{
count = lineNumber;
}
if(lowAdr+count>0x10000)
{
count = 0x10000 - lowAdr;
}
HLine.clear();
HLineStr = ":";
HLine.append((char)(count&0xff));
HLine.append((char)(lowAdr>>8));
HLine.append((char)(lowAdr&0xff));
HLine.append((char)0);
HLine += HLineArray.mid(0,count); //数据
ChSum = checkSum(HLine);
HLine.append(ChSum);
HLineStr += HLine.toHex();
HLineStr = HLineStr.toUpper(); //大写
HLineStr +="\n";
aFile.write(HLineStr.toLatin1());
HLineArray.remove(0,count);
address += count;
count = HLineArray.size();
};
}
if(UpperLinearBaseAddress.size()>0)
{
aFile.write(UpperLinearBaseAddress);
}
HLineStr = ":00000001FF";
HLineStr +="\n";
aFile.write(HLineStr.toLatin1());
aFile.close();
return 0;
}
3.2:S19文件创建:
int S19Parse::CreateFile(QString path, QList<S19RecordBlock> BlockList ,int lineNumber)
{
QString HLineStr;
QByteArray HLineArray;
QByteArray HLine;
unsigned int address;
int count;
char ChSum;
QFile aFile(path);
// if (!aFile.exists()) //文件不存在
// return -1;
if (!aFile.open(QIODevice::WriteOnly | QIODevice::Text)) //打开失败
return -2;
if(HeadLineStr.size()==0)
{
HLineStr = "S010000051413230335F4170702E7331393D";
HLineStr +="\n";
aFile.write(HLineStr.toLatin1());
}else
{
aFile.write(HeadLineStr.toLatin1());
}
for(int i = 0;i<BlockList.size();i++)
{
HLineArray = BlockList.at(i).data;
address = BlockList.at(i).address;
count = HLineArray.size();
while(count)
{
if(count > lineNumber)
{
count = lineNumber;
}
if(address+count<=0x10000)
{
HLineStr = "S1";
HLine = StrAdrr_Front(count+2+1,1); //1字节长度
HLine += StrAdrr_Front(address,2); //3个地址
}else if(address+count<=0x1000000)
{
HLineStr = "S2";
HLine = StrAdrr_Front(count+3+1,1); //1字节长度
HLine += StrAdrr_Front(address,3); //3个地址
}
else
{
HLineStr = "S3";
HLine = StrAdrr_Front(count+4+1,1); //1字节长度
HLine += StrAdrr_Front(address,4); //3个地址
}
HLine += HLineArray.mid(0,count); //数据
ChSum = checkSum(HLine);
HLine.append(ChSum); //校验
HLineStr += HLine.toHex();
HLineStr = HLineStr.toUpper(); //大写
HLineStr +="\n";
aFile.write(HLineStr.toLatin1());
HLineArray.remove(0,count);
address += count;
count = HLineArray.size();
};
}
if(TailLineStr.size()==0)
{
HLineStr = "S7050800A82921";
HLineStr +="\n";
aFile.write(HLineStr.toLatin1());
}else
{
aFile.write(TailLineStr.toLatin1());
}
aFile.close();
return 0;
}