diff options
author | David Crocker <dcrocker@eschertech.com> | 2021-12-13 20:14:31 +0300 |
---|---|---|
committer | David Crocker <dcrocker@eschertech.com> | 2021-12-13 20:14:31 +0300 |
commit | a72cf81b4b4fd22b464dff59c4ca08a3b1df38fd (patch) | |
tree | 1298bfa2a45d2098d91097208b87963181db8da3 | |
parent | 2133c443728f7ed9a1764697551f1d5ff4a42a42 (diff) |
Bug fixes to event handling
-rw-r--r-- | src/GCodes/GCodes.cpp | 47 | ||||
-rw-r--r-- | src/GCodes/GCodes3.cpp | 15 | ||||
-rw-r--r-- | src/Platform/Event.cpp | 24 | ||||
-rw-r--r-- | src/Platform/Event.h | 5 | ||||
-rw-r--r-- | src/Platform/Heap.cpp | 4 | ||||
-rw-r--r-- | src/Platform/Heap.h | 2 | ||||
-rw-r--r-- | src/Platform/Platform.cpp | 3 |
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) |