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>2020-10-18 20:37:11 +0300
committerDavid Crocker <dcrocker@eschertech.com>2020-10-18 20:37:11 +0300
commita5726e9fec70ea60322702d112dff5a0bde02538 (patch)
tree7282d7b20ea6411b8d8a9148292e5da04855880f
parent3341fd09923beb127e9088910808874c3fb24669 (diff)
Added out-of-memory handler for new CoreNG
-rw-r--r--src/GCodes/GCodes2.cpp4
-rw-r--r--src/Hardware/ExceptionHandlers.cpp47
-rw-r--r--src/Hardware/ExceptionHandlers.h5
-rw-r--r--src/Hardware/SoftwareReset.cpp4
-rw-r--r--src/Hardware/SoftwareReset.h5
-rw-r--r--src/Linux/LinuxInterface.cpp2
-rw-r--r--src/RepRap.cpp2
-rw-r--r--src/Version.h2
8 files changed, 40 insertions, 31 deletions
diff --git a/src/GCodes/GCodes2.cpp b/src/GCodes/GCodes2.cpp
index 189773af..d5d36710 100644
--- a/src/GCodes/GCodes2.cpp
+++ b/src/GCodes/GCodes2.cpp
@@ -4344,14 +4344,14 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
reprap.EmergencyStop(); // this disables heaters and drives - Duet WiFi pre-production boards need drives disabled here
{
- uint16_t reason = (uint16_t)SoftwareResetReason::user;
+ SoftwareResetReason reason = SoftwareResetReason::user;
if (gb.Seen('P'))
{
String<StringLength20> eraseString;
gb.GetQuotedString(eraseString.GetRef());
if (eraseString.Equals("ERASE"))
{
- reason = (uint16_t)SoftwareResetReason::erase;
+ reason = SoftwareResetReason::erase;
}
}
SoftwareReset(reason); // doesn't return
diff --git a/src/Hardware/ExceptionHandlers.cpp b/src/Hardware/ExceptionHandlers.cpp
index e53009ff..11958f11 100644
--- a/src/Hardware/ExceptionHandlers.cpp
+++ b/src/Hardware/ExceptionHandlers.cpp
@@ -12,7 +12,7 @@
#include <Cache.h>
// 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.
-void SoftwareReset(uint16_t reason, const uint32_t *stk) noexcept
+[[noreturn]] void SoftwareReset(SoftwareResetReason initialReason, const uint32_t *stk) noexcept
{
cpu_irq_disable(); // disable interrupts before we call any flash functions. We don't enable them again.
WatchdogReset(); // kick the watchdog
@@ -23,7 +23,8 @@ void SoftwareReset(uint16_t reason, const uint32_t *stk) noexcept
Cache::Disable();
- if (reason == (uint16_t)SoftwareResetReason::erase)
+ uint16_t fullReason = (uint16_t)initialReason;
+ if (initialReason == SoftwareResetReason::erase)
{
#if SAME5x
//TODO invalidate flash so the USB bootloader runs
@@ -33,11 +34,11 @@ void SoftwareReset(uint16_t reason, const uint32_t *stk) noexcept
}
else
{
- if (reason != (uint16_t)SoftwareResetReason::user)
+ if (initialReason != SoftwareResetReason::user)
{
if (SERIAL_MAIN_DEVICE.canWrite() == 0)
{
- reason |= (uint16_t)SoftwareResetReason::inUsbOutput; // if we are resetting because we are stuck in a Spin function, record whether we are trying to send to USB
+ fullReason |= (uint16_t)SoftwareResetReason::inUsbOutput; // if we are resetting because we are stuck in a Spin function, record whether we are trying to send to USB
}
#if HAS_AUX_DEVICES
@@ -47,20 +48,20 @@ void SoftwareReset(uint16_t reason, const uint32_t *stk) noexcept
# endif
)
{
- reason |= (uint16_t)SoftwareResetReason::inAuxOutput; // if we are resetting because we are stuck in a Spin function, record whether we are trying to send to aux
+ fullReason |= (uint16_t)SoftwareResetReason::inAuxOutput; // if we are resetting because we are stuck in a Spin function, record whether we are trying to send to aux
}
#endif
}
- reason |= (uint8_t)reprap.GetSpinningModule();
+ fullReason |= (uint8_t)reprap.GetSpinningModule();
if (reprap.GetPlatform().WasDeliberateError())
{
- reason |= (uint16_t)SoftwareResetReason::deliberate;
+ fullReason |= (uint16_t)SoftwareResetReason::deliberate;
}
// Record the reason for the software reset
NonVolatileMemory mem;
SoftwareResetData * const srd = mem.AllocateResetDataSlot();
- srd->Populate(reason, stk);
+ srd->Populate(fullReason, stk);
mem.EnsureWritten();
}
@@ -73,12 +74,18 @@ void SoftwareReset(uint16_t reason, const uint32_t *stk) noexcept
for(;;) {}
}
+[[noreturn]] void OutOfMemoryHandler() noexcept
+{
+ register const uint32_t * stack_ptr asm ("sp");
+ SoftwareReset(SoftwareResetReason::outOfMemory, stack_ptr);
+}
+
// Exception handlers
// By default the Usage Fault, Bus Fault and Memory Management fault handlers are not enabled,
// so they escalate to a Hard Fault and we don't need to provide separate exception handlers for them.
extern "C" [[noreturn]] void hardFaultDispatcher(const uint32_t *pulFaultStackAddress) noexcept
{
- SoftwareReset((uint16_t)SoftwareResetReason::hardFault, pulFaultStackAddress);
+ SoftwareReset(SoftwareResetReason::hardFault, pulFaultStackAddress);
}
// The fault handler implementation calls a function called hardFaultDispatcher()
@@ -102,7 +109,7 @@ void HardFault_Handler() noexcept
extern "C" [[noreturn]] void memManageDispatcher(const uint32_t *pulFaultStackAddress) noexcept
{
- SoftwareReset((uint16_t)SoftwareResetReason::memFault, pulFaultStackAddress);
+ SoftwareReset(SoftwareResetReason::memFault, pulFaultStackAddress);
}
// The fault handler implementation calls a function called memManageDispatcher()
@@ -126,7 +133,7 @@ void MemManage_Handler() noexcept
extern "C" [[noreturn]] void wdtFaultDispatcher(const uint32_t *pulFaultStackAddress) noexcept
{
- SoftwareReset((uint16_t)SoftwareResetReason::wdtFault, pulFaultStackAddress);
+ SoftwareReset(SoftwareResetReason::wdtFault, pulFaultStackAddress);
}
#ifdef __LPC17xx__
@@ -154,7 +161,7 @@ void WDT_Handler() noexcept
extern "C" [[noreturn]] void otherFaultDispatcher(const uint32_t *pulFaultStackAddress) noexcept
{
- SoftwareReset((uint16_t)SoftwareResetReason::otherFault, pulFaultStackAddress);
+ SoftwareReset(SoftwareResetReason::otherFault, pulFaultStackAddress);
}
// 2017-05-25: A user is getting 'otherFault' reports, so now we do a stack dump for those too.
@@ -177,15 +184,15 @@ void OtherFault_Handler() noexcept
// We could set up the following fault handlers to retrieve the program counter in the same way as for a Hard Fault,
// however these exceptions are unlikely to occur, so for now we just report the exception type.
-extern "C" [[noreturn]] void NMI_Handler () noexcept { SoftwareReset((uint16_t)SoftwareResetReason::NMI); }
-extern "C" [[noreturn]] void UsageFault_Handler () noexcept { SoftwareReset((uint16_t)SoftwareResetReason::usageFault); }
+extern "C" [[noreturn]] void NMI_Handler () noexcept { SoftwareReset(SoftwareResetReason::NMI); }
+extern "C" [[noreturn]] void UsageFault_Handler () noexcept { SoftwareReset(SoftwareResetReason::usageFault); }
extern "C" [[noreturn]] void DebugMon_Handler () noexcept __attribute__ ((alias("OtherFault_Handler")));
// FreeRTOS hooks that we need to provide
extern "C" [[noreturn]] void stackOverflowDispatcher(const uint32_t *pulFaultStackAddress, char* pcTaskName) noexcept
{
- SoftwareReset((uint16_t)SoftwareResetReason::stackOverflow, pulFaultStackAddress);
+ SoftwareReset(SoftwareResetReason::stackOverflow, pulFaultStackAddress);
}
extern "C" [[noreturn]] void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) noexcept __attribute((naked));
@@ -205,7 +212,7 @@ void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName) noexce
extern "C" [[noreturn]] void assertCalledDispatcher(const uint32_t *pulFaultStackAddress) noexcept
{
- SoftwareReset((uint16_t)SoftwareResetReason::assertCalled, pulFaultStackAddress);
+ SoftwareReset(SoftwareResetReason::assertCalled, pulFaultStackAddress);
}
extern "C" [[noreturn]] void vAssertCalled(uint32_t line, const char *file) noexcept __attribute((naked));
@@ -229,7 +236,7 @@ void vAssertCalled(uint32_t line, const char *file) noexcept
#ifdef __LPC17xx__
[[noreturn]] void applicationMallocFailedCalledDispatcher(const uint32_t *pulFaultStackAddress) noexcept
{
- reprap.SoftwareReset((uint16_t)SoftwareResetReason::assertCalled, pulFaultStackAddress);
+ reprap.SoftwareReset(SoftwareResetReason::assertCalled, pulFaultStackAddress);
}
[[noreturn]] extern "C" void vApplicationMallocFailedHook() noexcept __attribute((naked));
@@ -257,7 +264,7 @@ namespace std
[[noreturn]] void Terminate() noexcept
{
register const uint32_t * stack_ptr asm ("sp");
- SoftwareReset((uint16_t)SoftwareResetReason::terminateCalled, stack_ptr);
+ SoftwareReset(SoftwareResetReason::terminateCalled, stack_ptr);
}
namespace __cxxabiv1
@@ -268,13 +275,13 @@ namespace __cxxabiv1
extern "C" [[noreturn]] void __cxa_pure_virtual() noexcept
{
register const uint32_t * stack_ptr asm ("sp");
- SoftwareReset((uint16_t)SoftwareResetReason::pureVirtual, stack_ptr);
+ SoftwareReset(SoftwareResetReason::pureOrDeletedVirtual, stack_ptr);
}
extern "C" [[noreturn]] void __cxa_deleted_virtual() noexcept
{
register const uint32_t * stack_ptr asm ("sp");
- SoftwareReset((uint16_t)SoftwareResetReason::deletedVirtual, stack_ptr);
+ SoftwareReset(SoftwareResetReason::pureOrDeletedVirtual, stack_ptr);
}
// End
diff --git a/src/Hardware/ExceptionHandlers.h b/src/Hardware/ExceptionHandlers.h
index a5082add..e5141f71 100644
--- a/src/Hardware/ExceptionHandlers.h
+++ b/src/Hardware/ExceptionHandlers.h
@@ -8,8 +8,9 @@
#ifndef SRC_HARDWARE_EXCEPTIONHANDLERS_H_
#define SRC_HARDWARE_EXCEPTIONHANDLERS_H_
-#include <cstdint>
+#include "SoftwareReset.h"
-[[noreturn]] void SoftwareReset(uint16_t reason, const uint32_t *stk = nullptr) noexcept;
+[[noreturn]] void SoftwareReset(SoftwareResetReason initialReason, const uint32_t *stk = nullptr) noexcept;
+[[noreturn]] void OutOfMemoryHandler() noexcept;
#endif /* SRC_HARDWARE_EXCEPTIONHANDLERS_H_ */
diff --git a/src/Hardware/SoftwareReset.cpp b/src/Hardware/SoftwareReset.cpp
index 25b1f692..ed151eae 100644
--- a/src/Hardware/SoftwareReset.cpp
+++ b/src/Hardware/SoftwareReset.cpp
@@ -28,8 +28,8 @@ const char *const SoftwareResetData::ReasonText[] =
"HeatTaskStuck",
"MemoryProtectionFault",
"TerminateCalled",
- "PureVirtualFunctionCalled",
- "DeletedVirtualFunctionCalled",
+ "PureOrDeletedVirtualFunctionCalled",
+ "OutOfMemory",
"Unknown"
};
diff --git a/src/Hardware/SoftwareReset.h b/src/Hardware/SoftwareReset.h
index 3505ce3b..3e24d5a4 100644
--- a/src/Hardware/SoftwareReset.h
+++ b/src/Hardware/SoftwareReset.h
@@ -33,8 +33,9 @@ enum class SoftwareResetReason : uint16_t
heaterWatchdog = 10u << 5, // the Heat task didn't kick the watchdog often enough
memFault = 11u << 5, // the MPU raised a fault
terminateCalled = 12u << 5, // std::terminate was called
- pureVirtual = 13u << 5,
- deletedVirtual = 14u << 5,
+ pureOrDeletedVirtual = 13u << 5,
+ outOfMemory = 14u << 5,
+ //unused = 15u << 5,
mainReasonMask = 0x0F << 5, // mask to pick out the main reason in a uint16_t
diff --git a/src/Linux/LinuxInterface.cpp b/src/Linux/LinuxInterface.cpp
index c3e9f117..69a390a9 100644
--- a/src/Linux/LinuxInterface.cpp
+++ b/src/Linux/LinuxInterface.cpp
@@ -112,7 +112,7 @@ void LinuxInterface::Init() noexcept
// Reset the controller
case LinuxRequest::Reset:
- SoftwareReset((uint16_t)SoftwareResetReason::user);
+ SoftwareReset(SoftwareResetReason::user);
break;
// Perform a G/M/T-code
diff --git a/src/RepRap.cpp b/src/RepRap.cpp
index ae7884f8..8404987a 100644
--- a/src/RepRap.cpp
+++ b/src/RepRap.cpp
@@ -1190,7 +1190,7 @@ void RepRap::Tick() noexcept
__asm volatile("mrs r2, psp");
register const uint32_t * stackPtr asm ("r2"); // we want the PSP not the MSP
SoftwareReset(
- (heatTaskStuck) ? (uint16_t)SoftwareResetReason::heaterWatchdog : (uint16_t)SoftwareResetReason::stuckInSpin,
+ (heatTaskStuck) ? SoftwareResetReason::heaterWatchdog : SoftwareResetReason::stuckInSpin,
stackPtr + 5); // discard uninteresting registers, keep LR PC PSR
}
}
diff --git a/src/Version.h b/src/Version.h
index fb17f6dc..f6e4b540 100644
--- a/src/Version.h
+++ b/src/Version.h
@@ -19,7 +19,7 @@
#endif
#ifndef DATE
-# define DATE "2020-10-18b1"
+# define DATE "2020-10-18b2"
#endif
#define AUTHORS "reprappro, dc42, chrishamm, t3p3, dnewman, printm3d"