From: xue <2144439972@qq.com> Date: Thu, 23 Apr 2026 02:31:32 +0000 (+0800) Subject: 取消开始产测重启操作 X-Git-Url: http://git.snicker.com.cn/?a=commitdiff_plain;h=8ccea83437e7e370832321359ccded035fab3b96;p=mirrors%2Ffactory_tool.git 取消开始产测重启操作 --- diff --git a/mainwindow.cpp b/mainwindow.cpp index 9ea6236..48329d6 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -94,6 +94,8 @@ MainWindow::MainWindow(QWidget *parent) gSensorIntervalTimer = new QTimer(this); currentLcdColor = 0; isProductionTestRunning = false; + postFactoryVoteSequenceStarted = false; + waitingPmaddvoteOkForGreenButton = false; currentTestStep = TEST_IDLE; lcdTestPopupShown = false; motorTestPopupShown = false; @@ -550,6 +552,14 @@ void MainWindow::readSerialData() if (bootDetected && !factoryModeChecked && !isProductionTestRunning) { checkFactoryMode(line); } + + // 产测已开始:等待开机完成关键字后再进入 PMADDVOTE(与空闲时的 checkBootDetection 使用同一关键字列表) + if (isProductionTestRunning && currentTestStep == TEST_WAIT_BOOT) { + tryAdvanceProductionAfterBootKeywords(line); + if (currentTestStep == TEST_WAIT_BOOT && processLine != line) { + tryAdvanceProductionAfterBootKeywords(processLine); + } + } // 版本信息获取:当正在获取版本信息时,接收到数据后继续发送下一条指令 if (versionInfoFetched && currentVersionCommandIndex >= 0 && @@ -618,10 +628,13 @@ void MainWindow::readSerialData() // 4G/PPP 相关解析已移除 - // 检测工厂模式进入确认(用于产测) - if (line.contains("fac:enter or exit facotry mode")) { + // 检测工厂模式进入确认(用于产测;兼容 facotry/factory 拼写,大小写不敏感) + if (line.contains("enter or exit facotry mode", Qt::CaseInsensitive) || + line.contains("enter or exit factory mode", Qt::CaseInsensitive)) { checkFactoryModeResult(line); } + + tryApplyProductionStartGreenAfterPmaddvoteOk(line); // 4G/PPP 相关解析已移除 @@ -740,6 +753,8 @@ void MainWindow::on_ProductionTestButton_clicked() lcdTestTimer->stop(); motorTestTimer->stop(); isProductionTestRunning = false; + postFactoryVoteSequenceStarted = false; + waitingPmaddvoteOkForGreenButton = false; currentTestStep = TEST_IDLE; ui->statusbar->showMessage("产测已停止", 2000); @@ -753,6 +768,8 @@ void MainWindow::on_ProductionTestButton_clicked() // 开始产测流程 isProductionTestRunning = true; + postFactoryVoteSequenceStarted = false; + waitingPmaddvoteOkForGreenButton = false; if (isTestItemEnabled("lcd")) { currentTestStep = TEST_LCD; currentLcdColor = 1; // 从红色开始 @@ -910,88 +927,67 @@ void MainWindow::checkFactoryModeResult(const QString& data) if (!isProductionTestRunning || currentTestStep != TEST_RESET) { return; } - + + const bool hasFacConfirm = data.contains("enter or exit facotry mode", Qt::CaseInsensitive) + || data.contains("enter or exit factory mode", Qt::CaseInsensitive); + if (!hasFacConfirm) { + return; + } + qDebug() << "工厂模式确认收到数据:" << data.trimmed(); - - // 解析新格式:fac:enter or exit facotry mode :1 或 fac:enter or exit facotry mode :0 - if (data.contains("fac:enter or exit facotry mode")) { - // 使用正则表达式提取cmd值 - QRegExp factoryModePattern("fac:enter or exit facotry mode\\s*:\\s*(\\d+)"); - if (factoryModePattern.indexIn(data) != -1) { - QString cmdStr = factoryModePattern.cap(1); - int cmd = cmdStr.toInt(); - - qDebug() << "解析到工厂模式命令:" << cmd << "(1=进入产测, 0=退出产测)"; - - if (cmd == 1) { - // cmd=1 表示成功进入产测模式 - // 停止超时检测,因为已经收到确认 - if (testTimeoutTimer->isActive()) { - testTimeoutTimer->stop(); - qDebug() << "工厂模式进入确认收到,停止超时检测"; - } - - qDebug() << "工厂模式进入成功确认 (cmd=1)"; - ui->statusbar->showMessage("工厂模式进入成功,准备重启设备...", 2000); - - // 产测开始确认 - 按钮变绿色并禁用 - ui->openButton_2->setStyleSheet("QPushButton { background-color: #28A745; color: white; padding: 5px 10px; border: none; border-radius: 3px; }"); - ui->openButton_2->setEnabled(false); - qDebug() << "产测开始确认 - 按钮已变绿色并禁用"; - - // 延迟2秒后发送重启指令 - QTimer::singleShot(2000, this, [this]() { - if (isProductionTestRunning && currentTestStep == TEST_RESET) { - ui->statusbar->showMessage("产测模式已开启 - 重启设备中...", 3000); - qDebug() << "工厂模式确认后发送设备重启指令"; - ui->recvTextEdit->append(">>> 发送指令: AT^RESET (恢复出厂设置/重启设备)"); - serial->write("AT^RESET\r\n"); - qDebug() << "发送设备重启指令: AT^RESET"; - - // 切换到等待BuildVer状态 - currentTestStep = TEST_WAIT_BUILDVER; - qDebug() << "等待设备重启完成,寻找BuildVer标志..."; - } - }); - - } else if (cmd == 0) { - // cmd=0 表示退出产测模式 - qDebug() << "工厂模式退出确认 (cmd=0)"; - ui->statusbar->showMessage("工厂模式已退出", 2000); - - } else { - // 未知的cmd值 - qDebug() << "未知的工厂模式命令值:" << cmd; - ui->statusbar->showMessage("收到未知的工厂模式命令", 2000); - } - } else { - // 无法解析cmd值,使用旧的逻辑作为备用 - qDebug() << "无法解析工厂模式命令值,使用旧逻辑"; - - // 停止超时检测,因为已经收到确认 + + int cmd = -1; + QRegExp reFacotry("(?:fac:)?enter or exit facotry mode\\s*:\\s*(\\d+)", Qt::CaseInsensitive); + QRegExp reFactory("(?:fac:)?enter or exit factory mode\\s*:\\s*(\\d+)", Qt::CaseInsensitive); + if (reFacotry.indexIn(data) != -1) { + cmd = reFacotry.cap(1).toInt(); + } else if (reFactory.indexIn(data) != -1) { + cmd = reFactory.cap(1).toInt(); + } + + if (cmd >= 0) { + qDebug() << "解析到工厂模式命令:" << cmd << "(1=进入产测, 0=退出产测)"; + + if (cmd == 1) { if (testTimeoutTimer->isActive()) { testTimeoutTimer->stop(); - qDebug() << "工厂模式确认收到,停止超时检测"; + qDebug() << "工厂模式进入确认收到,停止超时检测"; } - - qDebug() << "工厂模式进入成功确认 (备用逻辑)"; - ui->statusbar->showMessage("工厂模式进入成功,准备重启设备...", 2000); - - // 延迟2秒后发送重启指令 - QTimer::singleShot(2000, this, [this]() { - if (isProductionTestRunning && currentTestStep == TEST_RESET) { - ui->statusbar->showMessage("产测模式已开启 - 重启设备中...", 3000); - qDebug() << "工厂模式确认后发送设备重启指令"; - ui->recvTextEdit->append(">>> 发送指令: AT^RESET (恢复出厂设置/重启设备)"); - serial->write("AT^RESET\r\n"); - qDebug() << "发送设备重启指令: AT^RESET"; - - // 切换到等待BuildVer状态 - currentTestStep = TEST_WAIT_BUILDVER; - qDebug() << "等待设备重启完成,寻找BuildVer标志..."; - } - }); + + qDebug() << "工厂模式进入成功确认 (cmd=1)"; + ui->statusbar->showMessage("工厂模式进入成功,等待 PMADDVOTE OK...", 2000); + + ui->openButton_2->setStyleSheet("QPushButton { background-color: #4A90E2; color: white; padding: 5px 10px; border: none; border-radius: 3px; }"); + qDebug() << "工厂模式进入成功,已发 PMADDVOTE 链后将根据 OK 把产测按钮变绿"; + + currentTestStep = TEST_PMADDVOTE_INIT; + qDebug() << "不执行 AT^RESET,直接进入 PMADDVOTE / ENTERTESTVIEW"; + runPostFactoryProductionInit(); + + } else if (cmd == 0) { + qDebug() << "工厂模式退出确认 (cmd=0)"; + ui->statusbar->showMessage("工厂模式已退出", 2000); + + } else { + qDebug() << "未知的工厂模式命令值:" << cmd; + ui->statusbar->showMessage("收到未知的工厂模式命令", 2000); + } + } else { + qDebug() << "无法解析工厂模式命令值,使用备用逻辑"; + + if (testTimeoutTimer->isActive()) { + testTimeoutTimer->stop(); + qDebug() << "工厂模式确认收到,停止超时检测"; } + + qDebug() << "工厂模式进入成功确认 (备用逻辑)"; + ui->statusbar->showMessage("工厂模式进入成功,等待 PMADDVOTE OK...", 2000); + + ui->openButton_2->setStyleSheet("QPushButton { background-color: #4A90E2; color: white; padding: 5px 10px; border: none; border-radius: 3px; }"); + + currentTestStep = TEST_PMADDVOTE_INIT; + qDebug() << "不执行 AT^RESET,直接进入 PMADDVOTE / ENTERTESTVIEW (备用解析路径)"; + runPostFactoryProductionInit(); } } @@ -1878,59 +1874,119 @@ void MainWindow::showKeyTestConfirmDialog(bool allKeysTested) } } -// 检查BuildVer启动完成 +// 工厂确认或重启后:PMADDVOTE → ENTERTESTVIEW → LCD +void MainWindow::runPostFactoryProductionInit() +{ + if (!isProductionTestRunning || !serial || !serial->isOpen()) { + qDebug() << "runPostFactoryProductionInit: 产测未运行或串口未打开,跳过"; + return; + } + if (postFactoryVoteSequenceStarted) { + qDebug() << "runPostFactoryProductionInit: 初始化链已在执行,忽略重复调用"; + return; + } + postFactoryVoteSequenceStarted = true; + waitingPmaddvoteOkForGreenButton = true; + + serial->write("AT^PMADDVOTE\r\n"); + qDebug() << "发送AT^PMADDVOTE指令(第1次): AT^PMADDVOTE"; + + QTimer::singleShot(500, this, [this]() { + if (isProductionTestRunning && serial->isOpen()) { + serial->write("AT^PMADDVOTE\r\n"); + qDebug() << "发送AT^PMADDVOTE指令(第2次): AT^PMADDVOTE"; + + if (serial->isOpen()) { + ui->recvTextEdit->append(">>> 发送指令: AT^ENTERTESTVIEW (进入产测界面)"); + serial->write("AT^ENTERTESTVIEW\r\n"); + qDebug() << "发送AT^ENTERTESTVIEW (进入产测界面)"; + } + + QTimer::singleShot(1000, this, [this]() { + if (!isProductionTestRunning) { + return; + } + if (isTestItemEnabled("lcd")) { + qDebug() << "AT^PMADDVOTE指令发送完成,开始LCD测试"; + ui->statusbar->showMessage("初始化完成,开始LCD测试", 2000); + currentTestStep = TEST_LCD; + QTimer::singleShot(1000, this, [this]() { + if (isProductionTestRunning && currentTestStep == TEST_LCD) { + qDebug() << "开始LCD测试流程"; + performLcdTest(); + } + }); + } else { + qDebug() << "AT^PMADDVOTE指令发送完成,LCD测试未启用,跳过"; + ui->statusbar->showMessage("初始化完成,LCD测试未启用,跳过", 2000); + currentTestStep = TEST_LCD; + skipToNextEnabledTest(); + } + }); + } + }); +} + +void MainWindow::tryAdvanceProductionAfterBootKeywords(const QString& data) +{ + if (!isProductionTestRunning || currentTestStep != TEST_WAIT_BOOT) { + return; + } + + const QStringList keywords = configManager.getBootDetectionKeywords(); + if (keywords.isEmpty()) { + return; + } + + for (const QString& keyword : keywords) { + if (data.contains(keyword, Qt::CaseInsensitive)) { + qDebug() << "产测:检测到开机完成关键字:" << keyword << ",数据片段:" << data.left(120); + appendToLogFile(QString("=== 产测流程-检测到开机完成: %1 ===\n").arg(keyword)); + + bootDetected = true; + currentTestStep = TEST_PMADDVOTE_INIT; + + if (testTimeoutTimer->isActive()) { + testTimeoutTimer->stop(); + } + + ui->statusbar->showMessage("设备已开机,正在发送 PMADDVOTE / ENTERTESTVIEW…", 3000); + ui->recvTextEdit->append(">>> 已检测到开机完成,进入 PMADDVOTE / ENTERTESTVIEW 初始化链(未发 AT^FACTORY=1)"); + + runPostFactoryProductionInit(); + return; + } + } +} + +void MainWindow::tryApplyProductionStartGreenAfterPmaddvoteOk(const QString& line) +{ + if (!waitingPmaddvoteOkForGreenButton || !isProductionTestRunning || + currentTestStep != TEST_PMADDVOTE_INIT) { + return; + } + const QString t = line.trimmed(); + if (t.compare(QStringLiteral("OK"), Qt::CaseInsensitive) != 0) { + return; + } + waitingPmaddvoteOkForGreenButton = false; + ui->openButton_2->setStyleSheet("QPushButton { background-color: #28A745; color: white; padding: 5px 10px; border: none; border-radius: 3px; }"); + ui->openButton_2->setEnabled(false); + qDebug() << "收到 AT^PMADDVOTE 的 OK 响应,产测按钮已变绿并禁用"; + ui->statusbar->showMessage("PMADDVOTE 成功,产测进行中", 2000); +} + +// 检查BuildVer启动完成(仅当仍使用「先重启再等 BuildVer」时使用) void MainWindow::checkBuildVerResult(const QString& data) { - // 检测设备启动完成标志,只在等待BuildVer阶段检测(大小写不敏感) - if (data.contains("BuildVer", Qt::CaseInsensitive) && currentTestStep == TEST_WAIT_BUILDVER && + if (data.contains("BuildVer", Qt::CaseInsensitive) && currentTestStep == TEST_WAIT_BUILDVER && isProductionTestRunning) { - + qDebug() << "检测到BuildVer启动完成标志:" << data.trimmed(); - qDebug() << "设备重启完成,发送AT^PMADDVOTE指令"; - - ui->statusbar->showMessage("设备重启完成,发送初始化指令...", 2000); - - // 发送第一次AT^PMADDVOTE指令 - serial->write("AT^PMADDVOTE\r\n"); - qDebug() << "发送AT^PMADDVOTE指令(第1次): AT^PMADDVOTE"; - - // 延迟0.5秒后发送第二次AT^PMADDVOTE指令 - QTimer::singleShot(500, this, [this]() { - if (isProductionTestRunning && serial->isOpen()) { - serial->write("AT^PMADDVOTE\r\n"); - qDebug() << "发送AT^PMADDVOTE指令(第2次): AT^PMADDVOTE"; - - // 开机初始化完成后,进入产测界面(满足AT^ENTERTESTVIEW要求) - if (serial->isOpen()) { - ui->recvTextEdit->append(">>> 发送指令: AT^ENTERTESTVIEW (进入产测界面)"); - serial->write("AT^ENTERTESTVIEW\r\n"); - qDebug() << "发送AT^ENTERTESTVIEW (进入产测界面)"; - } - - // 初始化完成后,切换到 LCD(若启用);功耗测试在 GPS 之后 - QTimer::singleShot(1000, this, [this]() { - if (!isProductionTestRunning) { - return; - } - if (isTestItemEnabled("lcd")) { - qDebug() << "AT^PMADDVOTE指令发送完成,开始LCD测试"; - ui->statusbar->showMessage("初始化完成,开始LCD测试", 2000); - currentTestStep = TEST_LCD; - QTimer::singleShot(1000, this, [this]() { - if (isProductionTestRunning && currentTestStep == TEST_LCD) { - qDebug() << "开始LCD测试流程"; - performLcdTest(); - } - }); - } else { - qDebug() << "AT^PMADDVOTE指令发送完成,LCD测试未启用,跳过"; - ui->statusbar->showMessage("初始化完成,LCD测试未启用,跳过", 2000); - currentTestStep = TEST_LCD; - skipToNextEnabledTest(); - } - }); - } - }); + ui->statusbar->showMessage("设备启动完成,发送初始化指令...", 2000); + + currentTestStep = TEST_PMADDVOTE_INIT; + runPostFactoryProductionInit(); } } @@ -2339,6 +2395,8 @@ void MainWindow::on_openButton_2_clicked() gSensorIntervalTimer->stop(); bluetoothTestTimer->stop(); isProductionTestRunning = false; + postFactoryVoteSequenceStarted = false; + waitingPmaddvoteOkForGreenButton = false; currentTestStep = TEST_IDLE; // 关闭测试日志文件 @@ -2361,10 +2419,13 @@ void MainWindow::on_openButton_2_clicked() // 开始产测流程 isProductionTestRunning = true; + postFactoryVoteSequenceStarted = false; + waitingPmaddvoteOkForGreenButton = false; + recvBuffer.clear(); testStartTime = QDateTime::currentDateTime(); // 记录测试开始时间 testStartTimeMap.clear(); testDurationSecMap.clear(); - currentTestStep = TEST_RESET; + currentTestStep = TEST_WAIT_BOOT; currentLcdColor = 1; // 从红色开始 // 在开始新测试前,尽量保存当前UI日志(如果有内容) @@ -2415,27 +2476,29 @@ void MainWindow::on_openButton_2_clicked() ui->statusbar->showMessage("开始产测流程...", 2000); qDebug() << "=== 开始产测流程 ==="; - qDebug() << "流程: 产测开启(AT^FACTORY=1) → 设备重启 → … → 全部完成后弹窗确认 → AT^RESTORE(恢复出厂) → AT^POWEROFF(关机)"; + qDebug() << "流程: 等待开机完成 → 跳过 AT^FACTORY=1 → PMADDVOTE/ENTERTESTVIEW → 各测试项 → 完成后弹窗确认等"; qDebug() << "LCD测试: 仅发送 AT^LCDTEST=1"; - // 发送产测开启指令,等待工厂模式确认 - qDebug() << "Step 1: 发送产测开启指令"; - ui->statusbar->showMessage("发送产测开启指令,等待设备确认...", 3000); - ui->recvTextEdit->append(">>> 发送指令: AT^FACTORY=1 (开始产测)"); - serial->write("AT^FACTORY=1\r\n"); - qDebug() << "发送产测开启指令(第1次): AT^FACTORY=1,等待接收 'fac:enter or exit facotry mode' 确认"; - - // 延迟0.5秒后再发送一次,确保设备接收到指令 - QTimer::singleShot(500, this, [this]() { - if (isProductionTestRunning && serial->isOpen()) { - ui->recvTextEdit->append(">>> 发送指令: AT^FACTORY=1 (开始产测 - 第2次)"); - serial->write("AT^FACTORY=1\r\n"); - qDebug() << "发送产测开启指令(第2次): AT^FACTORY=1"; - } - }); - - // 启动10秒超时检测,如果没有收到工厂模式确认则提示 - testTimeoutTimer->start(10000); + // 不再发送 AT^FACTORY=1:固件侧常会触发整机重启;在开机完成后再发 PMADDVOTE / ENTERTESTVIEW + qDebug() << "Step 1: 等待串口开机关键字(bootDetectionKeywords),然后 PMADDVOTE / ENTERTESTVIEW"; + + ui->openButton_2->setStyleSheet("QPushButton { background-color: #4A90E2; color: white; padding: 5px 10px; border: none; border-radius: 3px; }"); + ui->openButton_2->setEnabled(true); + qDebug() << "产测开始 - 先等开机完成;之后等待 AT^PMADDVOTE 回复 OK 后按钮变绿(期间可再点此按钮停止)"; + + const QStringList bootKws = configManager.getBootDetectionKeywords(); + if (bootKws.isEmpty()) { + qDebug() << "bootDetectionKeywords 为空,跳过等待开机"; + ui->recvTextEdit->append(">>> 未配置开机关键字,跳过等待,直接发送 PMADDVOTE / ENTERTESTVIEW(未发 AT^FACTORY=1)"); + ui->statusbar->showMessage("未配置开机关键字,直接初始化…", 3000); + currentTestStep = TEST_PMADDVOTE_INIT; + runPostFactoryProductionInit(); + } else { + ui->recvTextEdit->append(">>> 等待设备开机完成(与 settings 中 bootDetectionKeywords 匹配后,再发 PMADDVOTE / ENTERTESTVIEW)"); + ui->statusbar->showMessage("等待设备开机完成… 请上电或重启设备", 0); + testTimeoutTimer->stop(); + testTimeoutTimer->start(120000); + } } // 执行录音测试(配置了等级标准时共测 3 轮,任一轮「实际等级 >= 设置等级」则整体通过) @@ -3981,6 +4044,20 @@ void MainWindow::onTestTimeout() // 根据当前测试步骤确定测试名称 switch (currentTestStep) { + case TEST_WAIT_BOOT: + qDebug() << "等待设备开机超时,未匹配到 bootDetectionKeywords"; + ui->statusbar->showMessage("等待开机超时,请检查设备或关键字配置", 5000); + QMessageBox::warning(this, "等待开机超时", + QStringLiteral("在 120 秒内未在串口日志中检测到开机关键字(bootDetectionKeywords)。\n" + "请确认设备已上电/重启,或在 settings.json 中配置与固件日志一致的关键字。")); + isProductionTestRunning = false; + waitingPmaddvoteOkForGreenButton = false; + postFactoryVoteSequenceStarted = false; + currentTestStep = TEST_IDLE; + ui->openButton_2->setStyleSheet("QPushButton { background-color: #4A90E2; color: white; padding: 5px 10px; border: none; border-radius: 3px; }"); + ui->openButton_2->setEnabled(true); + return; + case TEST_RESET: // 工厂模式进入超时 qDebug() << "工厂模式进入超时,未收到确认消息"; @@ -4187,6 +4264,8 @@ void MainWindow::clearProductionTestState() // 重置产测状态变量 isProductionTestRunning = false; + postFactoryVoteSequenceStarted = false; + waitingPmaddvoteOkForGreenButton = false; currentTestStep = TEST_IDLE; currentLcdColor = 0; diff --git a/mainwindow.h b/mainwindow.h index 3215a5a..6f049fd 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -69,7 +69,10 @@ private slots: void showBatteryChargeFailDialog(); // 显示电池充电失败弹窗 void clearProductionTestState(); // 清空产测状态 void checkLcdTestResult(const QString& data); // 检查LCD测试结果 - void checkBuildVerResult(const QString& data); // 检查BuildVer启动完成 + void checkBuildVerResult(const QString& data); // 检查BuildVer启动完成(仅重启流程备用) + void runPostFactoryProductionInit(); // 工厂确认后:PMADDVOTE / ENTERTESTVIEW / LCD(不重启) + void tryAdvanceProductionAfterBootKeywords(const QString& data); // 产测已开始且处于等待开机:匹配到关键字则进入 PMADDVOTE 链 + void tryApplyProductionStartGreenAfterPmaddvoteOk(const QString& line); // 收到 PMADDVOTE 后的 OK 再将产测按钮变绿 void showLcdTestConfirmDialog(); // 显示LCD测试确认弹窗 void showMotorTestConfirmDialog(); // 显示马达测试确认弹窗 void performTouchTest(); // 触控测试(AT^TESTJUMP=TP) @@ -142,6 +145,8 @@ private: QTimer *gpsPollTimer; // GPS信息轮询定时器(每2秒发AT^GPSINFO) int currentLcdColor; // 当前LCD测试颜色 (1=红, 2=绿, 3=蓝) bool isProductionTestRunning; // 产测是否正在运行 + bool postFactoryVoteSequenceStarted; // PMADDVOTE 初始化链是否已启动(防重复) + bool waitingPmaddvoteOkForGreenButton; // 已发 PMADDVOTE,等待 OK 后再把「开始产测」按钮变绿 QDateTime testStartTime; // 测试开始时间 bool lcdTestPopupShown; // LCD测试弹窗是否已显示 bool motorTestPopupShown; // 马达测试弹窗是否已显示 @@ -197,8 +202,10 @@ private: enum ProductionTestStep { TEST_IDLE, + TEST_WAIT_BOOT, // 已点开始产测,等待串口出现开机完成关键字(与 settings 中 bootDetectionKeywords 一致) TEST_RESET, TEST_WAIT_BUILDVER, + TEST_PMADDVOTE_INIT, TEST_LCD, TEST_TOUCH, TEST_BRIGHT,