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>2021-07-30 10:17:45 +0300
committerDavid Crocker <dcrocker@eschertech.com>2021-07-30 10:17:45 +0300
commit7c5ef6000bdeebfa8d51c0ead656ea554f1eb882 (patch)
tree170bd0a4bc3f8282d6a97f16498b356a64b2f925
parent7b0dde7831f35450b6c5c077b00821b118eb9570 (diff)
parentd7fd1866ffbfbb87229fa89ae2c7add48307cd8a (diff)
Merge branch 'v3-chrishamm' into 3.4-input-shaping
-rw-r--r--src/CAN/CanInterface.cpp2
-rw-r--r--src/Configuration.h1
-rw-r--r--src/GCodes/GCodeBuffer/ExpressionParser.cpp6
-rw-r--r--src/GCodes/GCodeBuffer/ExpressionParser.h2
-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
14 files changed, 65 insertions, 60 deletions
diff --git a/src/CAN/CanInterface.cpp b/src/CAN/CanInterface.cpp
index 9b42ab44..d7d93946 100644
--- a/src/CAN/CanInterface.cpp
+++ b/src/CAN/CanInterface.cpp
@@ -1191,7 +1191,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 14878668..89765445 100644
--- a/src/Configuration.h
+++ b/src/Configuration.h
@@ -383,6 +383,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/ExpressionParser.cpp b/src/GCodes/GCodeBuffer/ExpressionParser.cpp
index 60d5db79..0c65a39c 100644
--- a/src/GCodes/GCodeBuffer/ExpressionParser.cpp
+++ b/src/GCodes/GCodeBuffer/ExpressionParser.cpp
@@ -812,10 +812,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 25ad7470..adfff7c7 100644
--- a/src/GCodes/GCodeBuffer/ExpressionParser.h
+++ b/src/GCodes/GCodeBuffer/ExpressionParser.h
@@ -33,7 +33,7 @@ public:
void ParseDriverIdArray(DriverId arr[], size_t& length) 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/GCodes.cpp b/src/GCodes/GCodes.cpp
index a4c36491..85e88c33 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -479,16 +479,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 84cee85f..ee50c201 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -829,7 +829,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.
@@ -847,7 +849,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 74ba76a9..42388844 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();