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-12-13 20:14:31 +0300
committerDavid Crocker <dcrocker@eschertech.com>2021-12-13 20:14:31 +0300
commita72cf81b4b4fd22b464dff59c4ca08a3b1df38fd (patch)
tree1298bfa2a45d2098d91097208b87963181db8da3
parent2133c443728f7ed9a1764697551f1d5ff4a42a42 (diff)
Bug fixes to event handling
-rw-r--r--src/GCodes/GCodes.cpp47
-rw-r--r--src/GCodes/GCodes3.cpp15
-rw-r--r--src/Platform/Event.cpp24
-rw-r--r--src/Platform/Event.h5
-rw-r--r--src/Platform/Heap.cpp4
-rw-r--r--src/Platform/Heap.h2
-rw-r--r--src/Platform/Platform.cpp3
7 files changed, 57 insertions, 43 deletions
diff --git a/src/GCodes/GCodes.cpp b/src/GCodes/GCodes.cpp
index e40bb387..72ea8fb4 100644
--- a/src/GCodes/GCodes.cpp
+++ b/src/GCodes/GCodes.cpp
@@ -433,40 +433,29 @@ void GCodes::Spin() noexcept
CheckTriggers();
- // Get the GCodeBuffer that we want to process a command from. Use round-robin scheduling but give priority to auto-pause.
- GCodeBuffer *gbp = autoPauseGCode;
- if (!autoPauseGCode->IsCompletelyIdle()
-#if HAS_MASS_STORAGE || HAS_SBC_INTERFACE || HAS_EMBEDDED_FILES
- || autoPauseGCode->LatestMachineState().DoingFile()
-#endif
- ) // if autoPause is active
- {
- (void)SpinGCodeBuffer(*autoPauseGCode);
- (void)SpinGCodeBuffer(*queuedGCode); // autopause sometimes to wait for queued GCodes to complete, so spin queuedGCodes too to avoid lockup
- }
- else
+ // The autoPause buffer has priority, so spin that one first. It may have to wait for other buffers to release locks etc.
+ (void)SpinGCodeBuffer(*autoPauseGCode);
+
+ // Use round-robin scheduling for the other input sources
+ // Scan the GCode input channels until we find one that we can do some useful work with, or we have scanned them all.
+ // The idea is that when a single GCode input channel is active, we do some useful work every time we come through this polling loop, not once every N times (N = number of input channels)
+ const size_t originalNextGCodeSource = nextGcodeSource;
+ do
{
- // Scan the GCode input channels until we find one that we can do some useful work with, or we have scanned them all.
- // The idea is that when a single GCode input channel is active, we do some useful work every time we come through this polling loop, not once every N times (N = number of input channels)
- const size_t originalNextGCodeSource = nextGcodeSource;
- do
+ GCodeBuffer * const gbp = gcodeSources[nextGcodeSource];
+ ++nextGcodeSource; // move on to the next gcode source ready for next time
+ if (nextGcodeSource == ARRAY_SIZE(gcodeSources) - 1) // the last one is autoPauseGCode, so don't do it again
{
- gbp = gcodeSources[nextGcodeSource];
- ++nextGcodeSource; // move on to the next gcode source ready for next time
- if (nextGcodeSource == ARRAY_SIZE(gcodeSources) - 1) // the last one is autoPauseGCode, so don't do it again
- {
- nextGcodeSource = 0;
- }
- if (isFlashingPanelDue && gbp == auxGCode) // Skip auxGCode while flashing PanelDue is in progress
- {
- continue;
- }
- if (gbp != nullptr && SpinGCodeBuffer(*gbp)) // if we did something useful
+ nextGcodeSource = 0;
+ }
+ if (gbp != nullptr && (gbp != auxGCode || !isFlashingPanelDue)) // skip auxGCode while flashing PanelDue is in progress
+ {
+ if (SpinGCodeBuffer(*gbp)) // if we did something useful
{
break;
}
- } while (nextGcodeSource != originalNextGCodeSource);
- }
+ }
+ } while (nextGcodeSource != originalNextGCodeSource);
#if HAS_SBC_INTERFACE
diff --git a/src/GCodes/GCodes3.cpp b/src/GCodes/GCodes3.cpp
index c534b5bc..1f5b432a 100644
--- a/src/GCodes/GCodes3.cpp
+++ b/src/GCodes/GCodes3.cpp
@@ -1936,10 +1936,17 @@ void GCodes::ProcessEvent(GCodeBuffer& gb) noexcept
// It's a serious event that causes the print to pause by default, so send an alert
String<StringLength100> eventText;
Event::GetTextDescription(eventText.GetRef());
- platform.SendAlert(GenericMessage, eventText.c_str(), "Printing paused", 1, 0.0, AxesBitmap());
-
- // We are going to pause. It may need to wait for the movement lock, so do it in a new state.
- gb.SetState(GCodeState::processingEvent);
+ const bool isPrinting = IsReallyPrinting();
+ platform.SendAlert(GenericMessage, eventText.c_str(), (isPrinting) ? "Printing paused" : "Event notification", 1, 0.0, AxesBitmap());
+ if (IsReallyPrinting())
+ {
+ // We are going to pause. It may need to wait for the movement lock, so do it in a new state.
+ gb.SetState(GCodeState::processingEvent);
+ }
+ else
+ {
+ Event::FinishedProcessing();
+ }
}
}
diff --git a/src/Platform/Event.cpp b/src/Platform/Event.cpp
index 4757bbe8..5439bed7 100644
--- a/src/Platform/Event.cpp
+++ b/src/Platform/Event.cpp
@@ -5,15 +5,19 @@
* Author: David
*/
+#include <Platform/Platform.h>
#include <Platform/Event.h>
#include <RepRapFirmware.h>
#include <ObjectModel/ObjectModel.h>
#include <ObjectModel/Variable.h>
Event *_ecv_null Event::eventsPending = nullptr;
+unsigned int Event::eventsQueued = 0;
+unsigned int Event::eventsProcessed = 0;
-inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint8_t devNum, CanAddress p_ba, const char *_ecv_array format, va_list vargs) noexcept
- : next(pnext), param(p_param), type(et), boardAddress(p_ba), deviceNumber(devNum), isBeingProcessed(false)
+// Private constructor, inline because it is only called from one place
+inline Event::Event(Event *_ecv_null p_next, EventType et, uint16_t p_param, uint8_t devNum, CanAddress p_ba, const char *_ecv_array format, va_list vargs) noexcept
+ : next(p_next), param(p_param), type(et), boardAddress(p_ba), deviceNumber(devNum), isBeingProcessed(false)
{
text.vprintf(format, vargs);
}
@@ -33,17 +37,17 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint
/*static*/ bool Event::AddEventV(EventType et, uint16_t p_param, uint8_t devNum, CanAddress p_ba, const char *_ecv_array format, va_list vargs) noexcept
{
// Search for similar events already pending or being processed.
- // An event is 'similar' if it has the same type, device number and parameter even if the text is different.
+ // An event is 'similar' if it has the same type, device number, CAN address and parameter even if the text is different.
TaskCriticalSectionLocker lock;
Event** pe = &eventsPending;
while (*pe != nullptr && (et >= (*pe)->type || (*pe)->isBeingProcessed)) // while the next event in the list has same or higher priority than the new one
{
- if (et == (*pe)->type && devNum == (*pe)->deviceNumber
+ if (et == (*pe)->type && devNum == (*pe)->deviceNumber &&(*pe)->param == p_param
#if SUPPORT_CAN_EXPANSION
&& p_ba == (*pe)->boardAddress
#endif
- )
+ )
{
return false; // there is a similar event already in the queue
}
@@ -52,6 +56,7 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint
// We didn't find a similar event, so add the new one
*pe = new Event(*pe, et, p_param, p_ba, devNum, format, vargs);
+ ++eventsQueued;
return true;
}
@@ -128,6 +133,7 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint
{
eventsPending = ev->next;
delete ev;
+ ++eventsProcessed;
}
}
@@ -141,7 +147,7 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint
{
case EventType::heater_fault:
{
- const char *_ecv_array heaterFaultText = HeaterFaultText[max<size_t>(ep->param, ARRAY_SIZE(HeaterFaultText) - 1)];
+ const char *_ecv_array heaterFaultText = HeaterFaultText[min<size_t>(ep->param, ARRAY_SIZE(HeaterFaultText) - 1)];
str.printf("Heater %u fault: %s%s", ep->deviceNumber, heaterFaultText, ep->text.c_str());
}
return ErrorMessage;
@@ -191,4 +197,10 @@ inline Event::Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint
return ErrorMessage;
}
+// Generate diagnostic data
+/*static*/ void Event::Diagnostics(MessageType mt, Platform& p) noexcept
+{
+ p.MessageF(mt, "Events: %u queued, %u completed\n", eventsQueued, eventsProcessed);
+}
+
// End
diff --git a/src/Platform/Event.h b/src/Platform/Event.h
index edeb12b2..81fb2a60 100644
--- a/src/Platform/Event.h
+++ b/src/Platform/Event.h
@@ -63,6 +63,9 @@ public:
// Mark the highest priority event as completed
static void FinishedProcessing() noexcept;
+ // Generate diagnostic data
+ static void Diagnostics(MessageType mt, Platform& p) noexcept;
+
private:
Event(Event *_ecv_null pnext, EventType et, uint16_t p_param, uint8_t devNum, CanAddress p_ba, const char *_ecv_array format, va_list vargs) noexcept;
@@ -75,6 +78,8 @@ private:
String<50> text; // additional info to display to the user
static Event * _ecv_null eventsPending; // linked list of events waiting to be processed
+ static unsigned int eventsQueued;
+ static unsigned int eventsProcessed;
};
#endif /* SRC_PLATFORM_EVENT_H_ */
diff --git a/src/Platform/Heap.cpp b/src/Platform/Heap.cpp
index aa61ff45..fb819222 100644
--- a/src/Platform/Heap.cpp
+++ b/src/Platform/Heap.cpp
@@ -486,7 +486,7 @@ size_t StringHandle::GetLength() const noexcept
return strlen(slotPtr->storage->data);
}
-/*static*/ void StringHandle::Diagnostics(MessageType mt) noexcept
+/*static*/ void StringHandle::Diagnostics(MessageType mt, Platform& p) noexcept
{
String<StringLength256> temp;
const bool ok = CheckIntegrity(temp.GetRef());
@@ -496,7 +496,7 @@ size_t StringHandle::GetLength() const noexcept
}
temp.catf(", handles allocated/used %u/%u, heap memory allocated/used/recyclable %u/%u/%u, gc cycles %u\n",
handlesAllocated, (unsigned int)handlesUsed, heapAllocated, heapUsed, (unsigned int)heapToRecycle, gcCyclesDone);
- reprap.GetPlatform().Message(mt, temp.c_str());
+ p.Message(mt, temp.c_str());
}
// AutoStringHandle members
diff --git a/src/Platform/Heap.h b/src/Platform/Heap.h
index 58b449cc..5f22993f 100644
--- a/src/Platform/Heap.h
+++ b/src/Platform/Heap.h
@@ -44,7 +44,7 @@ public:
// static size_t GetIndexSpace() noexcept { return totalIndexSpace; }
// static size_t GetHeapSpace() noexcept { return totalHeapSpace; }
static bool CheckIntegrity(const StringRef& errmsg) noexcept;
- static void Diagnostics(MessageType mt) noexcept;
+ static void Diagnostics(MessageType mt, Platform& p) noexcept;
protected:
void InternalAssign(const char *s, size_t len) noexcept;
diff --git a/src/Platform/Platform.cpp b/src/Platform/Platform.cpp
index cda05c8e..58dc2a2a 100644
--- a/src/Platform/Platform.cpp
+++ b/src/Platform/Platform.cpp
@@ -1756,7 +1756,8 @@ void Platform::Diagnostics(MessageType mtype) noexcept
ResetVoltageMonitors();
- StringHandle::Diagnostics(mtype);
+ StringHandle::Diagnostics(mtype, *this);
+ Event::Diagnostics(mtype, *this);
// Show the motor position and stall status
for (size_t drive = 0; drive < NumDirectDrivers; ++drive)