2015-12-10 12:30:14 -05:00
|
|
|
//
|
2015-12-10 12:26:56 -05:00
|
|
|
// FILE: avrheap.cpp
|
|
|
|
// AUTHOR: Rob Tillaart
|
2015-12-10 12:35:47 -05:00
|
|
|
// VERSION: 0.1.02
|
2015-12-10 12:26:56 -05:00
|
|
|
// PURPOSE: library for avrheap Arduino
|
2015-12-10 12:30:14 -05:00
|
|
|
// URL: http://forum.arduino.cc/index.php?topic=355660
|
2015-12-10 12:26:56 -05:00
|
|
|
//
|
2015-12-10 12:35:47 -05:00
|
|
|
// REFERENCES
|
|
|
|
// http://forum.arduino.cc/index.php?topic=27536.15
|
|
|
|
//
|
2015-12-10 12:26:56 -05:00
|
|
|
// Released to the public domain
|
|
|
|
//
|
2015-12-10 12:35:47 -05:00
|
|
|
// 0.1.02 - added followHeap()
|
|
|
|
// 0.1.01 - refactor, added startAddress()
|
2015-12-10 12:26:56 -05:00
|
|
|
// 0.1.00 - initial version
|
|
|
|
|
|
|
|
#include "Avrheap.h"
|
|
|
|
|
2015-12-10 12:35:47 -05:00
|
|
|
struct __freelist
|
|
|
|
{
|
2015-12-10 12:30:14 -05:00
|
|
|
size_t size;
|
|
|
|
struct __freelist *next;
|
2015-12-10 12:26:56 -05:00
|
|
|
};
|
|
|
|
|
2015-12-10 12:35:47 -05:00
|
|
|
extern struct __freelist *__flp;
|
|
|
|
extern uint16_t __heap_start;
|
|
|
|
extern uint16_t *__brkval;
|
|
|
|
extern char *__malloc_heap_start;
|
|
|
|
extern char *__malloc_heap_end;
|
|
|
|
extern size_t __malloc_margin;
|
|
|
|
extern uint16_t __data_start;
|
|
|
|
extern uint16_t __data_end;
|
|
|
|
extern uint16_t __bss_start;
|
|
|
|
extern uint16_t __bss_end;
|
|
|
|
extern uint16_t __heap_start;
|
2015-12-10 12:26:56 -05:00
|
|
|
|
|
|
|
|
2015-12-10 12:35:47 -05:00
|
|
|
Avrheap::Avrheap()
|
2015-12-10 12:26:56 -05:00
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
bool Avrheap::isFragmented()
|
|
|
|
{
|
2015-12-10 12:35:47 -05:00
|
|
|
return this->freeListCount() > 0;
|
2015-12-10 12:26:56 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
uint16_t Avrheap::freeListCount()
|
|
|
|
{
|
|
|
|
uint16_t count = 0;
|
2015-12-10 12:35:47 -05:00
|
|
|
for (struct __freelist* p = __flp; p; p = p->next) count++;
|
2015-12-10 12:26:56 -05:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t Avrheap::freeListSize()
|
|
|
|
{
|
|
|
|
uint16_t total = 0;
|
2015-12-10 12:30:14 -05:00
|
|
|
for (struct __freelist* p = __flp; p; p = p->next)
|
2015-12-10 12:26:56 -05:00
|
|
|
{
|
|
|
|
total += 2; // malloc size
|
|
|
|
total += (uint16_t) p->size;
|
|
|
|
}
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Avrheap::freeListDump()
|
|
|
|
{
|
|
|
|
for (struct __freelist* p = __flp; p; p = p->next)
|
|
|
|
{
|
|
|
|
Serial.print((uint16_t)p);
|
|
|
|
Serial.print("\t");
|
|
|
|
Serial.println((uint16_t)p->size);
|
|
|
|
}
|
|
|
|
Serial.println();
|
|
|
|
}
|
|
|
|
|
2015-12-10 12:30:14 -05:00
|
|
|
uint16_t Avrheap::startAddress()
|
|
|
|
{
|
2015-12-10 12:35:47 -05:00
|
|
|
return (uint16_t) &__heap_start;
|
2015-12-10 12:30:14 -05:00
|
|
|
}
|
|
|
|
|
2015-12-10 12:35:47 -05:00
|
|
|
// PRINTTO?
|
2015-12-10 12:30:14 -05:00
|
|
|
void Avrheap::dump(uint16_t count)
|
|
|
|
{
|
2015-12-10 12:35:47 -05:00
|
|
|
/*
|
|
|
|
Serial.println((int)__brkval);
|
|
|
|
Serial.println((int)RAMEND);
|
|
|
|
Serial.println((int)SP);
|
|
|
|
Serial.println((int)__data_start);
|
|
|
|
Serial.println((int)__data_end);
|
|
|
|
Serial.println((int)__bss_start);
|
|
|
|
Serial.println((int)__bss_end);
|
|
|
|
Serial.println((int)__malloc_heap_start);
|
|
|
|
Serial.println((int)__malloc_heap_end);
|
|
|
|
Serial.println((int)__malloc_margin);
|
|
|
|
*/
|
|
|
|
|
|
|
|
for (int i = 0; i < count;)
|
2015-12-10 12:30:14 -05:00
|
|
|
{
|
|
|
|
Serial.print('\t');
|
|
|
|
Serial.print((uint8_t) * ((&__heap_start) + i) );
|
|
|
|
if (++i % 16 == 0) Serial.println();
|
|
|
|
}
|
|
|
|
Serial.println();
|
|
|
|
}
|
|
|
|
|
2015-12-10 12:35:47 -05:00
|
|
|
// EXPERIMENTAL
|
|
|
|
void Avrheap::followHeap()
|
|
|
|
{
|
|
|
|
byte* p = (byte*) &__heap_start;
|
|
|
|
struct __freelist* fp = __flp;
|
2015-12-10 12:30:14 -05:00
|
|
|
|
2015-12-10 12:35:47 -05:00
|
|
|
Serial.println("addr\tsize");
|
|
|
|
while ((int)p < (int)__brkval)
|
|
|
|
{
|
|
|
|
Serial.print((uint16_t)p); // p+2 ?
|
|
|
|
Serial.print("\t\t");
|
|
|
|
Serial.print(*p, DEC);
|
|
|
|
// if (inFreeList(p) Serial.print("\t (free)");
|
|
|
|
if ( (fp != NULL) && ((uint16_t)p == (uint16_t)fp))
|
|
|
|
{
|
|
|
|
Serial.print("\t (free)");
|
|
|
|
fp = fp->next;
|
|
|
|
}
|
|
|
|
Serial.println();
|
|
|
|
p += (byte) *p + 2;
|
|
|
|
}
|
|
|
|
}
|
2015-12-10 12:26:56 -05:00
|
|
|
|
2015-12-10 12:35:47 -05:00
|
|
|
bool Avrheap::inFreeList(uint16_t addr)
|
|
|
|
{
|
|
|
|
for (struct __freelist* p = __flp; p; p = p->next)
|
|
|
|
{
|
|
|
|
if (addr == (uint16_t)p) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t Avrheap::freeListLargest()
|
|
|
|
{
|
|
|
|
uint16_t largest = 0;
|
|
|
|
for (struct __freelist* p = __flp; p; p = p->next)
|
|
|
|
{
|
|
|
|
largest = max(largest, (uint16_t) p->size);
|
|
|
|
}
|
|
|
|
return largest;
|
|
|
|
}
|
2015-12-10 12:26:56 -05:00
|
|
|
|
|
|
|
// --- END OF FILE ---
|