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:
authorChristian Hammacher <bmasterc@gmail.com>2021-07-29 20:04:19 +0300
committerChristian Hammacher <bmasterc@gmail.com>2021-07-29 20:04:19 +0300
commitd7fd1866ffbfbb87229fa89ae2c7add48307cd8a (patch)
tree571bd76255c3083a50bf198c0871b06bf629c328
parent448c585f89bb48fcb1b1e728001a0b2f4ca32197 (diff)
Further improvements
Added support for expression lists (untested in standalone mode) M23/M32 are invoked again by DSF in SBC mode Increased SBC task priority Bug fix: CAN diagnostics output extra NL Bug fix: M999 P"ERASE" was not working on the Mini5+ series
-rw-r--r--src/CAN/CanInterface.cpp2
-rw-r--r--src/Configuration.h1
-rw-r--r--src/GCodes/GCodeBuffer/BinaryParser.cpp121
-rw-r--r--src/GCodes/GCodeBuffer/BinaryParser.h2
-rw-r--r--src/GCodes/GCodeBuffer/ExpressionParser.cpp6
-rw-r--r--src/GCodes/GCodeBuffer/ExpressionParser.h2
-rw-r--r--src/GCodes/GCodeBuffer/StringParser.cpp8
-rw-r--r--src/GCodes/GCodes.cpp12
-rw-r--r--src/GCodes/GCodes2.cpp14
-rw-r--r--src/GCodes/GCodes3.cpp8
-rw-r--r--src/Hardware/ExceptionHandlers.cpp9
-rw-r--r--src/Linux/DataTransfer.cpp6
-rw-r--r--src/Linux/DataTransfer.h2
-rw-r--r--src/Linux/LinuxInterface.cpp45
-rw-r--r--src/Linux/LinuxInterface.h14
-rw-r--r--src/Platform/TaskPriorities.h2
-rw-r--r--src/PrintMonitor/PrintMonitor.cpp2
17 files changed, 171 insertions, 85 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp
index 502fad4f..35ccc87e 100644
--- a/src/CAN/CanInterface.cpp
+++ b/src/CAN/CanInterface.cpp
@@ -1170,7 +1170,7 @@ void CanInterface::Diagnostics(MessageType mtype) noexcept
CanId id;
id.SetReceivedId(lastCancelledId);
lastCancelledId = 0;
- str.catf(" last cancelled message type %u dest %u\n", (unsigned int)id.MsgType(), id.Dst());
+ str.catf(" last cancelled message type %u dest %u", (unsigned int)id.MsgType(), id.Dst());
}
reprap.GetPlatform().MessageF(mtype, "Tx timeouts%s\n", str.c_str());
diff --git a/src/Configuration.h b/src/Configuration.h
index dd67344f..efdd6141 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -377,6 +377,7 @@ static_assert(MaxExpectedWebDirFilenameLength + strlen(WEB_DIR) + strlen(".gz")
#define EOF_STRING "<!-- **EoF** -->"
// List defaults
+constexpr char EXPRESSION_LIST_SEPARATOR = ',';
constexpr char LIST_SEPARATOR = ':';
#endif
diff --git a/src/GCodes/GCodeBuffer/BinaryParser.cpp b/src/GCodes/GCodeBuffer/BinaryParser.cpp
index 78145ef1..de4b7b02 100644
--- a/src/GCodes/GCodeBuffer/BinaryParser.cpp
+++ b/src/GCodes/GCodeBuffer/BinaryParser.cpp
@@ -457,17 +457,17 @@ void BinaryParser::GetPossiblyQuotedString(const StringRef& str, bool allowEmpty
void BinaryParser::GetFloatArray(float arr[], size_t& length, bool doPad) THROWS(GCodeException)
{
- GetArray(arr, length, doPad);
+ GetArray(arr, length, doPad, DataType::Float);
}
void BinaryParser::GetIntArray(int32_t arr[], size_t& length, bool doPad) THROWS(GCodeException)
{
- GetArray(arr, length, doPad);
+ GetArray(arr, length, doPad, DataType::Int);
}
void BinaryParser::GetUnsignedArray(uint32_t arr[], size_t& length, bool doPad) THROWS(GCodeException)
{
- GetArray(arr, length, doPad);
+ GetArray(arr, length, doPad, DataType::UInt);
}
// Get a :-separated list of drivers after a key letter
@@ -498,6 +498,17 @@ void BinaryParser::GetDriverIdArray(DriverId arr[], size_t& length) THROWS(GCode
length = seenParameter->intValue;
break;
+ case DataType::Expression:
+ {
+ float temp[seenParameter->intValue];
+ GetArray(temp, length, false, DataType::Float);
+ for (int i = 0; i < seenParameter->intValue; i++)
+ {
+ SetDriverIdFromBinary(arr[i], temp[i]);
+ }
+ break;
+ }
+
default:
length = 0;
return;
@@ -562,7 +573,7 @@ void BinaryParser::AppendFullCommand(const StringRef &s) const noexcept
}
}
-template<typename T> void BinaryParser::GetArray(T arr[], size_t& length, bool doPad) THROWS(GCodeException)
+template<typename T> void BinaryParser::GetArray(T arr[], size_t& length, bool doPad, DataType type) THROWS(GCodeException)
{
if (seenParameter == nullptr)
{
@@ -617,34 +628,104 @@ template<typename T> void BinaryParser::GetArray(T arr[], size_t& length, bool d
break;
case DataType::Expression:
- //TODO need a way to pass multi-element array-valued expressions. For now we support only single-element expressions.
+ {
+ const char *pos = seenParameterValue, *endPos = seenParameterValue + seenParameter->intValue;
+
+ // Check if the whole expression is encapsulated in curly braces and remove them if necessary
+ if (*pos == '{' && pos != endPos)
{
- ExpressionParser parser(gb, seenParameterValue, seenParameterValue + seenParameter->intValue, -1);
- const ExpressionValue val = parser.Parse();
- switch ((TypeCode)val.type)
+ bool isEncapsulated = true, inQuotes = false;
+ size_t numBraces = 1;
+ for (const char *str = pos + 1; str < endPos; str++)
+ {
+ if (inQuotes)
+ {
+ inQuotes = (*str != '"');
+ }
+ else if (*str == '"')
+ {
+ inQuotes = true;
+ }
+ else if (*str == '{')
+ {
+ numBraces++;
+ }
+ else if (*str == '}')
+ {
+ numBraces--;
+ if (numBraces == 0)
+ {
+ const char *curPos = str;
+ while (str != endPos && strchr("\t ", *++str) != nullptr) { }
+ if (str == endPos)
+ {
+ endPos = curPos + 1;
+ }
+ else
+ {
+ isEncapsulated = false;
+ }
+ break;
+ }
+ }
+ }
+
+ if (isEncapsulated)
{
- case TypeCode::Int32:
- arr[0] = (T)val.iVal;
- lastIndex = 0;
+ pos++;
+ endPos--;
+ }
+ }
+
+ // Read array expression
+ for (;;)
+ {
+ if (lastIndex >= (int)length)
+ {
+ throw ConstructParseException("array too long, max length = %u", (uint32_t)length);
+ }
+
+ // Read the next expression value
+ ExpressionParser parser(gb, pos, endPos, -1);
+ switch (type)
+ {
+ case DataType::Int:
+ arr[++lastIndex] = (T)parser.ParseInteger();
break;
- case TypeCode::Float:
- arr[0] = (T)val.fVal;
- lastIndex = 0;
+ case DataType::UInt:
+ arr[++lastIndex] = (T)parser.ParseUnsigned();
break;
- case TypeCode::Uint32:
- case TypeCode::DriverId:
- arr[0] = (T)val.uVal;
- lastIndex = 0;
+ case DataType::Float:
+ arr[++lastIndex] = (T)parser.ParseFloat();
break;
default:
- throw ConstructParseException("invalid expression type");
+ throw ConstructParseException("Unsupported array data type");
+ }
+ parser.CheckForExtraCharacters(true);
+ pos = parser.GetEndptr();
+
+ if (pos++ >= endPos)
+ {
+ break;
+ }
+ }
+
+ if (doPad && lastIndex == 0)
+ {
+ for (size_t i = 1; i < length; i++)
+ {
+ arr[i] = arr[0];
}
- parser.CheckForExtraCharacters();
+ }
+ else
+ {
+ length = lastIndex + 1;
}
break;
+ }
default:
length = 0;
diff --git a/src/GCodes/GCodeBuffer/BinaryParser.h b/src/GCodes/GCodeBuffer/BinaryParser.h
index 5a4bcc38..3495d9c8 100644
--- a/src/GCodes/GCodeBuffer/BinaryParser.h
+++ b/src/GCodes/GCodeBuffer/BinaryParser.h
@@ -72,7 +72,7 @@ private:
GCodeException ConstructParseException(const char *str, uint32_t param) const noexcept;
size_t AddPadding(size_t bytesRead) const noexcept { return (bytesRead + 3u) & (~3u); }
- template<typename T> void GetArray(T arr[], size_t& length, bool doPad) THROWS(GCodeException) SPEED_CRITICAL;
+ template<typename T> void GetArray(T arr[], size_t& length, bool doPad, DataType type) THROWS(GCodeException) SPEED_CRITICAL;
void WriteParameters(const StringRef& s, bool quoteStrings) const noexcept;
size_t bufferLength;
diff --git a/src/GCodes/GCodeBuffer/ExpressionParser.cpp b/src/GCodes/GCodeBuffer/ExpressionParser.cpp
index 133ed763..0e3ac432 100644
--- a/src/GCodes/GCodeBuffer/ExpressionParser.cpp
+++ b/src/GCodes/GCodeBuffer/ExpressionParser.cpp
@@ -713,10 +713,12 @@ void ExpressionParser::SkipWhiteSpace() noexcept
}
}
-void ExpressionParser::CheckForExtraCharacters() THROWS(GCodeException)
+void ExpressionParser::CheckForExtraCharacters(bool isArrayExpression) THROWS(GCodeException)
{
SkipWhiteSpace();
- if (CurrentCharacter() != 0)
+
+ char c = CurrentCharacter();
+ if (c != 0 && (!isArrayExpression || (c != EXPRESSION_LIST_SEPARATOR && c != LIST_SEPARATOR)))
{
ThrowParseException("Unexpected characters after expression");
}
diff --git a/src/GCodes/GCodeBuffer/ExpressionParser.h b/src/GCodes/GCodeBuffer/ExpressionParser.h
index fc8dc1b3..bfd4de4e 100644
--- a/src/GCodes/GCodeBuffer/ExpressionParser.h
+++ b/src/GCodes/GCodeBuffer/ExpressionParser.h
@@ -26,7 +26,7 @@ public:
uint32_t ParseUnsigned() THROWS(GCodeException);
void SkipWhiteSpace() noexcept;
- void CheckForExtraCharacters() THROWS(GCodeException);
+ void CheckForExtraCharacters(bool isArrayExpression = false) THROWS(GCodeException);
const char *GetEndptr() const noexcept { return currentp; }
private:
diff --git a/src/GCodes/GCodeBuffer/StringParser.cpp b/src/GCodes/GCodeBuffer/StringParser.cpp
index 691be0ac..9247c577 100644
--- a/src/GCodes/GCodeBuffer/StringParser.cpp
+++ b/src/GCodes/GCodeBuffer/StringParser.cpp
@@ -1086,7 +1086,7 @@ void StringParser::GetFloatArray(float arr[], size_t& returnedLength, bool doPad
{
CheckArrayLength(length, returnedLength);
arr[length++] = ReadFloatValue();
- if (gb.buffer[readPointer] != LIST_SEPARATOR)
+ if (gb.buffer[readPointer] != EXPRESSION_LIST_SEPARATOR && gb.buffer[readPointer] != LIST_SEPARATOR)
{
break;
}
@@ -1123,7 +1123,7 @@ void StringParser::GetIntArray(int32_t arr[], size_t& returnedLength, bool doPad
CheckArrayLength(length, returnedLength);
arr[length] = ReadIValue();
length++;
- if (gb.buffer[readPointer] != LIST_SEPARATOR)
+ if (gb.buffer[readPointer] != EXPRESSION_LIST_SEPARATOR && gb.buffer[readPointer] != LIST_SEPARATOR)
{
break;
}
@@ -1159,7 +1159,7 @@ void StringParser::GetUnsignedArray(uint32_t arr[], size_t& returnedLength, bool
CheckArrayLength(length, returnedLength);
arr[length] = ReadUIValue();
length++;
- if (gb.buffer[readPointer] != LIST_SEPARATOR)
+ if (gb.buffer[readPointer] != EXPRESSION_LIST_SEPARATOR && gb.buffer[readPointer] != LIST_SEPARATOR)
{
break;
}
@@ -1196,7 +1196,7 @@ void StringParser::GetDriverIdArray(DriverId arr[], size_t& returnedLength) THRO
CheckArrayLength(length, returnedLength);
arr[length] = ReadDriverIdValue();
length++;
- if (gb.buffer[readPointer] != LIST_SEPARATOR)
+ if (gb.buffer[readPointer] != EXPRESSION_LIST_SEPARATOR && gb.buffer[readPointer] != LIST_SEPARATOR)
{
break;
}
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index 1a932bd0..9c716f3b 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -478,16 +478,10 @@ void GCodes::Spin() noexcept
#if HAS_LINUX_INTERFACE
- if (reprap.UsingLinuxInterface())
+ // Need to check if the print has been stopped by the SBC
+ if (reprap.UsingLinuxInterface() && reprap.GetLinuxInterface().HasPrintStopped())
{
- if (reprap.GetLinuxInterface().HasPrintStarted())
- {
- StartPrinting(true);
- }
- else if (reprap.GetLinuxInterface().HasPrintStopped())
- {
- StopPrint(reprap.GetLinuxInterface().GetPrintStopReason());
- }
+ StopPrint(reprap.GetLinuxInterface().GetPrintStopReason());
}
#endif
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 894630b0..d5dc4af4 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -831,7 +831,9 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
result = MassStorage::Unmount(card, reply);
}
break;
+#endif
+#if HAS_MASS_STORAGE || HAS_LINUX_INTERFACE
case 23: // Set file to print
case 32: // Select file and start SD print
// We now allow a file that is being printed to chain to another file. This is required for the resume-after-power-fail functionality.
@@ -849,7 +851,17 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
{
String<MaxFilenameLength> filename;
gb.GetUnprecedentedString(filename.GetRef());
- if (QueueFileToPrint(filename.c_str(), reply))
+ if (
+#if HAS_LINUX_INTERFACE
+ reprap.UsingLinuxInterface()
+# if HAS_MASS_STORAGE
+ ||
+# endif
+#endif
+#if HAS_MASS_STORAGE
+ QueueFileToPrint(filename.c_str(), reply)
+#endif
+ )
{
reprap.GetPrintMonitor().StartingPrint(filename.c_str());
if (gb.LatestMachineState().compatibility == Compatibility::Marlin)
diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp
index 3f991bf0..5bed126e 100644
--- a/src/GCodes/GCodes3.cpp
+++ b/src/GCodes/GCodes3.cpp
@@ -432,13 +432,7 @@ GCodeResult GCodes::SimulateFile(GCodeBuffer& gb, const StringRef &reply, const
simulationMode = 1;
reprap.GetMove().Simulate(simulationMode);
reprap.GetPrintMonitor().StartingPrint(file.c_str());
-# if HAS_LINUX_INTERFACE
- if (!reprap.UsingLinuxInterface())
-# endif
- {
- // If using a SBC, this is already called when the print file info is set
- StartPrinting(true);
- }
+ StartPrinting(true);
reply.printf("Simulating print of file %s", file.c_str());
return GCodeResult::ok;
}
diff --git a/src/Hardware/ExceptionHandlers.cpp b/src/Hardware/ExceptionHandlers.cpp
index 640c0a41..1413108d 100644
--- a/src/Hardware/ExceptionHandlers.cpp
+++ b/src/Hardware/ExceptionHandlers.cpp
@@ -15,6 +15,12 @@
# include <Reset.h>
#endif
+#if SAME5x
+// Magic address and value to launch the uf2 bootloader on failure, see inc/uf2.h in uf2-samdx1 repository
+# define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))
+# define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set
+#endif
+
// Perform a software reset. 'stk' points to the exception stack (r0 r1 r2 r3 r12 lr pc xPSR) if the cause is an exception, otherwise it is nullptr.
[[noreturn]] void SoftwareReset(SoftwareResetReason initialReason, const uint32_t *stk) noexcept
{
@@ -31,7 +37,8 @@
if (initialReason == SoftwareResetReason::erase)
{
#if SAME5x
- //TODO invalidate flash so the USB bootloader runs
+ // Start from uf2 bootloader next time. This pretends the reset button has been pressed twice in short succession
+ *DBL_TAP_PTR = DBL_TAP_MAGIC;
#else
EraseAndReset();
#endif
diff --git a/src/Linux/DataTransfer.cpp b/src/Linux/DataTransfer.cpp
index 69c09cd9..bd1312fa 100644
--- a/src/Linux/DataTransfer.cpp
+++ b/src/Linux/DataTransfer.cpp
@@ -304,7 +304,7 @@ pre(bytesToTransfer <= inBuffer.limit; bytesToTransfer <= outBuffer.limit)
// Enable SPI and notify the SBC we are ready
#if SAME5x
- SbcSpiSercom->SPI.INTFLAG.reg = 0xFF; // clear any pending interrupts
+ SbcSpiSercom->SPI.INTFLAG.reg = 0xFF; // clear any pending interrupts
SbcSpiSercom->SPI.INTENSET.reg = SERCOM_SPI_INTENSET_SSL; // enable the start of transfer (SS low) interrupt
SbcSpiSercom->SPI.CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE;
while (SbcSpiSercom->SPI.SYNCBUSY.reg & (SERCOM_SPI_SYNCBUSY_SWRST | SERCOM_SPI_SYNCBUSY_ENABLE)) { };
@@ -494,9 +494,9 @@ void DataTransfer::Init() noexcept
}
}
-void DataTransfer::SetSBCTask(TaskHandle handle) noexcept
+void DataTransfer::InitFromTask() noexcept
{
- linuxTaskHandle = handle;
+ linuxTaskHandle = TaskBase::GetCallerTaskHandle();
}
void DataTransfer::Diagnostics(MessageType mtype) noexcept
diff --git a/src/Linux/DataTransfer.h b/src/Linux/DataTransfer.h
index cf1d47d6..c7f9fa2d 100644
--- a/src/Linux/DataTransfer.h
+++ b/src/Linux/DataTransfer.h
@@ -30,7 +30,7 @@ class DataTransfer
public:
DataTransfer() noexcept;
void Init() noexcept;
- void SetSBCTask(TaskHandle handle) noexcept;
+ void InitFromTask() noexcept;
void Diagnostics(MessageType mtype) noexcept;
bool IsConnected() const noexcept; // Check if the connection to DCS is live
diff --git a/src/Linux/LinuxInterface.cpp b/src/Linux/LinuxInterface.cpp
index c442ffa5..9469c139 100644
--- a/src/Linux/LinuxInterface.cpp
+++ b/src/Linux/LinuxInterface.cpp
@@ -39,6 +39,7 @@ constexpr size_t SBCTaskStackWords = 1000; // debug builds use more stack
#else
constexpr size_t SBCTaskStackWords = 820;
#endif
+constexpr uint32_t LinuxYieldTimeout = 10;
static Task<SBCTaskStackWords> *sbcTask;
@@ -49,7 +50,7 @@ extern "C" [[noreturn]] void SBCTaskStart(void * pvParameters) noexcept
LinuxInterface::LinuxInterface() noexcept : isConnected(false), numDisconnects(0), numTimeouts(0),
maxDelayBetweenTransfers(SpiTransferDelay), numMaxEvents(SpiEventsRequired), delaying(false), numEvents(0),
- reportPause(false), reportPauseWritten(false), printStarted(false), printStopped(false),
+ reportPause(false), reportPauseWritten(false), printStopped(false),
codeBuffer(nullptr), rxPointer(0), txPointer(0), txEnd(0), sendBufferUpdate(true), iapWritePointer(IAP_IMAGE_START),
waitingForFileChunk(false), fileMutex(), fileSemaphore(), fileOperation(FileOperation::none), fileOperationPending(false)
#ifdef TRACK_FILE_CODES
@@ -94,12 +95,12 @@ void LinuxInterface::Spin() noexcept
[[noreturn]] void LinuxInterface::TaskLoop() noexcept
{
- transfer.SetSBCTask(sbcTask);
+ transfer.InitFromTask();
transfer.StartNextTransfer();
- bool writingIap = false, hadReset = false, skipNextDelay = false;
+
+ bool writingIap = false, isReady = false, hadReset = false, skipNextDelay = false;
for (;;)
{
- bool isReady = false;
if (hadReset)
{
isReady = true;
@@ -110,6 +111,10 @@ void LinuxInterface::Spin() noexcept
isReady = true;
hadReset = isConnected && transfer.LinuxHadReset();
}
+ else
+ {
+ isReady = false;
+ }
if (isReady && !hadReset)
{
@@ -280,7 +285,6 @@ void LinuxInterface::Spin() noexcept
String<MaxFilenameLength> filename;
transfer.ReadPrintStartedInfo(packet->length, filename.GetRef(), fileInfo);
reprap.GetPrintMonitor().SetPrintingFileInfo(filename.c_str(), fileInfo);
- printStarted = true;
break;
}
@@ -292,7 +296,7 @@ void LinuxInterface::Spin() noexcept
{
// Just mark the print file as finished
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel::File);
- MutexLocker locker(gb->mutex, 10);
+ MutexLocker locker(gb->mutex, LinuxYieldTimeout);
if (locker)
{
gb->SetPrintFinished();
@@ -330,7 +334,7 @@ void LinuxInterface::Spin() noexcept
}
else
{
- MutexLocker locker(gb->mutex, 10);
+ MutexLocker locker(gb->mutex, LinuxYieldTimeout);
if (locker)
{
if (error)
@@ -408,7 +412,7 @@ void LinuxInterface::Spin() noexcept
if (channel.IsValid())
{
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- MutexLocker locker(gb->mutex, 10);
+ MutexLocker locker(gb->mutex, LinuxYieldTimeout);
if (locker && reprap.GetGCodes().LockMovementAndWaitForStandstill(*gb))
{
transfer.WriteLocked(channel);
@@ -432,7 +436,7 @@ void LinuxInterface::Spin() noexcept
if (channel.IsValid())
{
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- MutexLocker locker(gb->mutex, 10);
+ MutexLocker locker(gb->mutex, LinuxYieldTimeout);
if (locker)
{
reprap.GetGCodes().UnlockAll(*gb);
@@ -523,7 +527,7 @@ void LinuxInterface::Spin() noexcept
try
{
// Evaluate the expression and send the result to DSF
- MutexLocker lock(gb->mutex, 10);
+ MutexLocker lock(gb->mutex, LinuxYieldTimeout);
if (lock)
{
ExpressionParser parser(*gb, expression.c_str(), expression.c_str() + expression.strlen());
@@ -620,7 +624,7 @@ void LinuxInterface::Spin() noexcept
gb->ResolveMacroRequest(true, false);
}
- MutexLocker locker(gb->mutex, 10);
+ MutexLocker locker(gb->mutex, LinuxYieldTimeout);
if (locker)
{
// Note that we do not call StopPrint here or set any other variables; DSF already does that
@@ -654,7 +658,7 @@ void LinuxInterface::Spin() noexcept
}
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- MutexLocker lock(gb->mutex, 10);
+ MutexLocker lock(gb->mutex, LinuxYieldTimeout);
if (!lock)
{
packetAcknowledged = false;
@@ -734,7 +738,7 @@ void LinuxInterface::Spin() noexcept
}
GCodeBuffer * const gb = reprap.GetGCodes().GetGCodeBuffer(channel);
- MutexLocker lock(gb->mutex, 10);
+ MutexLocker lock(gb->mutex, LinuxYieldTimeout);
if (!lock)
{
packetAcknowledged = false;
@@ -865,8 +869,6 @@ void LinuxInterface::Spin() noexcept
if (!writingIap && !skipNextDelay && numEvents < numMaxEvents && !waitingForFileChunk &&
!fileOperationPending && (fileOperation != FileOperation::write || numFileWriteRequests == 0))
{
- TaskBase::ClearNotifyCount();
-
delaying = true;
if (!TaskBase::Take(maxDelayBetweenTransfers))
{
@@ -901,7 +903,7 @@ void LinuxInterface::Spin() noexcept
sendBufferUpdate = !transfer.WriteCodeBufferUpdate(bufferSpace);
}
- if (!writingIap) // it's not safe to access GCodes once we have started writing the IAP
+ if (!writingIap) // it's not safe to access other resources once we have started writing the IAP
{
// Get another chunk of the file being requested
if (waitingForFileChunk &&
@@ -1010,7 +1012,7 @@ void LinuxInterface::Spin() noexcept
// Deal with other requests unless we are still waiting in a semaphore
if (!gb->IsWaitingForMacro())
{
- MutexLocker gbLock(gb->mutex, 10);
+ MutexLocker gbLock(gb->mutex, LinuxYieldTimeout);
if (gbLock)
{
if (gb->GetChannel() != GCodeChannel::Daemon)
@@ -1080,7 +1082,7 @@ void LinuxInterface::Spin() noexcept
if (reportPause)
{
GCodeBuffer * const fileGCode = reprap.GetGCodes().GetGCodeBuffer(GCodeChannel::File);
- MutexLocker locker(fileGCode->mutex, 10);
+ MutexLocker locker(fileGCode->mutex, LinuxYieldTimeout);
if (locker && transfer.WritePrintPaused(pauseFilePosition, pauseReason))
{
fileGCode->Invalidate();
@@ -1157,7 +1159,7 @@ void LinuxInterface::Spin() noexcept
if (hadReset)
{
// Let the main task invalidate resources
- RTOSIface::Yield();
+ TaskBase::Take(LinuxYieldTimeout);
}
else
{
@@ -1168,6 +1170,11 @@ void LinuxInterface::Spin() noexcept
else if (!writingIap)
{
// A transfer is being performed but it has not finished yet
+ TaskBase::Take(LinuxYieldTimeout);
+ }
+ else
+ {
+ // IAP binary is being written, only keep equal or higher priority tasks running
RTOSIface::Yield();
}
}
diff --git a/src/Linux/LinuxInterface.h b/src/Linux/LinuxInterface.h
index b28d88d2..74936723 100644
--- a/src/Linux/LinuxInterface.h
+++ b/src/Linux/LinuxInterface.h
@@ -46,7 +46,6 @@ public:
void EventOccurred(bool timeCritical = false) noexcept; // Called when a new event has happened. It can optionally start off a new transfer immediately
GCodeResult HandleM576(GCodeBuffer& gb, const StringRef& reply) noexcept; // Set the SPI communication parameters
- bool HasPrintStarted();
bool HasPrintStopped();
StopPrintReason GetPrintStopReason() const { return printStopReason; }
bool FillBuffer(GCodeBuffer &gb) noexcept; // Try to fill up the G-code buffer with the next available G-code
@@ -80,7 +79,7 @@ private:
GCodeFileInfo fileInfo;
FilePosition pauseFilePosition;
PrintPausedReason pauseReason;
- bool reportPause, reportPauseWritten, printStarted, printStopped;
+ bool reportPause, reportPauseWritten, printStopped;
StopPrintReason printStopReason;
char *codeBuffer;
@@ -147,17 +146,6 @@ inline void LinuxInterface::SetPauseReason(FilePosition position, PrintPausedRea
reportPause = true;
}
-inline bool LinuxInterface::HasPrintStarted()
-{
- TaskCriticalSectionLocker locker;
- if (printStarted)
- {
- printStarted = false;
- return true;
- }
- return false;
-}
-
inline bool LinuxInterface::HasPrintStopped()
{
TaskCriticalSectionLocker locker;
diff --git a/src/Platform/TaskPriorities.h b/src/Platform/TaskPriorities.h
index 36545a55..a30743c0 100644
--- a/src/Platform/TaskPriorities.h
+++ b/src/Platform/TaskPriorities.h
@@ -14,7 +14,7 @@ namespace TaskPriority
constexpr int IdlePriority = 0;
constexpr int SpinPriority = 1; // priority for tasks that rarely block
#if HAS_LINUX_INTERFACE
- constexpr int SbcPriority = 1; // priority for SBC task. TODO increase this when we are certain that it never spins.
+ constexpr int SbcPriority = 2; // priority for SBC task
#endif
#if defined(LPC_NETWORKING)
constexpr int TcpPriority = 2;
diff --git a/src/PrintMonitor/PrintMonitor.cpp b/src/PrintMonitor/PrintMonitor.cpp
index 925897fd..07a4dae3 100644
--- a/src/PrintMonitor/PrintMonitor.cpp
+++ b/src/PrintMonitor/PrintMonitor.cpp
@@ -292,11 +292,11 @@ void PrintMonitor::StartingPrint(const char* filename) noexcept
#if HAS_MASS_STORAGE
WriteLocker locker(printMonitorLock);
MassStorage::CombineName(filenameBeingPrinted.GetRef(), platform.GetGCodeDir(), filename);
- printingFileParsed = false;
# if HAS_LINUX_INTERFACE
if (!reprap.UsingLinuxInterface())
# endif
{
+ printingFileParsed = false;
if (MassStorage::GetFileInfo(filenameBeingPrinted.c_str(), printingFileInfo, false) != GCodeResult::notFinished)
{
UpdatePrintingFileInfo();