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-05-23 21:39:55 +0300
committerDavid Crocker <dcrocker@eschertech.com>2021-05-23 21:39:55 +0300
commit214d486c4c9fe3639f2f861605c89d1b0dc56a8f (patch)
treebe75195ae98c77698a5951af7df71e386a342d92
parentf055e129c4047bdba729db1c6ace6eb0a0a76698 (diff)
Bug fix to crash handler (still 3.3RC3 candidate)
Tyhe crash handler was allocating the buffer for reading/writing flash memory on the stack. When the crash handler was called in-process (e.g. due to an assertion failure or a memory allocation failure), this typically corrupted the task details.
-rw-r--r--src/Hardware/ExceptionHandlers.cpp7
-rw-r--r--src/Platform/Tasks.cpp26
-rw-r--r--src/Platform/Tasks.h1
3 files changed, 31 insertions, 3 deletions
diff --git a/src/Hardware/ExceptionHandlers.cpp b/src/Hardware/ExceptionHandlers.cpp
index 7253f5cf..640c0a41 100644
--- a/src/Hardware/ExceptionHandlers.cpp
+++ b/src/Hardware/ExceptionHandlers.cpp
@@ -8,6 +8,7 @@
#include "ExceptionHandlers.h"
#include <Platform/RepRap.h>
#include <Platform/Platform.h>
+#include <Platform/Tasks.h>
#include <Hardware/NonVolatileMemory.h>
#include <Cache.h>
#if SAME70 || SAM4S || SAM4E
@@ -62,10 +63,10 @@
}
// Record the reason for the software reset
- NonVolatileMemory mem;
- SoftwareResetData * const srd = mem.AllocateResetDataSlot();
+ NonVolatileMemory * const mem = new(Tasks::GetNVMBuffer(stk)) NonVolatileMemory;
+ SoftwareResetData * const srd = mem->AllocateResetDataSlot();
srd->Populate(fullReason, stk);
- mem.EnsureWritten();
+ mem->EnsureWritten();
}
#if defined(__LPC17xx__)
diff --git a/src/Platform/Tasks.cpp b/src/Platform/Tasks.cpp
index e5b1331c..e433b8d8 100644
--- a/src/Platform/Tasks.cpp
+++ b/src/Platform/Tasks.cpp
@@ -11,6 +11,7 @@
#include <Cache.h>
#include <Platform/TaskPriorities.h>
#include <Hardware/SoftwareReset.h>
+#include <Hardware/NonVolatileMemory.h>
#include <Storage/CRC32.h>
#include <Movement/StepTimer.h>
@@ -102,6 +103,31 @@ extern "C" void ReleaseMallocMutex() noexcept
}
}
+// Get a 4-byte aligned NonVolatileMemory buffer suitable for the crash handler to use for reading/writing flash memory.
+// We don't want to use a static buffer because that is wasteful of RAM, given that only the crash handler uses it, we have interrupts disabled while we use it,
+// and we reset immediately afterwards.
+// Instead we use either the bottom or top of the main task stack.
+// Parameter 'stk' is the stack we are interested in, which we must not overwrite. The caller is either using the same stack a little lower, or the exception stack.
+void *Tasks::GetNVMBuffer(const uint32_t *stk) noexcept
+{
+ constexpr size_t stackAllowance = 128;
+ static_assert((sizeof(NonVolatileMemory) & 3) == 0);
+ static_assert(MainTaskStackWords * 4 >= 2 * sizeof(NonVolatileMemory) + stackAllowance + 4);
+ const char * const cStack = reinterpret_cast<const char*>(stk);
+
+ // See if we can use the bottom of the main task stack
+ char *ret = (char *)&mainTask + sizeof(TaskBase);
+ if (cStack > ret + (sizeof(NonVolatileMemory) + stackAllowance + 4)) // allow space for the buffer + 128b in case we are on that stack
+ {
+ ret += 4; // the +4 is so that we leave the stack marker alone in case the main task raised the exception
+ }
+ else
+ {
+ ret += (MainTaskStackWords * 4) - sizeof(NonVolatileMemory); // use the top area instead
+ }
+ return ret;
+}
+
// Application entry point
[[noreturn]] void AppMain() noexcept
{
diff --git a/src/Platform/Tasks.h b/src/Platform/Tasks.h
index aff42e38..f3f8b878 100644
--- a/src/Platform/Tasks.h
+++ b/src/Platform/Tasks.h
@@ -21,6 +21,7 @@ namespace Tasks
const char* GetHeapTop() noexcept;
Mutex *GetI2CMutex() noexcept;
Mutex *GetFilamentsMutex() noexcept;
+ void *GetNVMBuffer(const uint32_t *stk) noexcept;
}
#if SUPPORT_CAN_EXPANSION