From ddc55690f3b486698804c418c213ab764c863468 Mon Sep 17 00:00:00 2001 From: Neil McKechnie Date: Mon, 8 Mar 2021 13:09:09 +0000 Subject: [PATCH 1/2] More conservative memory monitoring Add function to maintain a minimum value seen of free memory. Add call to it in DCCWaveform interrupt handler (assumed to be the likely worst case for stack usage). Report this minimum value in main loop. --- CommandStation-EX.ino | 2 +- DCCWaveform.cpp | 4 ++++ freeMemory.cpp | 13 +++++++++++++ freeMemory.h | 2 ++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CommandStation-EX.ino b/CommandStation-EX.ino index 0e282d1..2357638 100644 --- a/CommandStation-EX.ino +++ b/CommandStation-EX.ino @@ -127,7 +127,7 @@ void loop() #if ENABLE_FREE_MEM_WARNING static int ramLowWatermark = 32767; // replaced on first loop - int freeNow = freeMemory(); + int freeNow = updateMinimumFreeMemory(); if (freeNow < ramLowWatermark) { ramLowWatermark = freeNow; diff --git a/DCCWaveform.cpp b/DCCWaveform.cpp index c1e0269..c7baa9f 100644 --- a/DCCWaveform.cpp +++ b/DCCWaveform.cpp @@ -23,6 +23,7 @@ #include "DCCWaveform.h" #include "DCCTimer.h" #include "DIAG.h" +#include "freeMemory.h" DCCWaveform DCCWaveform::mainTrack(PREAMBLE_BITS_MAIN, true); @@ -203,6 +204,9 @@ void DCCWaveform::interrupt2() { if (remainingPreambles > 0 ) { state=WAVE_MID_1; // switch state to trigger LOW on next interrupt remainingPreambles--; + // Update free memory diagnostic as we don't have anything else to do this time. + // Allow for checkAck and its called functions using 22 bytes more. + updateMinimumFreeMemory(22); return; } diff --git a/freeMemory.cpp b/freeMemory.cpp index 30fa16d..82ec436 100644 --- a/freeMemory.cpp +++ b/freeMemory.cpp @@ -1,5 +1,6 @@ /* * © 2020, Harald Barth + * © 2021, Neil McKechnie * * This file is part of Asbelos DCC-EX * @@ -30,6 +31,9 @@ extern char *__malloc_heap_start; #endif +static int minimum_free_memory = 32767; + + int freeMemory() { char top; #if defined(__arm__) @@ -40,3 +44,12 @@ int freeMemory() { #error bailed out alredy above #endif } + +// Update low ram level. Allow for extra bytes to be specified +// by estimation or inspection, that may be used by other +// called subroutines. +int updateMinimumFreeMemory(unsigned char extraBytes) { + int spare = freeMemory()-extraBytes; + if (spare < minimum_free_memory) minimum_free_memory = spare; + return minimum_free_memory; +} diff --git a/freeMemory.h b/freeMemory.h index 2bd35c1..bf93189 100644 --- a/freeMemory.h +++ b/freeMemory.h @@ -1,5 +1,6 @@ /* * © 2020, Harald Barth + * © 2021, Neil McKechnie * * This file is part of DCC-EX * @@ -20,4 +21,5 @@ #ifndef freeMemory_h #define freeMemory_h int freeMemory(); +int updateMinimumFreeMemory(unsigned char extraBytes=0); #endif From 609d3d13de7911721380ecebb729e8649eb28bf5 Mon Sep 17 00:00:00 2001 From: Neil McKechnie Date: Mon, 8 Mar 2021 13:25:13 +0000 Subject: [PATCH 2/2] Mark minimum_free_memory volatile. --- freeMemory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/freeMemory.cpp b/freeMemory.cpp index 82ec436..6735ac1 100644 --- a/freeMemory.cpp +++ b/freeMemory.cpp @@ -31,7 +31,7 @@ extern char *__malloc_heap_start; #endif -static int minimum_free_memory = 32767; +static volatile int minimum_free_memory = 32767; int freeMemory() {