forked from StopPointTeam/TaiChi
115 lines
4.3 KiB
C++
115 lines
4.3 KiB
C++
/*
|
|
MemoryUsage.c - MemoryUsage library
|
|
Copyright (c) 2015 Thierry Paris. All right reserved.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/*! \file MemoryUsage.cpp
|
|
|
|
Main library code file.
|
|
*/
|
|
|
|
#include "Arduino.h"
|
|
#include "MemoryUsage.h"
|
|
|
|
/// Thanks to adafruit : https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory
|
|
int mu_freeRam()
|
|
{
|
|
//extern int __heap_start, *__brkval;
|
|
int v;
|
|
return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
|
|
}
|
|
|
|
/// Copy / adaptation of the library StackPaint available here : https://github.com/WickedDevice/StackPaint
|
|
|
|
#define STACK_CANARY 0xc5
|
|
|
|
void mu_StackPaint(void) __attribute__((naked)) __attribute__((section(".init1")));
|
|
|
|
|
|
/// Function called before any other function.
|
|
void mu_StackPaint(void)
|
|
{
|
|
#if 1
|
|
uint8_t *p = &_end;
|
|
|
|
while (p <= &__stack)
|
|
{
|
|
*p = STACK_CANARY;
|
|
p++;
|
|
}
|
|
#else
|
|
__asm volatile (
|
|
" ldi r30,lo8(_end)\n"
|
|
" ldi r31,hi8(_end)\n"
|
|
" ldi r24,lo8(0xc5)\n" // STACK_CANARY = 0xc5
|
|
" ldi r25,hi8(__stack)\n"
|
|
" rjmp .cmp\n"
|
|
".loop:\n"
|
|
" st Z+,r24\n"
|
|
".cmp:\n"
|
|
" cpi r30,lo8(__stack)\n"
|
|
" cpc r31,r25\n"
|
|
" brlo .loop\n"
|
|
" breq .loop"::);
|
|
#endif
|
|
}
|
|
|
|
/// Checks the first undecorated byte.
|
|
uint16_t mu_StackCount(void)
|
|
{
|
|
uint8_t *p = (__brkval == 0 ? (uint8_t *) &__heap_start : __brkval);
|
|
|
|
while (*p == STACK_CANARY && (int) p <= SP)
|
|
p++;
|
|
|
|
return (uint16_t)RAMEND - (uint16_t)p;
|
|
}
|
|
|
|
/// Modified function from http://www.avr-developers.com/mm/memoryusage.html
|
|
void SRamDisplay(void)
|
|
{
|
|
int data_size = (int)&__data_end - (int)&__data_start;
|
|
int bss_size = (int)&__bss_end - (int)&__data_end;
|
|
int heap_end = (int) (__brkval == 0 ? (uint8_t *) &__heap_start : __brkval);
|
|
//int heap_end = (int)SP - (int)&__malloc_margin;
|
|
int heap_size = heap_end - (int)&__bss_end;
|
|
int stack_size = RAMEND - (int)SP + 1;
|
|
int available = (RAMEND - (int)&__data_start + 1);
|
|
|
|
available -= data_size + bss_size + heap_size + stack_size;
|
|
|
|
NeoSerialDebug.print(F("+----------------+ ")); NeoSerialDebug.print((int)&__data_start); NeoSerialDebug.println(" (__data_start)");
|
|
NeoSerialDebug.print(F("+ data +")); NeoSerialDebug.println();
|
|
NeoSerialDebug.print(F("+ variables + size = ")); NeoSerialDebug.println(data_size);
|
|
NeoSerialDebug.print(F("+----------------+ ")); NeoSerialDebug.print((int)&__data_end); NeoSerialDebug.println(" (__data_end / __bss_start)");
|
|
NeoSerialDebug.print(F("+ bss +")); NeoSerialDebug.println();
|
|
NeoSerialDebug.print(F("+ variables + size = ")); NeoSerialDebug.println(bss_size);
|
|
NeoSerialDebug.print(F("+----------------+ ")); NeoSerialDebug.print((int)&__bss_end); NeoSerialDebug.println(" (__bss_end / __heap_start)");
|
|
NeoSerialDebug.print(F("+ heap + size = ")); NeoSerialDebug.println(heap_size);
|
|
NeoSerialDebug.print(F("+----------------+ ")); NeoSerialDebug.print((int)heap_end); NeoSerialDebug.println(" (__brkval if not 0, or __heap_start)");
|
|
NeoSerialDebug.print(F("+ +")); NeoSerialDebug.println();
|
|
NeoSerialDebug.print(F("+ +")); NeoSerialDebug.println();
|
|
NeoSerialDebug.print(F("+ FREE RAM + size = ")); NeoSerialDebug.println(available);
|
|
NeoSerialDebug.print(F("+ +")); NeoSerialDebug.println();
|
|
NeoSerialDebug.print(F("+ +")); NeoSerialDebug.println();
|
|
NeoSerialDebug.print(F("+----------------+ ")); NeoSerialDebug.print((int)SP); NeoSerialDebug.println(" (SP)");
|
|
NeoSerialDebug.print(F("+ stack + size = ")); NeoSerialDebug.println(stack_size);
|
|
NeoSerialDebug.print(F("+----------------+ ")); NeoSerialDebug.print((int)RAMEND); NeoSerialDebug.println(" (RAMEND / __stack)");
|
|
|
|
NeoSerialDebug.println();
|
|
NeoSerialDebug.println();
|
|
} |