Index: sources/canbus/CanInterface.cpp =================================================================== diff -u -r20b370a54d2737831b307a0de82aec9e06e2b772 -ra789f05e3d97087703029792b6fd81bce77157f0 --- sources/canbus/CanInterface.cpp (.../CanInterface.cpp) (revision 20b370a54d2737831b307a0de82aec9e06e2b772) +++ sources/canbus/CanInterface.cpp (.../CanInterface.cpp) (revision a789f05e3d97087703029792b6fd81bce77157f0) @@ -27,6 +27,9 @@ #include "FrameInterface.h" #include "UiSwUpdate.h" +#include +#include + // namespace using namespace Can; @@ -281,6 +284,11 @@ _erFrameCount++; } } + + // Delay 100 us between msg sends. + // 8 bytes is roughly 400us. + using namespace std::chrono_literals; + std::this_thread::sleep_for(100us); } } return ok; Index: sources/model/hd/alarm/MAlarmMapping.cpp =================================================================== diff -u -rd881f3ded899d68df7b5ef5b2fcbbf49f4bbc959 -ra789f05e3d97087703029792b6fd81bce77157f0 --- sources/model/hd/alarm/MAlarmMapping.cpp (.../MAlarmMapping.cpp) (revision d881f3ded899d68df7b5ef5b2fcbbf49f4bbc959) +++ sources/model/hd/alarm/MAlarmMapping.cpp (.../MAlarmMapping.cpp) (revision a789f05e3d97087703029792b6fd81bce77157f0) @@ -7,7 +7,7 @@ * * \file MAlarmMapping.cpp * \author (last) Behrouz NematiPour - * \date (last) 24-Apr-2023 + * \date (last) 20-May-2023 * \author (original) Behrouz NematiPour * \date (original) 03-May-2021 * Index: sources/update/UiProtocol.cpp =================================================================== diff -u -r7cf31f6cfef97bb564a103c263821a3b722c8a2b -ra789f05e3d97087703029792b6fd81bce77157f0 --- sources/update/UiProtocol.cpp (.../UiProtocol.cpp) (revision 7cf31f6cfef97bb564a103c263821a3b722c8a2b) +++ sources/update/UiProtocol.cpp (.../UiProtocol.cpp) (revision a789f05e3d97087703029792b6fd81bce77157f0) @@ -379,7 +379,7 @@ } // Create the security token and send it. - SwUpdate_createSecurity((uint8 *) &msg, sizeof(SwUpdateDataBuffer)); + SwUpdate_createSecurity((uint8 *) &msg, sizeof(SwUpdateDataBuffer)); ok = _link.sendOk( (_target == HD) ? SwUpdateCanMsgIds::DataBufferId_HD_FW : (_target == DG) ? SwUpdateCanMsgIds::DataBufferId_DG_FW : Index: sources/update/VSwUpdate.cpp =================================================================== diff -u -r7cf31f6cfef97bb564a103c263821a3b722c8a2b -ra789f05e3d97087703029792b6fd81bce77157f0 --- sources/update/VSwUpdate.cpp (.../VSwUpdate.cpp) (revision 7cf31f6cfef97bb564a103c263821a3b722c8a2b) +++ sources/update/VSwUpdate.cpp (.../VSwUpdate.cpp) (revision a789f05e3d97087703029792b6fd81bce77157f0) @@ -41,6 +41,10 @@ #define MSG_ID_REBOOT_NOW (0x8094) ///< HD Reboot RM46 immediately #define MSG_ID_SET_ENTER_BOOTLOADER (0x8095) ///< HD Set the flag to stay +/** 1 or 0 means do once, 2 = do twice, 3 = three times, etc. */ +#define MAX_TEST_LOOPS (1) + + /*! * \brief Constructor. * @@ -63,7 +67,9 @@ _isVisible(false), _progressVisible(false), _postWasOk(false), - _settingsOk(false) + _settingsOk(false), + _testLoops(0), + _maxTestLoops(MAX_TEST_LOOPS) { setButtonText("Start"); setState(""); @@ -278,52 +284,9 @@ _ApplicationController.enableKeepAlive(true); } else { - // Start. - int row_index = (int)_selected; - if (row_index >= 0) { - std::vector update; - std::string package_location = _available[row_index].fullPath; + _testLoops = 0; // UI initiated. - // Copy / cache it (if not already in there). - // - // The UI has already checked the package as ok before allowing the user to pick it. - bool ok = _package.copyUpdate(package_location, _oldUpdates, _maxOld); - if (!ok) - { - writeLog("Failed to cache: " + QString::fromStdString(package_location), true); - } - - // As part of starting, it re-checks and then leaves the file open during the rest of the process - // and thus not-modifiable as a stream as a security feature. - _ApplicationController.enableKeepAlive(false); - _CanInterface.setSWUpdateMode(true); - - // Tell it to enter bootloader, this is done using the application protocol but from here. - // - // If these did fail which is extremely unlikely it feels to the user like they didn't quite - // press the start button. - - ok = _package.start_hasKey(package_location, update); - if (ok) - { - // If we got an ok, we are no longer allowed to trust the DG or HD image - // that exists so we'll never use MSG_ID_HD_REBOOT_NOW - QString info = QString::fromStdString(_package.get_info()); - set_progress(info); - startStopUpdate("Started update" + info, true); - } else { - // This is the only point in an update that can fail and just go to the existing image. - // Because we didn't write MSG_ID_HD_SET_ENTER_BOOTLOADER this should reboot to the app. - // - // This should put both into the FW bootloader, which timesout into launching the app if - // nothing else is commanded. - _package.rebootFW(); - - set_progress("Failed to start " + QString::fromStdString(_available[row_index].fileName)); - writeLog("Failed to start " + QString::fromStdString(package_location), false); - writeLog(QString::fromStdString(_package.get_info()), true); - } - } + startUpdate(); } // Falling through, success or failure ensure these are set correctly. @@ -676,6 +639,16 @@ } } + if (!_updating) { + _testLoops++; + + // Finished but not abort, so... + if (_testLoops< _maxTestLoops) { + startUpdate(); + } + } + + // Ensure these match up with _updating state. _ApplicationController.enableKeepAlive(!_updating); _mpBackButton->setEnabled(!_updating); @@ -820,6 +793,9 @@ return true; } +/*! + * \brief Check and if needed mount the USB. + */ void VSWUpdate::checkMountUsb() { static bool mounted = false; static QString oldDevice; @@ -847,3 +823,55 @@ mounted = false; oldDevice = ""; } + +/*! + * \brief Start the update. + */ +void VSWUpdate::startUpdate() { + // Start. + int row_index = (int)_selected; + if (row_index >= 0) { + std::vector update; + std::string package_location = _available[row_index].fullPath; + + // Copy / cache it (if not already in there). + // + // The UI has already checked the package as ok before allowing the user to pick it. + bool ok = _package.copyUpdate(package_location, _oldUpdates, _maxOld); + if (!ok) + { + writeLog("Failed to cache: " + QString::fromStdString(package_location), true); + } + + // As part of starting, it re-checks and then leaves the file open during the rest of the process + // and thus not-modifiable as a stream as a security feature. + _ApplicationController.enableKeepAlive(false); + _CanInterface.setSWUpdateMode(true); + + // Tell it to enter bootloader, this is done using the application protocol but from here. + // + // If these did fail which is extremely unlikely it feels to the user like they didn't quite + // press the start button. + + ok = _package.start_hasKey(package_location, update); + if (ok) + { + // If we got an ok, we are no longer allowed to trust the DG or HD image + // that exists so we'll never use MSG_ID_HD_REBOOT_NOW + QString info = QString::fromStdString(_package.get_info()); + set_progress(info); + startStopUpdate("Started update" + info, true); + } else { + // This is the only point in an update that can fail and just go to the existing image. + // Because we didn't write MSG_ID_HD_SET_ENTER_BOOTLOADER this should reboot to the app. + // + // This should put both into the FW bootloader, which timesout into launching the app if + // nothing else is commanded. + _package.rebootFW(); + + set_progress("Failed to start " + QString::fromStdString(_available[row_index].fileName)); + writeLog("Failed to start " + QString::fromStdString(package_location), false); + writeLog(QString::fromStdString(_package.get_info()), true); + } + } +} Index: sources/update/VSwUpdate.h =================================================================== diff -u -r7cf31f6cfef97bb564a103c263821a3b722c8a2b -ra789f05e3d97087703029792b6fd81bce77157f0 --- sources/update/VSwUpdate.h (.../VSwUpdate.h) (revision 7cf31f6cfef97bb564a103c263821a3b722c8a2b) +++ sources/update/VSwUpdate.h (.../VSwUpdate.h) (revision a789f05e3d97087703029792b6fd81bce77157f0) @@ -288,6 +288,9 @@ bool controlUSB(bool enable); void checkMountUsb(); + void startUpdate(); + + std::vector _available; ///< List of available things. QString _pubKey; ///< Public key. QStringList _updateDirs; ///< Update available directories. @@ -310,6 +313,9 @@ bool _settingsOk; ///< Version and settings are ok. bool _wasTrialBoot; ///< This was a trial boot or normal. std::chrono::time_point _lastPing; ///< Last ping time. + + uint32 _testLoops; ///< For testing loop update an index. + uint32 _maxTestLoops; ///< Max loop count. }; #endif // V_SW_UPDATE_H_