1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-24 13:21:23 +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
// Optionally report any decrease in memory (will automatically trigger on first call)
#if ENABLE_FREE_MEM_WARNING
static int ramLowWatermark = 32767; // replaced on first loop
// Report any decrease in memory (will automatically trigger on first call)
static int ramLowWatermark = __INT_MAX__; // replaced on first loop
int freeNow = updateMinimumFreeMemory();
int freeNow = minimumFreeMemory();
if (freeNow < ramLowWatermark)
{
ramLowWatermark = freeNow;
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;
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;
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
/////////////////////////////////////////////////////////////////////////////////////
//
// 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/>.
*/
#include <Arduino.h>
#include "freeMemory.h"
// thanks go to https://github.com/mpflaga/Arduino-MemoryFree
@ -31,25 +32,40 @@ extern char *__malloc_heap_start;
#endif
static volatile int minimum_free_memory = 32767;
static volatile int minimum_free_memory = __INT_MAX__;
int freeMemory() {
static inline int freeMemory() {
char top;
#if defined(__arm__)
return &top - reinterpret_cast<char*>(sbrk(0));
#elif defined(__AVR__)
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
#else
#error bailed out alredy above
#error bailed out already 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) {
// called subroutines. Must be called with interrupts disabled.
//
// 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;
if (spare < 0) spare = 0;
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
#define freeMemory_h
int freeMemory();
int updateMinimumFreeMemory(unsigned char extraBytes=0);
void updateMinimumFreeMemory(unsigned char extraBytes=0);
int minimumFreeMemory();
#endif