diff options
-rw-r--r-- | src/Comms/FirmwareUpdater.cpp | 39 | ||||
-rw-r--r-- | src/Comms/FirmwareUpdater.h | 9 | ||||
-rw-r--r-- | src/Comms/PanelDueUpdater.cpp | 11 | ||||
-rw-r--r-- | src/Comms/PanelDueUpdater.h | 6 | ||||
-rw-r--r-- | src/GCodes/GCodes.cpp | 5 | ||||
-rw-r--r-- | src/GCodes/GCodes.h | 3 | ||||
-rw-r--r-- | src/GCodes/GCodes3.cpp | 34 | ||||
-rw-r--r-- | src/GCodes/GCodes4.cpp | 12 | ||||
-rw-r--r-- | src/RepRap.cpp | 23 | ||||
-rw-r--r-- | src/RepRap.h | 6 | ||||
-rw-r--r-- | src/bossa/Flasher.cpp | 8 | ||||
-rw-r--r-- | src/bossa/Flasher.h | 4 |
12 files changed, 100 insertions, 60 deletions
diff --git a/src/Comms/FirmwareUpdater.cpp b/src/Comms/FirmwareUpdater.cpp index 780aa8db..8b60378b 100644 --- a/src/Comms/FirmwareUpdater.cpp +++ b/src/Comms/FirmwareUpdater.cpp @@ -29,41 +29,51 @@ namespace FirmwareUpdater // Check that the prerequisites are satisfied. // Return true if yes, else print a message and return false. - GCodeResult CheckFirmwareUpdatePrerequisites(uint8_t moduleMap, GCodeBuffer& gb, const StringRef& reply, const size_t serialChannel) noexcept + GCodeResult CheckFirmwareUpdatePrerequisites( + Bitmap<uint8_t> moduleMap, + GCodeBuffer& gb, + const StringRef& reply, + const size_t serialChannel, + const StringRef& filenameRef) noexcept { #if HAS_WIFI_NETWORKING - if ( (moduleMap & (1 << WifiExternalFirmwareModule)) != 0 - || (moduleMap & (1 << WifiFirmwareModule)) != 0) + if (moduleMap.IsBitSet(WifiExternalFirmwareModule) || moduleMap.IsBitSet(WifiFirmwareModule)) { GCodeResult result; if (!reprap.GetGCodes().CheckNetworkCommandAllowed(gb, reply, result)) { return result; } - if ((moduleMap & (1 << WifiExternalFirmwareModule)) != 0 && (moduleMap & (1 << WifiFirmwareModule)) != 0) + if (moduleMap.IsBitSet(WifiExternalFirmwareModule) && moduleMap.IsBitSet(WifiFirmwareModule)) { reply.copy("Invalid combination of firmware update modules"); return GCodeResult::error; } - if ((moduleMap & (1 << WifiFirmwareModule)) != 0 - && !reprap.GetPlatform().FileExists(FIRMWARE_DIRECTORY, WIFI_FIRMWARE_FILE)) + if (moduleMap.IsBitSet(WifiFirmwareModule)) { - reply.printf("File %s not found", FIRMWARE_DIRECTORY WIFI_FIRMWARE_FILE); - return GCodeResult::error; + String<MaxFilenameLength> location; + if (!MassStorage::CombineName(location.GetRef(), FIRMWARE_DIRECTORY, filenameRef.IsEmpty() ? WIFI_FIRMWARE_FILE : filenameRef.c_str()) + || !MassStorage::FileExists(location.c_str())) + { + reply.printf("File %s not found", location.c_str()); + return GCodeResult::error; + } } } #endif #if HAS_AUX_DEVICES - if ((moduleMap & (1 << PanelDueFirmwareModule)) != 0) + if (moduleMap.IsBitSet(PanelDueFirmwareModule)) { if (!reprap.GetPlatform().IsAuxEnabled(serialChannel-1) || reprap.GetPlatform().IsAuxRaw(serialChannel-1)) { reply.printf("Aux port %d is not enabled or not in PanelDue mode", serialChannel-1); return GCodeResult::error; } - if (!reprap.GetPlatform().FileExists(FIRMWARE_DIRECTORY, PANEL_DUE_FIRMWARE_FILE)) + String<MaxFilenameLength> location; + if (!MassStorage::CombineName(location.GetRef(), FIRMWARE_DIRECTORY, filenameRef.IsEmpty() ? PANEL_DUE_FIRMWARE_FILE : filenameRef.c_str()) + || !MassStorage::FileExists(location.c_str())) { - reply.printf("File %s not found", PanelDueUpdater::firmwareFilename); + reply.printf("File %s not found", location.c_str()); return GCodeResult::error; } } @@ -88,7 +98,7 @@ namespace FirmwareUpdater return true; } - void UpdateModule(unsigned int module, const size_t serialChannel) noexcept + void UpdateModule(unsigned int module, const size_t serialChannel, const StringRef& filenameRef) noexcept { #if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES switch(module) @@ -111,7 +121,8 @@ namespace FirmwareUpdater WifiFirmwareUploader * const uploader = reprap.GetNetwork().GetWifiUploader(); if (uploader != nullptr) { - uploader->SendUpdateFile(WIFI_FIRMWARE_FILE, FIRMWARE_DIRECTORY, WifiFirmwareUploader::FirmwareAddress); + const char* binaryFilename = filenameRef.IsEmpty() ? WIFI_FIRMWARE_FILE : filenameRef.c_str(); + uploader->SendUpdateFile(binaryFilename, FIRMWARE_DIRECTORY, WifiFirmwareUploader::FirmwareAddress); } } break; @@ -124,7 +135,7 @@ namespace FirmwareUpdater { platform.InitPanelDueUpdater(); } - platform.GetPanelDueUpdater()->Start(serialChannel); + platform.GetPanelDueUpdater()->Start(filenameRef, serialChannel); } # endif } diff --git a/src/Comms/FirmwareUpdater.h b/src/Comms/FirmwareUpdater.h index aa9f8f0a..4e4d4530 100644 --- a/src/Comms/FirmwareUpdater.h +++ b/src/Comms/FirmwareUpdater.h @@ -17,9 +17,14 @@ namespace FirmwareUpdater const unsigned int PanelDueFirmwareModule = 4; #endif - GCodeResult CheckFirmwareUpdatePrerequisites(uint8_t moduleMap, GCodeBuffer& gb, const StringRef& reply, size_t serialChannel) noexcept; + GCodeResult CheckFirmwareUpdatePrerequisites( + Bitmap<uint8_t> moduleMap, + GCodeBuffer& gb, + const StringRef& reply, + size_t serialChannel, + const StringRef& filenameRef) noexcept; bool IsReady() noexcept; - void UpdateModule(unsigned int module, const size_t serialChannel) noexcept; + void UpdateModule(unsigned int module, const size_t serialChannel, const StringRef& filenameRef) noexcept; } #endif /* SRC_NETWORKING_FIRMWAREUPDATER_H_ */ diff --git a/src/Comms/PanelDueUpdater.cpp b/src/Comms/PanelDueUpdater.cpp index 5789501b..353f2458 100644 --- a/src/Comms/PanelDueUpdater.cpp +++ b/src/Comms/PanelDueUpdater.cpp @@ -108,6 +108,7 @@ PanelDueUpdater::PanelDueUpdater() noexcept , offset(0) , erasedAndResetAt(0) , state(FlashState::idle) + , filename(nullptr) { } @@ -120,13 +121,14 @@ PanelDueUpdater::~PanelDueUpdater() noexcept delete flasher; } -void PanelDueUpdater::Start(const uint32_t serialChan) noexcept +void PanelDueUpdater::Start(const StringRef& filenameRef, const uint32_t serialChan) noexcept { if (state != FlashState::idle) { return; } serialChannel = serialChan; + filename = filenameRef.IsEmpty() ? PANEL_DUE_FIRMWARE_FILE : filenameRef.c_str(); state = FlashState::eraseAndReset; } @@ -204,7 +206,7 @@ void PanelDueUpdater::Spin() noexcept case FlashState::bossaWrite: { - bool done = flasher->write(firmwareFilename, offset); + bool done = flasher->write(filename, FIRMWARE_DIRECTORY, offset); if (done) { offset = 0; // Reset it for verification @@ -218,7 +220,7 @@ void PanelDueUpdater::Spin() noexcept { uint32_t pageErrors; uint32_t totalErrors; - bool done = flasher->verify(firmwareFilename, pageErrors, totalErrors, offset); + bool done = flasher->verify(filename, FIRMWARE_DIRECTORY, pageErrors, totalErrors, offset); if (done && pageErrors == 0) { state = FlashState::bossaWriteOptions; @@ -283,6 +285,9 @@ void PanelDueUpdater::Spin() noexcept offset = 0; erasedAndResetAt = 0; + + filename = nullptr; + state = FlashState::idle; } break; diff --git a/src/Comms/PanelDueUpdater.h b/src/Comms/PanelDueUpdater.h index b48ae7b4..a92abfbd 100644 --- a/src/Comms/PanelDueUpdater.h +++ b/src/Comms/PanelDueUpdater.h @@ -33,12 +33,9 @@ public: PanelDueUpdater() noexcept; virtual ~PanelDueUpdater() noexcept; void Spin() noexcept; - void Start(const uint32_t serialChan = 1) noexcept; + void Start(const StringRef& filenameRef, const uint32_t serialChan = 1) noexcept; bool Idle() const noexcept { return state == FlashState::idle; } - // For now fix the filename here - constexpr static const char* const firmwareFilename = FIRMWARE_DIRECTORY PANEL_DUE_FIRMWARE_FILE; - private: NamedEnum(FlashState, uint8_t, idle, @@ -65,6 +62,7 @@ private: uint32_t offset; uint32_t erasedAndResetAt; FlashState state; + const char* filename; UARTClass* GetAuxPort() noexcept; }; diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp index d4a1fb70..6f9613d7 100644 --- a/src/GCodes/GCodes.cpp +++ b/src/GCodes/GCodes.cpp @@ -296,7 +296,10 @@ void GCodes::Reset() noexcept #endif pausePending = filamentChangePausePending = false; moveBuffer.filePos = noFilePosition; - firmwareUpdateModuleMap = 0; + firmwareUpdateModuleMap.Clear(); + filenameString.Clear(); + isFlashing = false; + isFlashingPanelDue = false; lastFilamentError = FilamentSensorStatus::ok; currentZProbeNumber = 0; diff --git a/src/GCodes/GCodes.h b/src/GCodes/GCodes.h index d0dda5d0..8e59d083 100644 --- a/src/GCodes/GCodes.h +++ b/src/GCodes/GCodes.h @@ -635,7 +635,8 @@ private: TriggerNumbersBitmap triggersPending; // Bitmap of triggers pending but not yet executed // Firmware update - uint8_t firmwareUpdateModuleMap; // Bitmap of firmware modules to be updated + Bitmap<uint8_t> firmwareUpdateModuleMap; // Bitmap of firmware modules to be updated + String<MaxFilenameLength> filenameString; // Filename for the current update bool isFlashing; // Is a new firmware binary going to be flashed? bool isFlashingPanelDue; // Are we in the process of flashing PanelDue? diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp index 59f65f09..a985a576 100644 --- a/src/GCodes/GCodes3.cpp +++ b/src/GCodes/GCodes3.cpp @@ -1102,7 +1102,7 @@ GCodeResult GCodes::UpdateFirmware(GCodeBuffer& gb, const StringRef &reply) reprap.GetHeat().SwitchOffAll(true); // turn all heaters off because the main loop may get suspended DisableDrives(); // all motors off - if (firmwareUpdateModuleMap == 0) // have we worked out which modules to update? + if (firmwareUpdateModuleMap.IsEmpty()) // have we worked out which modules to update? { // Find out which modules we have been asked to update if (gb.Seen('S')) @@ -1116,42 +1116,54 @@ GCodeResult GCodes::UpdateFirmware(GCodeBuffer& gb, const StringRef &reply) if (t >= NumFirmwareUpdateModules) { reply.printf("Invalid module number '%" PRIu32 "'\n", t); - firmwareUpdateModuleMap = 0; + firmwareUpdateModuleMap.Clear(); return GCodeResult::error; break; } - firmwareUpdateModuleMap |= (1u << t); + firmwareUpdateModuleMap.SetBit(t); } } else { - firmwareUpdateModuleMap = (1u << 0); // no modules specified, so update module 0 to match old behaviour + firmwareUpdateModuleMap.SetBit(0); // no modules specified, so update module 0 to match old behaviour } - if (firmwareUpdateModuleMap == 0) + if (firmwareUpdateModuleMap.IsEmpty()) { return GCodeResult::ok; // nothing to update } + filenameString.Clear(); + if (gb.Seen('P')) + { + if (firmwareUpdateModuleMap.CountSetBits() > 1) + { + reply.copy("Filename can only be provided when updating excactly one module\n"); + firmwareUpdateModuleMap.Clear(); + return GCodeResult::error; + } + gb.GetQuotedString(filenameString.GetRef()); + } + // Check prerequisites of all modules to be updated, if any are not met then don't update any of them #if HAS_WIFI_NETWORKING || HAS_AUX_DEVICES const auto result = FirmwareUpdater::CheckFirmwareUpdatePrerequisites( firmwareUpdateModuleMap, gb, reply, # if HAS_AUX_DEVICES - serialChannelForPanelDueFlashing + serialChannelForPanelDueFlashing, #else - 0 + 0, #endif - ); + filenameString.GetRef()); if (result != GCodeResult::ok) { - firmwareUpdateModuleMap = 0; + firmwareUpdateModuleMap.Clear(); return result; } #endif - if ((firmwareUpdateModuleMap & 1) != 0 && !reprap.CheckFirmwareUpdatePrerequisites(reply)) + if (firmwareUpdateModuleMap.IsBitSet(0) && !reprap.CheckFirmwareUpdatePrerequisites(reply, filenameString.GetRef())) { - firmwareUpdateModuleMap = 0; + firmwareUpdateModuleMap.Clear(); return GCodeResult::error; } } diff --git a/src/GCodes/GCodes4.cpp b/src/GCodes/GCodes4.cpp index 7cfa5f86..c5005067 100644 --- a/src/GCodes/GCodes4.cpp +++ b/src/GCodes/GCodes4.cpp @@ -471,10 +471,10 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept bool updating = false; for (unsigned int module = 1; module < NumFirmwareUpdateModules; ++module) { - if ((firmwareUpdateModuleMap & (1u << module)) != 0) + if (firmwareUpdateModuleMap.IsBitSet(module)) { - firmwareUpdateModuleMap &= ~(1u << module); - FirmwareUpdater::UpdateModule(module, serialChannelForPanelDueFlashing); + firmwareUpdateModuleMap.ClearBit(module); + FirmwareUpdater::UpdateModule(module, serialChannelForPanelDueFlashing, filenameString.GetRef()); updating = true; isFlashingPanelDue = (module == FirmwareUpdater::PanelDueFirmwareModule); break; @@ -502,11 +502,11 @@ void GCodes::RunStateMachine(GCodeBuffer& gb, const StringRef& reply) noexcept break; case GCodeState::flashing2: - if ((firmwareUpdateModuleMap & 1) != 0) + if (firmwareUpdateModuleMap.IsBitSet(0)) { // Update main firmware - firmwareUpdateModuleMap = 0; - reprap.UpdateFirmware(); + firmwareUpdateModuleMap.Clear(); + reprap.UpdateFirmware(filenameString.GetRef()); // The above call does not return unless an error occurred } isFlashing = false; diff --git a/src/RepRap.cpp b/src/RepRap.cpp index bb77f424..4b9253b2 100644 --- a/src/RepRap.cpp +++ b/src/RepRap.cpp @@ -2682,13 +2682,15 @@ bool RepRap::WriteToolParameters(FileStore *f, const bool forceWriteOffsets) noe #else // Check the prerequisites for updating the main firmware. Return True if satisfied, else print a message to 'reply' and return false. -bool RepRap::CheckFirmwareUpdatePrerequisites(const StringRef& reply) noexcept +bool RepRap::CheckFirmwareUpdatePrerequisites(const StringRef& reply, const StringRef& filenameRef) noexcept { #if HAS_MASS_STORAGE - FileStore * const firmwareFile = platform->OpenFile(FIRMWARE_DIRECTORY, IAP_FIRMWARE_FILE, OpenMode::read); + FileStore * const firmwareFile = platform->OpenFile(FIRMWARE_DIRECTORY, filenameRef.IsEmpty() ? IAP_FIRMWARE_FILE : filenameRef.c_str(), OpenMode::read); if (firmwareFile == nullptr) { - reply.printf("Firmware binary \"%s\" not found", FIRMWARE_DIRECTORY IAP_FIRMWARE_FILE); + String<MaxFilenameLength> firmwareBinaryLocation; + MassStorage::CombineName(firmwareBinaryLocation.GetRef(), FIRMWARE_DIRECTORY, filenameRef.IsEmpty() ? IAP_FIRMWARE_FILE : filenameRef.c_str()); + reply.printf("Firmware binary \"%s\" not found", firmwareBinaryLocation.c_str()); return false; } @@ -2700,7 +2702,7 @@ bool RepRap::CheckFirmwareUpdatePrerequisites(const StringRef& reply) noexcept firmwareFile->Seek(32) && #endif - firmwareFile->Read(reinterpret_cast<char*>(&firstDword), sizeof(firstDword)) == (int)sizeof(firstDword); + firmwareFile->Read(reinterpret_cast<char*>(&firstDword), sizeof(firstDword)) == (int)sizeof(firstDword); firmwareFile->Close(); if (!ok || firstDword != #if SAME5x @@ -2727,7 +2729,7 @@ bool RepRap::CheckFirmwareUpdatePrerequisites(const StringRef& reply) noexcept } // Update the firmware. Prerequisites should be checked before calling this. -void RepRap::UpdateFirmware() noexcept +void RepRap::UpdateFirmware(const StringRef& filenameRef) noexcept { #if HAS_MASS_STORAGE FileStore * const iapFile = platform->OpenFile(FIRMWARE_DIRECTORY, IAP_UPDATE_FILE, OpenMode::read); @@ -2737,12 +2739,13 @@ void RepRap::UpdateFirmware() noexcept return; } + PrepareToLoadIap(); // Use RAM-based IAP iapFile->Read(reinterpret_cast<char *>(IAP_IMAGE_START), iapFile->Length()); iapFile->Close(); - StartIap(); + StartIap(filenameRef); #endif } @@ -2798,7 +2801,7 @@ void RepRap::PrepareToLoadIap() noexcept #endif } -void RepRap::StartIap() noexcept +void RepRap::StartIap(const StringRef& filenameRef) noexcept { // Disable all interrupts, then reallocate the vector table and program entry point to the new IAP binary // This does essentially what the Atmel AT02333 paper suggests (see 3.2.2 ff) @@ -2827,7 +2830,9 @@ void RepRap::StartIap() noexcept #if HAS_MASS_STORAGE // Newer versions of IAP reserve space above the stack for us to pass the firmware filename - static const char filename[] = FIRMWARE_DIRECTORY IAP_FIRMWARE_FILE; + String<MaxFilenameLength> firmwareFileLocation; + MassStorage::CombineName(firmwareFileLocation.GetRef(), FIRMWARE_DIRECTORY, filenameRef.IsEmpty() ? IAP_FIRMWARE_FILE : filenameRef.c_str()); + const char* filename = firmwareFileLocation.c_str(); const uint32_t topOfStack = *reinterpret_cast<uint32_t *>(IAP_IMAGE_START); if (topOfStack + sizeof(filename) <= # if SAME5x @@ -2839,7 +2844,7 @@ void RepRap::StartIap() noexcept # endif ) { - memcpy(reinterpret_cast<char*>(topOfStack), filename, sizeof(filename)); + strcpy(reinterpret_cast<char*>(topOfStack), filename); } #endif diff --git a/src/RepRap.h b/src/RepRap.h index 77ca2b36..029fac95 100644 --- a/src/RepRap.h +++ b/src/RepRap.h @@ -168,10 +168,10 @@ public: bool IsProcessingConfig() const noexcept { return processingConfig; } // Firmware update operations - bool CheckFirmwareUpdatePrerequisites(const StringRef& reply) noexcept; - void UpdateFirmware() noexcept; + bool CheckFirmwareUpdatePrerequisites(const StringRef& reply, const StringRef& filenameRef) noexcept; + void UpdateFirmware(const StringRef& filenameRef) noexcept; void PrepareToLoadIap() noexcept; - [[noreturn]] void StartIap() noexcept; + [[noreturn]] void StartIap(const StringRef& filenameRef) noexcept; void ReportInternalError(const char *file, const char *func, int line) const noexcept; // report an internal error diff --git a/src/bossa/Flasher.cpp b/src/bossa/Flasher.cpp index 011849b9..976906a0 100644 --- a/src/bossa/Flasher.cpp +++ b/src/bossa/Flasher.cpp @@ -44,7 +44,7 @@ void Flasher::erase(uint32_t foffset) THROWS(GCodeException) _flash->eraseAuto(false); } -bool Flasher::write(const char* filename, uint32_t& foffset) THROWS(GCodeException) +bool Flasher::write(const char* filename, const char* dir, uint32_t& foffset) THROWS(GCodeException) { uint32_t pageSize = _flash->pageSize(); uint32_t numPages; @@ -54,7 +54,7 @@ bool Flasher::write(const char* filename, uint32_t& foffset) THROWS(GCodeExcepti { pageNum = 0; Platform& platform = reprap.GetPlatform(); - infile = MassStorage::OpenFile(filename, OpenMode::read, 0); + infile = platform.OpenFile(dir, filename, OpenMode::read); if (infile == nullptr) { platform.MessageF(ErrorMessage, "Failed to open file %s\n", filename); @@ -111,7 +111,7 @@ bool Flasher::write(const char* filename, uint32_t& foffset) THROWS(GCodeExcepti return true; } -bool Flasher::verify(const char* filename, uint32_t& pageErrors, uint32_t& totalErrors, uint32_t& foffset) THROWS(GCodeException) +bool Flasher::verify(const char* filename, const char* dir, uint32_t& pageErrors, uint32_t& totalErrors, uint32_t& foffset) THROWS(GCodeException) { uint32_t pageSize = _flash->pageSize(); uint8_t bufferA[pageSize]; @@ -134,7 +134,7 @@ bool Flasher::verify(const char* filename, uint32_t& pageErrors, uint32_t& total // Note that we can skip all checks for file validity here since // we would not get here from write() if any of these failed - infile = MassStorage::OpenFile(filename, OpenMode::read, 0); + infile = reprap.GetPlatform().OpenFile(dir, filename, OpenMode::read); } try diff --git a/src/bossa/Flasher.h b/src/bossa/Flasher.h index f3421883..e0d365bb 100644 --- a/src/bossa/Flasher.h +++ b/src/bossa/Flasher.h @@ -58,8 +58,8 @@ public: virtual ~Flasher() {} void erase(uint32_t foffset) THROWS(GCodeException); - bool write(const char* filename, uint32_t& foffset) THROWS(GCodeException); - bool verify(const char* filename, uint32_t& pageErrors, uint32_t& totalErrors, uint32_t& foffset) THROWS(GCodeException); + bool write(const char* filename, const char* dir, uint32_t& foffset) THROWS(GCodeException); + bool verify(const char* filename, const char* dir, uint32_t& pageErrors, uint32_t& totalErrors, uint32_t& foffset) THROWS(GCodeException); void lock(/* std::string& regionArg, */ bool enable) THROWS(GCodeException); private: |