1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-24 21:21:24 +01:00

Merge pull request #133 from DCC-EX/neil-updates

Protect minimum memory threshold against interrupts.
This commit is contained in:
Neil McKechnie 2021-03-10 17:55:55 +00:00 committed by GitHub
commit 62b17d4a71
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 17 deletions

View File

@ -123,15 +123,13 @@ void loop()
LCDDisplay::loop(); // ignored if LCD not in use LCDDisplay::loop(); // ignored if LCD not in use
// Optionally report any decrease in memory (will automatically trigger on first call) // Report any decrease in memory (will automatically trigger on first call)
#if ENABLE_FREE_MEM_WARNING static int ramLowWatermark = __INT_MAX__; // replaced on first loop
static int ramLowWatermark = 32767; // replaced on first loop
int freeNow = updateMinimumFreeMemory(); int freeNow = minimumFreeMemory();
if (freeNow < ramLowWatermark) if (freeNow < ramLowWatermark)
{ {
ramLowWatermark = freeNow; ramLowWatermark = freeNow;
LCD(2,F("Free RAM=%5db"), ramLowWatermark); LCD(2,F("Free RAM=%5db"), ramLowWatermark);
} }
#endif
} }

View File

@ -720,7 +720,7 @@ bool DCCEXParser::parseD(Print *stream, int params, int p[])
return true; return true;
case HASH_KEYWORD_RAM: // <D RAM> case HASH_KEYWORD_RAM: // <D RAM>
StringFormatter::send(stream, F("\nFree memory=%d\n"), freeMemory()); StringFormatter::send(stream, F("\nFree memory=%d\n"), minimumFreeMemory());
break; break;
case HASH_KEYWORD_ACK: // <D ACK ON/OFF> <D ACK [LIMIT|MIN|MAX] Value> case HASH_KEYWORD_ACK: // <D ACK ON/OFF> <D ACK [LIMIT|MIN|MAX] Value>

View File

@ -111,6 +111,4 @@ The configuration file for DCC-EX Command Station
// #define OLED_DRIVER 128,32 // #define OLED_DRIVER 128,32
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
//
// Enable warning as memory gets depleted
#define ENABLE_FREE_MEM_WARNING false

View File

@ -18,6 +18,7 @@
* along with CommandStation. If not, see <https://www.gnu.org/licenses/>. * along with CommandStation. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <Arduino.h>
#include "freeMemory.h" #include "freeMemory.h"
// thanks go to https://github.com/mpflaga/Arduino-MemoryFree // thanks go to https://github.com/mpflaga/Arduino-MemoryFree
@ -31,25 +32,40 @@ extern char *__malloc_heap_start;
#endif #endif
static volatile int minimum_free_memory = 32767; static volatile int minimum_free_memory = __INT_MAX__;
int freeMemory() { static inline int freeMemory() {
char top; char top;
#if defined(__arm__) #if defined(__arm__)
return &top - reinterpret_cast<char*>(sbrk(0)); return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(__AVR__) #elif defined(__AVR__)
return __brkval ? &top - __brkval : &top - __malloc_heap_start; return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#else #else
#error bailed out alredy above #error bailed out already above
#endif #endif
} }
// Update low ram level. Allow for extra bytes to be specified // Update low ram level. Allow for extra bytes to be specified
// by estimation or inspection, that may be used by other // by estimation or inspection, that may be used by other
// called subroutines. // called subroutines. Must be called with interrupts disabled.
int updateMinimumFreeMemory(unsigned char extraBytes) { //
// Although __brkval may go up and down as heap memory is allocated
// and freed, this function records only the worst case encountered.
// So even if all of the heap is freed, the reported minimum free
// memory will not increase.
//
void updateMinimumFreeMemory(unsigned char extraBytes) {
int spare = freeMemory()-extraBytes; int spare = freeMemory()-extraBytes;
if (spare < 0) spare = 0;
if (spare < minimum_free_memory) minimum_free_memory = spare; if (spare < minimum_free_memory) minimum_free_memory = spare;
return minimum_free_memory; }
// Return low memory value.
int minimumFreeMemory() {
byte sreg_save = SREG;
noInterrupts(); // Disable interrupts
int retval = minimum_free_memory;
SREG = sreg_save; // Restore interrupt state
return retval;
} }

View File

@ -20,6 +20,6 @@
#ifndef freeMemory_h #ifndef freeMemory_h
#define freeMemory_h #define freeMemory_h
int freeMemory(); void updateMinimumFreeMemory(unsigned char extraBytes=0);
int updateMinimumFreeMemory(unsigned char extraBytes=0); int minimumFreeMemory();
#endif #endif