概要
本文档通过QT,调用jlink.exe 实现对Flash的自定义操作吗,例如对某个特定位置的读写修改或者其他操作。
程序主要是通过QT调用jlink.exe,依据jlink command的相关命令完成。
技术细节
` QT 主要通过调用外部的可执行程序,相关函数为
QProcess process;
QString programPath;
QStringList arguments;
process.start(programPath, arguments);
其中,programPath是可执行程序的位置。arguments是调用时的参数。
以cmd.exe 为例,arguments可以为直接运行的命令,例如:ipconfig,会打印出对应的数据。但是,jlink存在例外的情况,当我们直接输入命令,例如:jlink.exe中的connect命令,到arguments时,会出现以下的错误提示:
Unknown command line option connect
所以,不能直接将arguments设置为直接的命令,后面,发现需要通过脚本的方式进行命令下发,即如下的形式:
arguments << “-CommanderScript” << “script.txt”;通过这样的方式,就可以正常调用和下发命令。
script.txt的内容需要参考jlink command的相关命令,去了解相关命令的含义和左右。作者采用的相关命令如下
si 1
speed 4000
device -AT32F403AVGT7
r
h
erase
loadbin xxx.bin 0x8000000
q
烧录过程
后续的功能需求,通过修改script.txt中的内容即可完成。
主要代码如下:
执行jlink.exe调用
programPath=ui->lineEdit->text();
// 设置要执行的外部程序的路径和参数
QString script=ui->lineEdit_6->text();
arguments << "-CommanderScript" << script;
// 启动外部程序
process.start(programPath, arguments);
// 等待外部程序执行完成
process.waitForFinished();
// 获取外部程序的输出结果
QByteArray output = process.readAllStandardOutput();
QString outputString(output);
// 打印输出结果
qDebug() << "Output:" << outputString;
print_log(outputString);
QString info="<font color=\"#00FF00\">烧录完成</font> ";
qDebug()<<info;
print_log(info);
生成script.txt文件
QDateTime local(QDateTime::currentDateTime());
QString FileName ="./Script//"+local.toString("hh_mm_ss_")+ui->lineEdit->text()+"_modified.txt";
QFile file12(FileName);
bool bret1=file12.open(QIODevice::ReadWrite|QIODevice::Text|QIODevice::Append);
QTextStream out1(&file12);
if(!bret1)
{
//在sut 需要增加messagebox
qDebug()<<FileName+file12.errorString();
QMessageBox::warning(this, tr("警告!"),
FileName+file12.errorString(),
QMessageBox::Yes);
}
out1<<"si 1\n";//固定,后续优化
out1<<"speed 4000\n";//新固定,后续优化
out1<<("device -"+ui->lineEdit->text()+"\n");//固定,后续优化
out1<<"r\n";//固定,后续优化
out1<<"h\n";//固定,后续优化
out1<<("w1 "+ui->lineEdit_2->text()+" "+ui->lineEdit_3->text()+"\n");
out1<<"q\n";//固定,后续优化
file12.close();
可以根据需求,将txt生成在需要的位置
新增的界面和逻辑的修改:
由于是针对特定芯片和特定工程的烧录上位机,需要通过一个头文件形式的配置文件传入参数,例如存储区域大小和存储位置(不再需要手动输入)生成相关的烧录文件后,只需要选择对应的芯片文件即可进行烧录工作。
目前,只支持Jlink烧录,后续会加入串口烧录等。
可以通过下拉框选择对应的芯片型号,不过这个需要自己在文件夹中进行添加,位于./Config//Device.txt。然后需要选择Jlink.exe的地址,选择自己定义的配置文件,这个需要自己重新编写解析函数定义模板。
选中文件后,会自动根据选中的芯片,进行连接
进入配置界面,如果连接成功,会读取当前地址的值,并显示在最后一栏,连接失败,展示默认值。这个界面的值跟传入的配置文件是对应的,需要根据对应的配置文件重新编写解析的函数。
我使用的配置文件格式如下:#define(一个空格)IAP_AddreSize(4个空格)(0x10101) x小写,主要通过//#进行字符串匹配,获取地址,不直接采用宏的原因是 后面的结构体内容不好直接调用。
结构体中的某一项,主要是进行重新定义,通过//@进行匹配,然后 成员名 bool(主要是通过combobox进行选择)所以类似2选一,对于数值,我使用string,在表格中 对于lineedit进行填入。后面的 1 表示这一项一个字节,2 表示有两个可能的取值,最后 0x01 表示最大的一个取值(这个需要进一步优化,不好处理离散量对于combobox的初始化),连续量的话,知道取值个数和最大值就好初始化了。
这个,n表示不确定输入长度,对应lineedit,可能需要我们手动填充的类型。
修改完对应的值后,点击烧录按钮,执行即可。
对应的生成文件为:
分别对应配置文件,log文件(版本记录),和执行的脚本文件
小结
具体代码已上传,环境为QT6.5.3 MSVC2019 64bit