Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Crocker <dcrocker@eschertech.com>2022-07-20 16:57:02 +0300
committerDavid Crocker <dcrocker@eschertech.com>2022-07-20 16:57:02 +0300
commit5501f6d9885d73c96c180f98721d9524bd96290c (patch)
tree1a4dc530748814c73e8cf3d589da25fd4459dfac
parentec894c2d7a27b61348928b9cbfa64c8aa98b34ac (diff)
Implemented remote reset and remote firmware update (needs CAN IAP)
-rw-r--r--src/CAN/CommandProcessor.cpp43
-rw-r--r--src/Config/Pins_Duet3Mini.h1
-rw-r--r--src/Config/Pins_Duet3_MB6HC.h1
-rw-r--r--src/Config/Pins_Duet3_MB6XD.h1
-rw-r--r--src/GCodes/GCodes4.cpp4
-rw-r--r--src/Platform/RepRap.cpp82
-rw-r--r--src/Platform/RepRap.h15
7 files changed, 119 insertions, 28 deletions
diff --git a/src/CAN/CommandProcessor.cpp b/src/CAN/CommandProcessor.cpp
index f7c5ed0a..9b5b61b5 100644
--- a/src/CAN/CommandProcessor.cpp
+++ b/src/CAN/CommandProcessor.cpp
@@ -382,7 +382,30 @@ static GCodeResult EutGetInfo(const CanMessageReturnInfo& msg, const StringRef&
return GCodeResult::ok;
}
-#endif
+static GCodeResult InitiateFirmwareUpdate(const CanMessageUpdateYourFirmware& msg, const StringRef& reply)
+{
+ if (msg.boardId != CanInterface::GetCanAddress() || msg.invertedBoardId != (uint8_t)~CanInterface::GetCanAddress() || (msg.module != 0 && msg.module != 3))
+ {
+ reply.printf("Invalid firmware update command received");
+ return GCodeResult::error;
+ }
+
+ if (msg.module == 0)
+ {
+ if (!reprap.GetPlatform().FileExists(FIRMWARE_DIRECTORY, IAP_CAN_LOADER_FILE))
+ {
+ reply.printf("In-application programming binary \"%s\" not found on board %u", FIRMWARE_DIRECTORY IAP_CAN_LOADER_FILE, CanInterface::GetCanAddress());
+ return GCodeResult::error;
+ }
+ reply.printf("Board %u starting firmware update", CanInterface::GetCanAddress());
+ reprap.ScheduleFirmwareUpdateOverCan();
+ return GCodeResult::ok;
+ }
+ reply.copy("unknown firmware module number");
+ return GCodeResult::error;
+}
+
+#endif // SUPPORT_REMOTE_COMMANDS
// Process a received broadcast or request message. Don't free the message buffer
void CommandProcessor::ProcessReceivedMessage(CanMessageBuffer *buf) noexcept
@@ -410,6 +433,11 @@ void CommandProcessor::ProcessReceivedMessage(CanMessageBuffer *buf) noexcept
StepTimer::ProcessTimeSyncMessage(buf->msg.sync, buf->dataLength, buf->timeStamp);
return; // no reply needed
+ case CanMessageType::emergencyStop:
+ reprap.EmergencyStop();
+ reprap.ScheduleReset();
+ return; // no reply needed
+
case CanMessageType::movementLinear:
reprap.GetMove().AddMoveFromRemote(buf->msg.moveLinear);
return; // no reply needed
@@ -432,6 +460,19 @@ void CommandProcessor::ProcessReceivedMessage(CanMessageBuffer *buf) noexcept
CanInterface::MainBoardAcknowledgedAnnounce();
return;
+ case CanMessageType::updateFirmware:
+ requestId = buf->msg.updateYourFirmware.requestId;
+ rslt = InitiateFirmwareUpdate(buf->msg.updateYourFirmware, replyRef);
+ break;
+
+ case CanMessageType::reset:
+ requestId = buf->msg.reset.requestId;
+ reply.printf("Board %u resetting", CanInterface::GetCanAddress());
+ reprap.EmergencyStop();
+ reprap.ScheduleReset();
+ rslt = GCodeResult::ok;
+ break;
+
case CanMessageType::returnInfo:
requestId = buf->msg.getInfo.requestId;
rslt = EutGetInfo(buf->msg.getInfo, replyRef, extra);
diff --git a/src/Config/Pins_Duet3Mini.h b/src/Config/Pins_Duet3Mini.h
index 188c7f79..42612f96 100644
--- a/src/Config/Pins_Duet3Mini.h
+++ b/src/Config/Pins_Duet3Mini.h
@@ -23,6 +23,7 @@
#define IAP_FIRMWARE_FILE "Duet3Firmware_" BOARD_SHORT_NAME ".uf2"
#define IAP_UPDATE_FILE "Duet3_SDiap32_" BOARD_SHORT_NAME ".bin"
#define IAP_UPDATE_FILE_SBC "Duet3_SBCiap32_" BOARD_SHORT_NAME ".bin"
+#define IAP_CAN_LOADER_FILE "Duet3_CANiap32" BOARD_SHORT_NAME ".bin"
constexpr uint32_t IAP_IMAGE_START = 0x20038000;
#define WIFI_FIRMWARE_FILE "DuetWiFiServer.bin"
diff --git a/src/Config/Pins_Duet3_MB6HC.h b/src/Config/Pins_Duet3_MB6HC.h
index 5574ff1e..6d7ea386 100644
--- a/src/Config/Pins_Duet3_MB6HC.h
+++ b/src/Config/Pins_Duet3_MB6HC.h
@@ -11,6 +11,7 @@
#define IAP_UPDATE_FILE "Duet3_SDiap32_" BOARD_SHORT_NAME ".bin"
#define IAP_UPDATE_FILE_SBC "Duet3_SBCiap32_" BOARD_SHORT_NAME ".bin"
+#define IAP_CAN_LOADER_FILE "Duet3_CANiap32" BOARD_SHORT_NAME ".bin"
constexpr uint32_t IAP_IMAGE_START = 0x20458000; // last 32kb of RAM
// Features definition
diff --git a/src/Config/Pins_Duet3_MB6XD.h b/src/Config/Pins_Duet3_MB6XD.h
index 514cb4ed..c1df8adf 100644
--- a/src/Config/Pins_Duet3_MB6XD.h
+++ b/src/Config/Pins_Duet3_MB6XD.h
@@ -11,6 +11,7 @@
#define IAP_UPDATE_FILE "Duet3_SDiap32_" BOARD_SHORT_NAME ".bin"
#define IAP_UPDATE_FILE_SBC "Duet3_SBCiap32_" BOARD_SHORT_NAME ".bin"
+#define IAP_CAN_LOADER_FILE "Duet3_CANiap32" BOARD_SHORT_NAME ".bin"
constexpr uint32_t IAP_IMAGE_START = 0x20458000; // last 32kb of RAM
// Features definition
diff --git a/src/GCodes/GCodes4.cpp b/src/GCodes/GCodes4.cpp
index 48256718..5c0a6cf5 100644
--- a/src/GCodes/GCodes4.cpp
+++ b/src/GCodes/GCodes4.cpp
@@ -591,12 +591,12 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept
{
// Update main firmware
firmwareUpdateModuleMap.Clear();
- String<MaxFilenameLength> filenameString;
try
{
+ String<MaxFilenameLength> filenameString;
bool dummy;
gb.TryGetQuotedString('P', filenameString.GetRef(), dummy);
- reprap.UpdateFirmware(filenameString.GetRef());
+ reprap.UpdateFirmware(IAP_UPDATE_FILE, filenameString.c_str());
// The above call does not return unless an error occurred
}
catch (const GCodeException&) { }
diff --git a/src/Platform/RepRap.cpp b/src/Platform/RepRap.cpp
index ae951908..43dafec1 100644
--- a/src/Platform/RepRap.cpp
+++ b/src/Platform/RepRap.cpp
@@ -792,8 +792,30 @@ void RepRap::Spin() noexcept
diagnosticsDestination = MessageType::NoDestinationMessage;
}
- // Check if we need to display a cold extrusion warning
const uint32_t now = millis();
+
+#if SUPPORT_REMOTE_COMMANDS
+ const DeferredCommand defCom = deferredCommand; // capture volatile variable
+ if (defCom != DeferredCommand::none && now - whenDeferredCommandScheduled >= 250)
+ {
+ switch (defCom)
+ {
+ case DeferredCommand::reboot:
+ SoftwareReset(SoftwareResetReason::user);
+ break;
+
+ case DeferredCommand::updateFirmware:
+ UpdateFirmware(IAP_CAN_LOADER_FILE, "");
+ break;
+
+ default:
+ deferredCommand = DeferredCommand::none;
+ break;
+ }
+ }
+#endif
+
+ // Check if we need to display a cold extrusion warning
if (now - lastWarningMillis >= MinimumWarningInterval)
{
ReadLocker lock(toolListLock);
@@ -958,44 +980,58 @@ void RepRap::Diagnostics(MessageType mtype) noexcept
justSentDiagnostics = true;
}
-// Turn off the heaters, disable the motors, and deactivate the Heat and Move classes. Leave everything else working.
+// Turn off the heaters, disable the motors, and deactivate the Heat, Move and GCodes classes. Leave everything else working.
void RepRap::EmergencyStop() noexcept
{
#ifdef DUET3_ATE
Duet3Ate::PowerOffEUT();
#endif
- stopped = true; // a useful side effect of setting this is that it prevents Platform::Tick being called, which is needed when loading IAP into RAM
+ stopped = true; // a useful side effect of setting this is that it prevents Platform::Tick being called, which is needed when loading IAP into RAM
// Do not turn off ATX power here. If the nozzles are still hot, don't risk melting any surrounding parts by turning fans off.
//platform->SetAtxPower(false);
- platform->DisableAllDrivers(); // need to do this to ensure that any motor brakes are re-engaged
-
- switch (gCodes->GetMachineType())
+#if SUPPORT_REMOTE_COMMANDS
+ if (CanInterface::InExpansionMode())
{
- case MachineType::cnc:
- for (size_t i = 0; i < MaxSpindles; i++)
+ platform->EmergencyDisableDrivers(); // disable all local drivers - need to do this to ensure that any motor brakes are re-engaged
+ }
+ else
+#endif
+ {
+ platform->DisableAllDrivers(); // disable all local and remote drivers - need to do this to ensure that any motor brakes are re-engaged
+
+ switch (gCodes->GetMachineType())
{
- platform->AccessSpindle(i).SetState(SpindleState::stopped);
- }
- break;
+ case MachineType::cnc:
+ for (size_t i = 0; i < MaxSpindles; i++)
+ {
+ platform->AccessSpindle(i).SetState(SpindleState::stopped);
+ }
+ break;
#if SUPPORT_LASER
- case MachineType::laser:
- platform->SetLaserPwm(0);
- break;
+ case MachineType::laser:
+ platform->SetLaserPwm(0);
+ break;
#endif
- default:
- break;
+ default:
+ break;
+ }
}
- heat->Exit(); // this also turns off all heaters
- move->Exit(); // this stops the motors stepping
+ heat->Exit(); // this also turns off all heaters
+ move->Exit(); // this stops the motors stepping
#if SUPPORT_CAN_EXPANSION
- expansion->EmergencyStop();
+# if SUPPORT_REMOTE_COMMANDS
+ if (!CanInterface::InExpansionMode())
+# endif
+ {
+ expansion->EmergencyStop();
+ }
#endif
gCodes->EmergencyStop();
@@ -2916,13 +2952,13 @@ bool RepRap::CheckFirmwareUpdatePrerequisites(const StringRef& reply, const Stri
}
// Update the firmware. Prerequisites should be checked before calling this.
-void RepRap::UpdateFirmware(const StringRef& filenameRef) noexcept
+void RepRap::UpdateFirmware(const char *iapFilename, const char *iapParam) noexcept
{
#if HAS_MASS_STORAGE
- FileStore * iapFile = platform->OpenFile(FIRMWARE_DIRECTORY, IAP_UPDATE_FILE, OpenMode::read);
+ FileStore * iapFile = platform->OpenFile(FIRMWARE_DIRECTORY, iapFilename, OpenMode::read);
if (iapFile == nullptr)
{
- iapFile = platform->OpenFile(DEFAULT_SYS_DIR, IAP_UPDATE_FILE, OpenMode::read);
+ iapFile = platform->OpenFile(DEFAULT_SYS_DIR, iapFilename, OpenMode::read);
if (iapFile == nullptr)
{
// This should not happen because we already checked that the file exists, so use a simplified error message
@@ -2936,7 +2972,7 @@ void RepRap::UpdateFirmware(const StringRef& filenameRef) noexcept
// Use RAM-based IAP
iapFile->Read(reinterpret_cast<char *>(IAP_IMAGE_START), iapFile->Length());
iapFile->Close();
- StartIap(filenameRef.c_str());
+ StartIap(iapParam);
#endif
}
diff --git a/src/Platform/RepRap.h b/src/Platform/RepRap.h
index b380bb51..49c6dfd6 100644
--- a/src/Platform/RepRap.h
+++ b/src/Platform/RepRap.h
@@ -61,7 +61,7 @@ public:
RepRap(const RepRap&) = delete;
void EmergencyStop() noexcept;
- void Init() noexcept;
+ void Init() noexcept;
void Spin() noexcept;
void Exit() noexcept;
void Diagnostics(MessageType mtype) noexcept;
@@ -134,6 +134,11 @@ public:
ExpansionManager& GetExpansion() const noexcept { return *expansion; }
#endif
+#if SUPPORT_REMOTE_COMMANDS
+ void ScheduleReset() noexcept { whenDeferredCommandScheduled = millis(); deferredCommand = DeferredCommand::reboot; }
+ void ScheduleFirmwareUpdateOverCan() noexcept { whenDeferredCommandScheduled = millis(); deferredCommand = DeferredCommand::updateFirmware; }
+#endif
+
void Tick() noexcept;
bool SpinTimeoutImminent() const noexcept;
bool IsStopped() const noexcept;
@@ -171,7 +176,7 @@ public:
// Firmware update operations
bool CheckFirmwareUpdatePrerequisites(const StringRef& reply, const StringRef& filenameRef) noexcept;
- void UpdateFirmware(const StringRef& filenameRef) noexcept;
+ void UpdateFirmware(const char *iapFilename, const char *iapParam) noexcept;
void PrepareToLoadIap() noexcept;
[[noreturn]] void StartIap(const char *filename) noexcept;
@@ -280,6 +285,12 @@ private:
uint16_t heatTaskIdleTicks;
uint32_t fastLoop, slowLoop;
+#if SUPPORT_REMOTE_COMMANDS
+ enum class DeferredCommand : uint8_t { none, reboot, updateFirmware };
+ volatile uint32_t whenDeferredCommandScheduled;
+ volatile DeferredCommand deferredCommand;
+#endif
+
DebugFlags debugMaps[Module::numModules];
String<RepRapPasswordLength> password;