#define COUNT_ALLOC 1250000
//===============================================================================
#if defined(ARDUINO_TEENSY41)
extern "C" {
extern uint8_t external_psram_size;
}
uint8_t *extmem_next_free = nullptr; // set in startup NULL if we don't have external memory
extern unsigned long _seram;
extern unsigned long _eeram;
uint8_t *malloc_extmem(size_t cb_alloc) {
[B]uint8_t *extmem_free_last = extmem_next_free; // Record Prior value in case last alloc fails[/B]
if (!extmem_next_free) {
extmem_next_free = (uint8_t *)&_seram + (uint32_t)(external_psram_size * 1048576);
[B]extmem_free_last = extmem_next_free;[/B]
}
// lets allocate and return on 16 byte boundaries.
uint8_t *ret_val = (uint8_t *)((uint32_t)(extmem_next_free - cb_alloc) & 0xfffffff0);
// comparing _eeram to assure that we not overrun pre allocated
if (ret_val < (uint8_t *)&_eeram) {
[B]extmem_next_free = extmem_free_last; // On this fail undo last attempt alloc[/B]
return nullptr;
}
extmem_next_free = ret_val;
return ret_val;
}
#else
uint8_t *malloc_extmem(size_t cb_alloc) {
return nullptr;
}
#endif
void free_extmem(char *p) {
// we don't do any free yet
}
//===============================================================================
extern uint8_t *malloc_extmem(size_t cb_alloc);
uint16_t *buffer1;
uint16_t *buffer2;
uint16_t *buffer3;
#if 1
EXTMEM uint32_t fluff[1024];
EXTMEM uint32_t fluff2[1024];
#else
EXTMEM uint32_t fluff[256];
EXTMEM uint32_t fluff2[256];
#endif
uint8_t *buffer_eat_upper_8mb = nullptr;
void setup() {
pinMode(13, OUTPUT);
Serial.begin(115200);
while (!Serial && millis() < 4000 );
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
Serial.printf( "ERAM start==0x%x\t end==0x%x\n", &_seram, &_eeram );
Serial.printf( "EXTMEM \t fluff==0x%x[size=%x]\t fluff2==0x%x[size=%x]\n", fluff, sizeof(fluff), fluff2, sizeof(fluff2) );
#if defined(ARDUINO_TEENSY41)
Serial.printf("External PSRAM size: %d\n", external_psram_size);
if (external_psram_size == 16) buffer_eat_upper_8mb = malloc_extmem(1024 * 1024 * 8);
#endif
buffer1 = (uint16_t*)malloc_extmem(COUNT_ALLOC * sizeof(uint16_t));
buffer2 = (uint16_t*)malloc_extmem(COUNT_ALLOC * sizeof(uint16_t));
buffer3 = (uint16_t*)malloc_extmem(COUNT_ALLOC * sizeof(uint16_t));
Serial.printf("Eat: %x B1:%x B2:%x B3: %x\n", (uint32_t)buffer_eat_upper_8mb, (uint32_t)buffer1, (uint32_t)buffer2, (uint32_t)buffer3);
if (!buffer1 || !buffer2 || !buffer3) {
Serial.println("Failed to allocate external memory");
for (;;) {
digitalWrite(13, !digitalRead(13));
delay(250);
}
}
}
uint32_t loop_count = 0;
uint32_t loop_alloc = 8192 * 4;
uint16_t *buffer4 = nullptr; // waste and realloc memory test
void loop() {
digitalWrite(13, !digitalRead(13));
loop_count++;
for (uint32_t i = 0; i < COUNT_ALLOC; i++) {
buffer1[i] = i & 0xffff;
buffer2[i] = loop_count & 0xffff;
buffer3[i] = buffer1[i] ^ buffer2[i];
if (buffer_eat_upper_8mb)buffer_eat_upper_8mb[i] = loop_count + i ;
}
uint32_t error_count = 0;
for (uint32_t i = 0; i < COUNT_ALLOC; i++) {
if ((buffer1[i] != (i & 0xffff)) || (buffer2[i] != (loop_count & 0xffff)) || (buffer3[i] != (buffer1[i] ^ buffer2[i]))) {
error_count++;
if (error_count < 5) Serial.printf("%u %x %x %x\n", i, buffer1[i], buffer2[i], buffer3[i]);
}
}
if ( error_count == 0 && 1 != (loop_count % 50) ) {
if ( loop_count == 2 || buffer4 != nullptr ) {
uint16_t *before4 = buffer4;
[B]buffer4 = (uint16_t*)malloc_extmem(loop_alloc * sizeof(uint16_t));
if ( buffer4 == nullptr ) {
Serial.printf("\n\tEXTMEM exhausted at Pass %d alloc size: 0x%x \t was @ 0x%x\nTry smaller size:", loop_count, loop_alloc, before4 );
loop_alloc = loop_alloc / 2;
while ( loop_alloc > 0 && buffer4 == nullptr ) {
Serial.printf("0x%x\t", loop_alloc);
buffer4 = (uint16_t*)malloc_extmem(loop_alloc * sizeof(uint16_t));
if ( buffer4 == nullptr )
loop_alloc = loop_alloc / 2;
else
Serial.printf(" +!");
}
}
else
Serial.printf(" +");[/B]
}
else
Serial.printf(" .");
}
else
Serial.printf("\nPass %d error count: %d\n", loop_count, error_count);
}