diff options
author | Christian Hammacher <bmasterc@gmail.com> | 2020-10-24 16:32:26 +0300 |
---|---|---|
committer | Christian Hammacher <bmasterc@gmail.com> | 2020-10-24 16:32:26 +0300 |
commit | 8f719f336c10f6a2554c25bb1de87957c9873010 (patch) | |
tree | 0bc1f12ea344d63ec1e4bafabf19baaffdfb2eeb /src/Linux | |
parent | 994cb4f1fef542c20e318d4dd87a21f54145598f (diff) |
Improvements for SBC mode
RRF tells SBC explicitly about closed messages and macro files
Removed one more mutex in the Linux subsystem
Bug fix: Fixed issue about multiple stack levels in the same file in SBC mode
Bug fix: Firmware filenames for Duet 3 Mini 5+ were wrong
Diffstat (limited to 'src/Linux')
-rw-r--r-- | src/Linux/DataTransfer.cpp | 38 | ||||
-rw-r--r-- | src/Linux/DataTransfer.h | 2 | ||||
-rw-r--r-- | src/Linux/LinuxInterface.cpp | 30 | ||||
-rw-r--r-- | src/Linux/LinuxInterface.h | 10 | ||||
-rw-r--r-- | src/Linux/LinuxMessageFormats.h | 6 |
5 files changed, 68 insertions, 18 deletions
diff --git a/src/Linux/DataTransfer.cpp b/src/Linux/DataTransfer.cpp index 7dd42ee1..12cca374 100644 --- a/src/Linux/DataTransfer.cpp +++ b/src/Linux/DataTransfer.cpp @@ -1088,6 +1088,24 @@ bool DataTransfer::WriteAbortFileRequest(GCodeChannel channel, bool abortAll) no return true; } +bool DataTransfer::WriteMacroFileClosed(GCodeChannel channel) noexcept +{ + if (!CanWritePacket(sizeof(CodeChannelHeader))) + { + return false; + } + + // Write packet header + WritePacketHeader(FirmwareRequest::MacroFileClosed, sizeof(CodeChannelHeader)); + + // Write header + CodeChannelHeader *header = WriteDataHeader<CodeChannelHeader>(); + header->channel = channel.RawValue(); + header->paddingA = 0; + header->paddingB = 0; + return true; +} + bool DataTransfer::WritePrintPaused(FilePosition position, PrintPausedReason reason) noexcept { if (!CanWritePacket(sizeof(PrintPausedHeader))) @@ -1327,10 +1345,30 @@ bool DataTransfer::WriteWaitForAcknowledgement(GCodeChannel channel) noexcept // Write header CodeChannelHeader *header = WriteDataHeader<CodeChannelHeader>(); header->channel = channel.RawValue(); + header->paddingA = 0; + header->paddingB = 0; + return true; +} + +bool DataTransfer::WriteMessageAcknowledged(GCodeChannel channel) noexcept +{ + if (!CanWritePacket(sizeof(CodeChannelHeader))) + { + return false; + } + // Write packet header + WritePacketHeader(FirmwareRequest::MessageAcknowledged, sizeof(CodeChannelHeader)); + + // Write header + CodeChannelHeader *header = WriteDataHeader<CodeChannelHeader>(); + header->channel = channel.RawValue(); + header->paddingA = 0; + header->paddingB = 0; return true; } + PacketHeader *DataTransfer::WritePacketHeader(FirmwareRequest request, size_t dataLength, uint16_t resendPacketId) noexcept { // Make sure to stay aligned if the last packet ended with a string diff --git a/src/Linux/DataTransfer.h b/src/Linux/DataTransfer.h index bf7f2088..1b7964e5 100644 --- a/src/Linux/DataTransfer.h +++ b/src/Linux/DataTransfer.h @@ -59,6 +59,7 @@ public: bool WriteCodeReply(MessageType type, OutputBuffer *&response) noexcept; bool WriteMacroRequest(GCodeChannel channel, const char *filename, bool fromCode) noexcept; bool WriteAbortFileRequest(GCodeChannel channel, bool abortAll) noexcept; + bool WriteMacroFileClosed(GCodeChannel channel) noexcept; bool WritePrintPaused(FilePosition position, PrintPausedReason reason) noexcept; bool WriteHeightMap() noexcept; bool WriteLocked(GCodeChannel channel) noexcept; @@ -67,6 +68,7 @@ public: bool WriteEvaluationError(const char *expression, const char *errorMessage) noexcept; bool WriteDoCode(GCodeChannel channel, const char *code, size_t length) noexcept; bool WriteWaitForAcknowledgement(GCodeChannel channel) noexcept; + bool WriteMessageAcknowledged(GCodeChannel channel) noexcept; private: enum class SpiState diff --git a/src/Linux/LinuxInterface.cpp b/src/Linux/LinuxInterface.cpp index 00ffa950..eeb9ebad 100644 --- a/src/Linux/LinuxInterface.cpp +++ b/src/Linux/LinuxInterface.cpp @@ -28,7 +28,6 @@ extern char _end; // defined by the linker Mutex LinuxInterface::gcodeReplyMutex; -Mutex LinuxInterface::codesMutex; #ifdef __LPC17xx__ constexpr size_t LinuxTaskStackWords = 375; @@ -60,7 +59,6 @@ LinuxInterface::~LinuxInterface() void LinuxInterface::Init() noexcept { gcodeReplyMutex.Create("LinuxReply"); - codesMutex.Create("LinuxCodes"); #if defined(DUET_NG) // Make sure that the Wifi module if present is disabled. The ESP Reset pin is already forced low in Platform::Init(); @@ -123,7 +121,7 @@ void LinuxInterface::Init() noexcept // Perform a G/M/T-code case LinuxRequest::Code: { - MutexLocker lock(codesMutex); + TaskCriticalSectionLocker locker; // Read the next code and check if the GB is waiting for a macro file const CodeHeader *code = reinterpret_cast<const CodeHeader*>(transfer.ReadData(packet->length)); @@ -157,6 +155,7 @@ void LinuxInterface::Init() noexcept txPointer = 0; sendBufferUpdate = true; } + // Check to see if we are about to overwrite older packets. if (txPointer < rxPointer && txPointer + sizeof(BufferedCodeHeader) + packet->length > rxPointer) { @@ -536,7 +535,8 @@ void LinuxInterface::Init() noexcept // Notify DSF about the available buffer space if (sendBufferUpdate || transfer.LinuxHadReset()) { - MutexLocker lock(codesMutex); + TaskCriticalSectionLocker locker; + const uint16_t bufferSpace = (txLength == 0) ? max<uint16_t>(rxPointer, SpiCodeBufferSize - txPointer) : rxPointer - txPointer; sendBufferUpdate = !transfer.WriteCodeBufferUpdate(bufferSpace); } @@ -591,20 +591,30 @@ void LinuxInterface::Init() noexcept gb->Invalidate(false); } - // Handle file abort requests + // Handle file requests if (gb->IsAbortRequested() && transfer.WriteAbortFileRequest(channel, gb->IsAbortAllRequested())) { - gb->AcknowledgeAbort(); + gb->FileAbortSent(); gb->Invalidate(); } + else if (gb->IsMacroFileClosed() && transfer.WriteMacroFileClosed(channel)) + { + // Note this is only sent when a macro file has finished successfully + gb->MacroFileClosedSent(); + } - // Handle blocking messages + // Handle blocking messages and their results if (gb->MachineState().waitingForAcknowledgement && !gb->MachineState().waitingForAcknowledgementSent && transfer.WriteWaitForAcknowledgement(channel)) { gb->MachineState().waitingForAcknowledgementSent = true; gb->Invalidate(); } + else if (gb->IsMessageAcknowledged() && transfer.WriteMessageAcknowledged(channel)) + { + // Note this is only sent when a message was acknowledged in a regular way (i.e. by M292) + gb->MessageAcknowledgementSent(); + } // Send pending firmware codes if (gb->IsSendRequested() && transfer.WriteDoCode(channel, gb->DataStart(), gb->DataLength())) @@ -706,7 +716,7 @@ bool LinuxInterface::IsConnected() const noexcept bool LinuxInterface::FillBuffer(GCodeBuffer &gb) noexcept { - if (gb.IsInvalidated() || + if (gb.IsInvalidated() || gb.IsMacroFileClosed() || gb.IsMessageAcknowledged() || gb.IsAbortRequested() || (reportPause && gb.GetChannel() == GCodeChannel::File) || (gb.MachineState().waitingForAcknowledgement && !gb.MachineState().waitingForAcknowledgementSent)) { @@ -714,7 +724,7 @@ bool LinuxInterface::FillBuffer(GCodeBuffer &gb) noexcept return false; } - MutexLocker lock(codesMutex); + TaskCriticalSectionLocker locker; if (rxPointer != txPointer || txLength != 0) { bool updateRxPointer = true; @@ -825,7 +835,7 @@ void LinuxInterface::HandleGCodeReply(MessageType mt, OutputBuffer *buffer) noex void LinuxInterface::InvalidateBufferChannel(GCodeChannel channel) noexcept { - MutexLocker lock(codesMutex); + TaskCriticalSectionLocker locker; if (rxPointer != txPointer || txLength != 0) { bool updateRxPointer = true; diff --git a/src/Linux/LinuxInterface.h b/src/Linux/LinuxInterface.h index 49c8f6f5..dc2eade8 100644 --- a/src/Linux/LinuxInterface.h +++ b/src/Linux/LinuxInterface.h @@ -59,11 +59,6 @@ public: #endif private: - void InvalidateBufferChannel(GCodeChannel channel) noexcept; // Invalidate every buffered G-code of the corresponding channel from the buffer ring - - static Mutex gcodeReplyMutex; // static so that the LinuxInterface is safe to delete even is the mutex is linked into the mutex chain or is in use - static Mutex codesMutex; - DataTransfer transfer; bool wasConnected; uint32_t numDisconnects; @@ -80,7 +75,6 @@ private: uint32_t iapWritePointer; uint32_t iapRamAvailable; // must be at least 64Kb otherwise the SPI IAP can't work - OutputStack *gcodeReply; #if SUPPORT_CAN_EXPANSION // Data needed when a CAN expansion board requests a firmware file chunk @@ -91,6 +85,10 @@ private: int32_t requestedFileDataLength; #endif + static Mutex gcodeReplyMutex; // static so that the LinuxInterface is safe to delete even is the mutex is linked into the mutex chain or is in use + OutputStack *gcodeReply; + + void InvalidateBufferChannel(GCodeChannel channel) noexcept; // Invalidate every buffered G-code of the corresponding channel from the buffer ring }; inline void LinuxInterface::SetPauseReason(FilePosition position, PrintPausedReason reason) noexcept diff --git a/src/Linux/LinuxMessageFormats.h b/src/Linux/LinuxMessageFormats.h index 7f32105b..0df18fff 100644 --- a/src/Linux/LinuxMessageFormats.h +++ b/src/Linux/LinuxMessageFormats.h @@ -170,14 +170,16 @@ enum class FirmwareRequest : uint16_t Message = 3, // Message from the firmware ExecuteMacro = 4, // Request execution of a macro file AbortFile = 5, // Request the current file to be closed - StackEvent_Obsolete = 6, // Stack has been changed + StackEvent_Obsolete = 6, // Stack has been changed (unused) PrintPaused = 7, // Print has been paused HeightMap = 8, // Response to a heightmap request Locked = 9, // Movement has been locked and machine is in standstill FileChunk = 10, // Request another chunk of a file EvaluationResult = 11, // Response to an expression evaluation request DoCode = 12, // Perform a G/M/T-code from a code input - WaitForMessageAcknowledgment = 13 // Wait for a message to be acknowledged + WaitForMessageAcknowledgment = 13, // Wait for a message to be acknowledged + MacroFileClosed = 14, // Last macro file has been closed + MessageAcknowledged = 15 // Pending message prompt has been acknowledged }; enum class PrintPausedReason : uint8_t |