代码拉取完成,页面将自动刷新
同步操作将从 yuyaowen/stlink_burn_tool 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "launch.h"
#include <QSettings>
#include <QFileDialog>
#include <QStandardPaths>
#include <QTextCodec>
#include <QMessageBox>
#include <QLabel>
#include <QCryptographicHash>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->statusBar->addPermanentWidget(new QLabel("Ver:"+QString(__DATE__ "_" __TIME__)));
ui->progressBar->setStyleSheet("QProgressBar::chunk { background-color: #10ff10; width: 20px;}");
// 获取配置文件中板子的名称,更新到ui
QSettings configFile(configFilePath, QSettings::IniFormat);
configFile.setIniCodec(QTextCodec::codecForName("UTF-8"));
configFile.beginGroup("Global");
factoryMode = configFile.value("factory").toBool();
QString lastBoard=configFile.value("last_selected_board").toString();
configFile.endGroup();
QStringList sections = configFile.childGroups();
foreach(QString item, sections)
{
if (item.endsWith("Board"))
{
configFile.beginGroup(item);
QString boardName = configFile.value("NAME").toString();
configFile.endGroup();
ui->boardComboBox->addItem(boardName);
}
}
if (!lastBoard.isEmpty())
{
ui->boardComboBox->setCurrentText(lastBoard);
}
/* 生成update flag文件 */
QFile needUpdateFlag(firmwareDir + curNeedUpdateFlag);
needUpdateFlag.open(QIODevice::WriteOnly | QIODevice::Truncate);
QDataStream out(&needUpdateFlag);
out << static_cast<qint64>(0xffffffffb66bb66b);
needUpdateFlag.close();
QFile updateFlag(firmwareDir + curUpdateFlag);
updateFlag.open(QIODevice::WriteOnly | QIODevice::Truncate);
QDataStream out1(&updateFlag);
out1 << static_cast<qint64>(0xc77cc77cb66bb66b);
updateFlag.close();
ui->imageLabel->setHidden(true);
if (factoryMode) // 工厂模式
{
/* 不该显示的按钮藏起来 */
ui->burnIFlashPushButton->setHidden(true);
ui->burnEFlashPushButton->setHidden(true);
ui->eraseIFlashPushButton->setHidden(true);
ui->eraseEFlashPushButton->setHidden(true);
/* 修改刷机按钮样式 */
ui->burnAllPushButton->setFixedSize(522, 34);
ui->burnAllPushButton->setText("烧写程序");
/* 用图片盖住各选项 */
ui->imageLabel->raise();
ui->imageLabel->setHidden(false);
Launch la;
la.exec();
ui->boardComboBox->setCurrentText(la.getBoardName());
}
}
MainWindow::~MainWindow()
{
QSettings configFile(configFilePath, QSettings::IniFormat);
configFile.setIniCodec(QTextCodec::codecForName("UTF-8"));
configFile.beginGroup("Global");
configFile.setValue("last_selected_board", ui->boardComboBox->currentText());
configFile.endGroup();
QFile(firmwareDir + defaultBkpPara).remove();
QFile(firmwareDir + curUpdateFlag).remove();
QFile(firmwareDir + curNeedUpdateFlag).remove();
delete ui;
}
QString MainWindow::findSectionByName(const QString &boardName)
{
QSettings configFile(configFilePath, QSettings::IniFormat);
configFile.setIniCodec(QTextCodec::codecForName("UTF-8"));
QStringList sections = configFile.childGroups();
foreach (QString item, sections)
{
configFile.beginGroup(item);
if (configFile.value("NAME").toString() == boardName)
{
configFile.endGroup();
return item;
}
configFile.endGroup();
}
return nullptr;
}
QString MainWindow::findKeyByValue(const QString §ion, const QString &value)
{
QSettings configFile(configFilePath, QSettings::IniFormat);
configFile.setIniCodec(QTextCodec::codecForName("UTF-8"));
configFile.beginGroup(section);
QStringList keyList = configFile.allKeys();
foreach(QString key, keyList)
{
if (configFile.value(key).toString() == value)
{
return key;
}
}
configFile.endGroup();
return nullptr;
}
int MainWindow::burnExternFlash(QString filePath, QString loaderPath, QString offset)
{
QStringList param;
param.append("-P");
param.append(filePath);
param.append(offset);
param.append("-V");
param.append("after_programming");
param.append("-EL");
param.append(loaderPath);
param.append("-Rst");
param.append("-Q");
cliProcessInternal.start(stlinkPath, param);
cliProcessInternal.waitForStarted();
cliProcessInternal.waitForFinished(15000);
return judgeConnectionError(cliProcessInternal.readAll());
}
int MainWindow::eraseExternFlash(QString loaderPath)
{
QStringList param;
param.append("-c");
param.append("SWD");
param.append("UR");
param.append("-ME");
param.append("-EL");
param.append(loaderPath);
param.append("-Rst");
param.append("-Q");
cliProcessInternal.start(stlinkPath, param);
cliProcessInternal.waitForStarted();
cliProcessInternal.waitForFinished(15000);
return judgeConnectionError(cliProcessInternal.readAll());
}
int MainWindow::burnInternalFlash(QString filePath, QString offset)
{
QStringList param;
param.append("-c");
param.append("SWD");
param.append("UR");
param.append("-P");
param.append(filePath);
param.append(offset);
param.append("-V");
param.append("after_programming");
param.append("-Rst");
param.append("-Q");
cliProcessInternal.start(stlinkPath, param);
cliProcessInternal.waitForStarted();
cliProcessInternal.waitForFinished(15000);
return judgeConnectionError(cliProcessInternal.readAll());
}
int MainWindow::eraseInternalFlash()
{
QStringList param;
param.append("-c");
param.append("SWD");
param.append("UR");
param.append("-ME");
param.append("-Rst");
param.append("-Q");
cliProcessInternal.start(stlinkPath, param);
cliProcessInternal.waitForStarted();
cliProcessInternal.waitForFinished(15000);
return judgeConnectionError(cliProcessInternal.readAll());
}
int MainWindow::judgeConnectionError(QString res)
{
int ret;
if (res.contains("MCU Reset") &&
(res.contains("Programming Complete") ||
res.contains("Flash memory erased") ||
res.contains("External Memory full erase")))
{
ret = 0;
}
else if (res.contains("No target connected"))
{
QMessageBox::critical(this, "USB错误", "请检查ST-Link到PCB之间的连接线。\r\n或者重新拔插ST-Link的USB再试一次。");
ret = -1;
}
else if (res.contains("No ST-LINK detected") || res.contains("Unable to connect to ST-LINK"))
{
QMessageBox::critical(this, "SWD错误", "请检查电脑到ST-Link之间的连接线。");
ret = -2;
}
else if (res.contains("Timeout during flash programming") || res.contains("External Memory full erase"))
{
QMessageBox::critical(this, "超时", "芯片选择有误。");
ret = -3;
}
else if (res.contains("Unable to open file"))
{
QMessageBox::critical(this, "文件错误", "固件文件丢失,或者配置文件不对。");
ret = -3;
}
else
{
QMessageBox::critical(this, "未知错误", res);
ret = -100;
}
if (ret != 0)
{
ui->progressBar->setValue(0);
}
return ret;
}
qint64 MainWindow::convertQIntEndian(qint64 src)
{
qint64 dest = 0;
for (int i = 0; i < 8; i++) {
dest <<= 8;
dest |= src & 0xff;
src >>= 8;
}
return dest;
}
qint32 MainWindow::convertQIntEndian(qint32 src)
{
qint32 dest = 0;
for (int i = 0; i < 4; i++) {
dest <<= 8;
dest |= src & 0xff;
src >>= 8;
}
return dest;
}
void MainWindow::on_boardComboBox_currentTextChanged(const QString &arg1)
{
ui->socComboBox->clear();
setWindowTitle("厨芯:" + arg1);
curSection = findSectionByName(arg1);
QSettings configFile(configFilePath, QSettings::IniFormat);
configFile.setIniCodec(QTextCodec::codecForName("UTF-8"));
configFile.beginGroup(curSection);
QStringList keyList = configFile.allKeys();
foreach(QString key, keyList)
{
if (key.contains("SOC"))
{
ui->socComboBox->addItem(configFile.value(key).toString());
}
}
/* 显示电路板图片,只有工厂模式才会显示,否则隐藏 */
QString boardImage = configFile.value("IMG").toString();
ui->imageLabel->setPixmap(QPixmap(boardImagePath + boardImage).scaled(ui->imageLabel->size()));
/* 显示烧写计数 */
unsigned int burnCount = configFile.value("BURN_COUNT").toUInt();
ui->countLabel->setText("已成功烧写:" + QString::number(burnCount));
/* 显示板子注释信息 */
ui->commitLabel->setText(configFile.value("COMMIT").toString());
configFile.endGroup();
}
void MainWindow::on_socComboBox_currentTextChanged(const QString &arg1)
{
ui->bootComboBox->clear();
ui->appComboBox->clear();
ui->extLoaderLabel->clear();
curSoc = arg1;
QSettings configFile(configFilePath, QSettings::IniFormat);
configFile.setIniCodec(QTextCodec::codecForName("UTF-8"));
configFile.beginGroup(curSection);
QStringList keyList = configFile.allKeys();
foreach(QString key, keyList)
{
if (key.startsWith(curSoc + "_BL"))
{
ui->bootComboBox->addItem(configFile.value(key).toString());
ui->bootCheckBox->setChecked(true);
}
if (key.startsWith(curSoc + "_APP"))
{
ui->appComboBox->addItem(configFile.value(key).toString());
ui->appCheckBox->setChecked(true);
}
if (key.startsWith(curSoc + "_EXLOADER"))
{
curExtLoader = configFile.value(key).toString();
ui->extLoaderLabel->setText("SPI-Flash: " + curExtLoader);
}
}
configFile.endGroup();
}
void MainWindow::on_burnAllPushButton_clicked()
{
int ret;
QString pathStr;
ui->statusBar->showMessage("准备烧录,请稍后...", 3000);
ui->progressBar->setStyleSheet("QProgressBar::chunk { background-color: #c0c0ff; width: 20px;}"); // 设置进度条颜色
ui->progressBar->setValue(1);
if (ui->bootCheckBox->isChecked())
{
ui->statusBar->showMessage("正在烧写片内Flash:BootLoader(1/6)", 3000);
if (curBoot.contains(":/"))
{
pathStr = curBoot;
}
else
{
pathStr = firmwareDir + curBoot;
}
ret = burnInternalFlash(pathStr, defaultIFlashBootOffset);
if (ret != 0)
{
return;
}
}
ui->progressBar->setValue(10);
if (ui->appCheckBox->isChecked())
{
ui->statusBar->showMessage("正在烧写片内Flash:Application(2/6)", 3000);
if (curApp.contains(":/"))
{
pathStr = curApp;
}
else
{
pathStr = firmwareDir + curApp;
}
ret = burnInternalFlash(pathStr, defaultIFlashAppOffset);
if (ret != 0)
{
return;
}
ui->progressBar->setValue(36);
ui->statusBar->showMessage("正在烧写片外Flash升级标识区(3/6)", 3000);
if (curUpdateFlag.contains(":/"))
{
pathStr = curUpdateFlag;
}
else
{
pathStr = firmwareDir + curUpdateFlag;
}
ret = burnExternFlash(pathStr, extLoaderDir + curExtLoader, defaultExtFlashUpdateFlagOffset);
if (ret != 0)
{
return;
}
ui->progressBar->setValue(41);
ui->statusBar->showMessage("正在烧写片外Flash待升级标识区(4/6)", 3000);
if (curNeedUpdateFlag.contains(":/"))
{
pathStr = curNeedUpdateFlag;
}
else
{
pathStr = firmwareDir + curNeedUpdateFlag;
}
ret = burnExternFlash(pathStr, extLoaderDir + curExtLoader, defaultExtFlashNeedUpdateFlagOffset);
if (ret != 0)
{
return;
}
ui->progressBar->setValue(59);
ui->statusBar->showMessage("正在烧写片外Flash备份固件参数区(5/6)", 3000);
if (curBkpPara.contains(":/"))
{
pathStr = curBkpPara;
}
else
{
pathStr = firmwareDir + curBkpPara;
}
ret = burnExternFlash(pathStr, extLoaderDir + curExtLoader, defaultExtFlashBkpParaOffset);
if (ret != 0)
{
return;
}
ui->progressBar->setValue(78);
ui->statusBar->showMessage("正在烧写片外Flash备份固件区(6/6)", 3000);
if (curApp.contains(":/"))
{
pathStr = curApp;
}
else
{
pathStr = firmwareDir + curApp;
}
ret = burnExternFlash(pathStr, extLoaderDir + curExtLoader, defaultExtFlashAppOffset);
if (ret != 0)
{
return;
}
}
ui->progressBar->setValue(100);
ui->statusBar->showMessage("烧录完成。", 5000);
QSettings configFile(configFilePath, QSettings::IniFormat);
configFile.setIniCodec(QTextCodec::codecForName("UTF-8"));
configFile.beginGroup(curSection);
unsigned int count = configFile.value("BURN_COUNT").toUInt();
count++;
configFile.setValue("BURN_COUNT", count);
configFile.endGroup();
ui->countLabel->setText("已成功烧写:" + QString::number(count));
ui->progressBar->setStyleSheet("QProgressBar::chunk { background-color: #a0ffa0; width: 20px;}");
// QMessageBox::information(this, "成功", "烧录成功!");
// ui->progressBar->setValue(0);
}
void MainWindow::on_burnIFlashPushButton_clicked()
{
int ret;
QString pathStr;
ui->statusBar->showMessage("正在烧写片内Flash...", 3000);
ui->progressBar->setValue(1);
if (ui->bootCheckBox->isChecked())
{
ui->statusBar->showMessage("正在烧写片内Flash:BootLoader", 3000);
if (curBoot.contains(":/"))
{
pathStr = curBoot;
}
else
{
pathStr = firmwareDir + curBoot;
}
ret = burnInternalFlash(pathStr, defaultIFlashBootOffset);
if (ret != 0)
{
return;
}
}
ui->progressBar->setValue(49);
if (ui->appCheckBox->isChecked())
{
ui->statusBar->showMessage("正在烧写片内Flash:Application", 3000);
if (curApp.contains(":/"))
{
pathStr = curApp;
}
else
{
pathStr = firmwareDir + curApp;
}
ret = burnInternalFlash(pathStr, defaultIFlashAppOffset);
if (ret != 0)
{
return;
}
}
ui->progressBar->setValue(100);
ui->statusBar->showMessage("片内Flash烧录完成。", 5000);
}
void MainWindow::on_burnEFlashPushButton_clicked()
{
int ret;
QString pathStr;
if (curApp.isEmpty())
{
ui->progressBar->setValue(0);
ui->statusBar->showMessage("没有应用程序文件可烧写!", 3000);
return;
}
ui->statusBar->showMessage("正在烧写片外Flash升级标识区(1/4)", 3000);
ui->progressBar->setValue(1);
if (curUpdateFlag.contains(":/"))
{
pathStr = curUpdateFlag;
}
else
{
pathStr = firmwareDir + curUpdateFlag;
}
ret = burnExternFlash(pathStr, extLoaderDir + curExtLoader, defaultExtFlashUpdateFlagOffset);
if (ret != 0)
{
return;
}
ui->statusBar->showMessage("正在烧写片外Flash待升级标识区(2/4)", 3000);
ui->progressBar->setValue(23);
if (curNeedUpdateFlag.contains(":/"))
{
pathStr = curNeedUpdateFlag;
}
else
{
pathStr = firmwareDir + curNeedUpdateFlag;
}
ret = burnExternFlash(pathStr, extLoaderDir + curExtLoader, defaultExtFlashNeedUpdateFlagOffset);
if (ret != 0)
{
return;
}
ui->statusBar->showMessage("正在烧写片外Flash备份固件参数区(3/4)", 3000);
ui->progressBar->setValue(47);
if (curBkpPara.contains(":/"))
{
pathStr = curBkpPara;
}
else
{
pathStr = firmwareDir + curBkpPara;
}
ret = burnExternFlash(pathStr, extLoaderDir + curExtLoader, defaultExtFlashBkpParaOffset);
if (ret != 0)
{
return;
}
ui->statusBar->showMessage("正在烧写片外Flash备份固件区(4/4)", 3000);
ui->progressBar->setValue(68);
if (curApp.contains(":/"))
{
pathStr = curApp;
}
else
{
pathStr = firmwareDir + curApp;
}
ret = burnExternFlash(pathStr, extLoaderDir + curExtLoader, defaultExtFlashAppOffset);
if (ret != 0)
{
return;
}
ui->progressBar->setValue(100);
ui->statusBar->showMessage("片外Flash烧录完成。", 5000);
}
void MainWindow::on_eraseIFlashPushButton_clicked()
{
int ret;
ui->statusBar->showMessage("正在擦除片内Flash", 1000);
ui->progressBar->setValue(87);
ret = eraseInternalFlash();
if (ret != 0)
{
return;
}
ui->progressBar->setValue(100);
ui->statusBar->showMessage("擦除片内Flash完成", 5000);
}
void MainWindow::on_eraseEFlashPushButton_clicked()
{
int ret;
ui->statusBar->showMessage("正在擦除片外Flash,大约需要12秒", 12000);
ui->progressBar->setValue(15);
ret = eraseExternFlash(extLoaderDir + curExtLoader);
if (ret != 0)
{
return;
}
ui->progressBar->setValue(100);
ui->statusBar->showMessage("擦除片外Flash完成", 5000);
}
void MainWindow::on_bootComboBox_currentTextChanged(const QString &arg1)
{
curBoot = arg1;
if (curBoot.isEmpty())
ui->bootCheckBox->setChecked(false);
}
void MainWindow::on_appComboBox_currentTextChanged(const QString &arg1)
{
curApp = arg1;
if (curApp.isEmpty())
ui->appCheckBox->setChecked(false);
curBkpPara = defaultBkpPara;
QString filePath;
if (curApp.contains(":/"))
{
filePath = curApp;
}
else {
filePath = firmwareDir + curApp;
}
QFile binFile(filePath);
if (binFile.open(QIODevice::ReadOnly))
{
QByteArray binData = QCryptographicHash::hash(binFile.readAll(), QCryptographicHash::Md5);
binFile.close();
QFile args(firmwareDir + defaultBkpPara);
args.open(QIODevice::WriteOnly | QIODevice::Truncate);
QDataStream out(&args);
out << static_cast<qint32>(0);
out << convertQIntEndian(static_cast<qint32>(binFile.size()));
args.write(binData.toHex());
args.close();
}
ui->firmwareLabel->setText(curApp);
}
void MainWindow::on_openBootPushButton_clicked()
{
QString fileName;
fileName = QFileDialog::getOpenFileName(this, tr("Open file"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), tr("BootLoader(*.hex *.bin)"));
if (!fileName.isEmpty()) {
ui->bootComboBox->setCurrentText(fileName);
ui->bootCheckBox->setChecked(true);
}
}
void MainWindow::on_openAppPushButton_clicked()
{
QString fileName;
fileName = QFileDialog::getOpenFileName(this, tr("Open file"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation), tr("Application(*.hex *.bin)"));
if (!fileName.isEmpty()) {
ui->appComboBox->setCurrentText(fileName);
ui->appCheckBox->setChecked(true);
}
}
void MainWindow::on_clearCountPushButton_clicked()
{
unsigned int count = 0;
QSettings configFile(configFilePath, QSettings::IniFormat);
configFile.setIniCodec(QTextCodec::codecForName("UTF-8"));
configFile.beginGroup(curSection);
configFile.setValue("BURN_COUNT", count);
configFile.endGroup();
ui->countLabel->setText("已成功烧写:" + QString::number(count));
ui->progressBar->setValue(0);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。