@defragster - wonder if I need to learn more about how VS... works and try to build a version that is totally stand alone and does not require run time support?
/*
(c) Frank B, 2020
License: MIT
Please keep this info.
*/
inline
unsigned memfree(void) {
extern unsigned long _ebss;
extern unsigned long _sdata;
extern unsigned long _estack;
const unsigned DTCM_START = 0x20000000UL;
unsigned dtcm = (unsigned)&_estack - DTCM_START;
unsigned stackinuse = (unsigned) &_estack - (unsigned) __builtin_frame_address(0);
unsigned varsinuse = (unsigned)&_ebss - (unsigned)&_sdata;
unsigned freemem = dtcm - (stackinuse + varsinuse);
return freemem;
}
FLASHMEM
void flexRamInfo(void) {
#if defined(ARDUINO_TEENSY40)
static const unsigned DTCM_START = 0x20000000UL;
static const unsigned OCRAM_START = 0x20200000UL;
static const unsigned OCRAM_SIZE = 512;
static const unsigned FLASH_SIZE = 1984;
#elif defined(ARDUINO_TEENSY41)
static const unsigned DTCM_START = 0x20000000UL;
static const unsigned OCRAM_START = 0x20200000UL;
static const unsigned OCRAM_SIZE = 512;
static const unsigned FLASH_SIZE = 7936;
#endif
Serial.println(__FILE__ " " __DATE__ " " __TIME__ );
Serial.print("Teensyduino version ");
Serial.println(TEENSYDUINO / 100.0f);
Serial.println();
int itcm = 0;
int dtcm = 0;
int ocram = 0;
uint32_t gpr17 = IOMUXC_GPR_GPR17;
char __attribute__((unused)) dispstr[17] = {0};
dispstr[16] = 0;
for (int i = 15; i >= 0; i--) {
switch ((gpr17 >> (i * 2)) & 0b11) {
default: dispstr[15 - i] = '.'; break;
case 0b01: dispstr[15 - i] = 'O'; ocram++; break;
case 0b10: dispstr[15 - i] = 'D'; dtcm++; break;
case 0b11: dispstr[15 - i] = 'I'; itcm++; break;
}
}
Serial.printf("ITCM: %dkB, DTCM: %dkB, OCRAM: %d(+%d)kB [%s]\n", itcm * 32, dtcm * 32, ocram * 32, OCRAM_SIZE, dispstr);
const char* fmtstr = "%-6s%7d %5.02f%% of %4dkB (%7d Bytes free) %s\n";
extern unsigned long _stext;
extern unsigned long _etext;
extern unsigned long _sdata;
extern unsigned long _ebss;
extern unsigned long _flashimagelen;
extern unsigned long _heap_start;
extern unsigned long _estack;
Serial.printf(fmtstr, "ITCM:",
(unsigned)&_etext - (unsigned)&_stext,
(float)((unsigned)&_etext - (unsigned)&_stext) / ((float)itcm * 32768.0f) * 100.0f,
itcm * 32,
itcm * 32768 - ((unsigned)&_etext - (unsigned)&_stext), "(RAM1) FASTRUN");
Serial.printf(fmtstr, "OCRAM:",
(unsigned)&_heap_start - OCRAM_START,
(float)((unsigned)&_heap_start - OCRAM_START) / (OCRAM_SIZE * 1024.0f) * 100.0f,
OCRAM_SIZE,
OCRAM_SIZE * 1024 - ((unsigned)&_heap_start - OCRAM_START), "(RAM2) DMAMEM, Heap");
Serial.printf(fmtstr, "FLASH:",
(unsigned)&_flashimagelen,
((unsigned)&_flashimagelen) / (FLASH_SIZE * 1024.0f) * 100.0f,
FLASH_SIZE,
FLASH_SIZE * 1024 - ((unsigned)&_flashimagelen), "FLASHMEM, PROGMEM");
// Serial.println();
unsigned _dtcm = (unsigned)&_estack - DTCM_START; //or, one could use dtcm * 32768 here.
unsigned stackinuse = (unsigned) &_estack - (unsigned) __builtin_frame_address(0);
unsigned varsinuse = (unsigned)&_ebss - (unsigned)&_sdata;
unsigned freemem = _dtcm - stackinuse - varsinuse;
Serial.printf("DTCM:\n %7d Bytes (%d kB)\n", _dtcm, _dtcm / 1024);
Serial.printf("- %7d Bytes (%d kB) global variables\n", varsinuse, varsinuse / 1024);
Serial.printf("- %7d Bytes (%d kB) stack (currently)\n", stackinuse, stackinuse / 1024);
Serial.println("=========");
Serial.printf(" %7d Bytes free (%d kB), %d Bytes in use (%d kB).\n",
_dtcm - (varsinuse + stackinuse), (_dtcm - (varsinuse + stackinuse)) / 1024,
varsinuse + stackinuse, (varsinuse + stackinuse) / 1024
);
}
void setup() {
while (!Serial && millis() < 4000);
flexRamInfo();
// Serial.println(memfree());
}
void loop() {
}
C:\Users\Frank\Documents\Arduino\sketch_jan24a\sketch_jan24a.ino Jan 24 2020 15:45:33
Teensyduino version 1.49
ITCM: 32kB, DTCM: 480kB, OCRAM: 0(+512)kB [DDDDDDDDDDDDDDDI]
ITCM: 23584 71.97% of 32kB ( 9184 Bytes free) (RAM1) FASTRUN
OCRAM: 12384 2.36% of 512kB ( 511904 Bytes free) (RAM2) DMAMEM
FLASH: 33920 1.62% of 2048kB (2063232 Bytes free) FLASHMEM, PROGMEM
DTCM:
491520 Bytes (480 kB)
- 12992 Bytes (12 kB) global variables
- 80 Bytes (0 kB) stack (currently)
=========
478448 Bytes free (467 kB), 13072 Bytes in use (12 kB).
extern "C" {
void startup_late_hook(void) {
extern unsigned long _ebss;
unsigned long * p = &_ebss;
size_t size = (size_t)(uint8_t*)__builtin_frame_address(0) - 16 - (uintptr_t) &_ebss;
memset((void*)p, 0, size);
}
}
unsigned long maxstack() {
extern unsigned long _ebss;
extern unsigned long _estack;
unsigned long * p = &_ebss;
while (*p == 0) p++;
return (unsigned) &_estack - (unsigned) p;
}
void setup() {
[B]while (!Serial && millis() < 4000);[/B]
flexRamInfo();
No
(addsomedummycharacters)
#if defined(__IMXRT1062__) // Get Pointer to FREE ITCM
uint32_t *ptrFreeITCM; // Set to Usable ITCM free RAM
uint32_t sizeofFreeITCM; // sizeof free RAM in uint32_t units.
uint32_t SizeLeft_etext;
FLASHMEM
void getFreeITCM() { // end of CODE ITCM, skip full 32 bits
extern unsigned long _stext;
extern unsigned long _etext;
SizeLeft_etext = (32 * 1024) - (((uint32_t)&_etext - (uint32_t)&_stext) % (32 * 1024));
sizeofFreeITCM = SizeLeft_etext - 4;
sizeofFreeITCM /= sizeof(ptrFreeITCM[0]);
ptrFreeITCM = (uint32_t *) ( (uint32_t)&_stext + (uint32_t)&_etext + 4 );
Serial.printf( "Size of Free ITCM in Bytes = %u\n", sizeofFreeITCM*sizeof(ptrFreeITCM[0]) );
Serial.printf( "Start of Free ITCM = %u [%X] \n", ptrFreeITCM, ptrFreeITCM);
Serial.printf( "End of Free ITCM = %u [%X] \n", ptrFreeITCM + sizeofFreeITCM, ptrFreeITCM + sizeofFreeITCM);
}
#else
void getFreeITCM() {}
#endif
T:\tCode\T4\T4_MemoryInfo\T4_MemoryInfo.ino Jan 24 2020 11:48:53
Teensyduino version 1.49
ITCM: 32kB, DTCM: 480kB, OCRAM: 0(+512)kB [DDDDDDDDDDDDDDDI]
ITCM: 24176 73.78% of 32kB ( 8592 Bytes free) (RAM1) FASTRUN
OCRAM: 12384 2.36% of 512kB ( 511904 Bytes free) (RAM2) DMAMEM
FLASH: 34768 1.66% of 2048kB (2062384 Bytes free) FLASHMEM, PROGMEM
DTCM:
491520 Bytes (480 kB)
- 12992 Bytes (12 kB) global variables
- 96 Bytes (0 kB) stack (currently)
=========
478432 Bytes free (467 kB), 13088 Bytes in use (12 kB).
memfree()=478504
maxstack()=1348
++++++++++++++++++++++
Size of Free ITCM in Bytes = 8588
Start of Free ITCM = 24180 [5E74]
End of Free ITCM = 32768 [8000]
Funny note: If not 'used' the build drops that 'fill[]' from allocation++++++++++++++++++++++
Size of Free ITCM in Bytes = 31900
Start of Free ITCM = 33636 [8364]
End of Free ITCM = 65536 [10000]
Great. Not easy to use - It's quite possible that if you change only one line in your program, the free space can be the half or even near zero
But may be usefule sometimes.
FlexRAM section ITCM+DTCM = 512 KB
Config : aaaaaaaf
ITCM : 33632 B (51.32% of 64 KB)
DTCM : 12992 B ( 2.83% of 448 KB)
Available for Stack: 445760
OCRAM: 512KB
DMAMEM: 12384 B ( 2.36% of 512 KB)
Available for Heap: 511904 B (97.64% of 512 KB)
Flash: 42992 B ( 2.12% of 1984 KB)
@Frank - did you see that KurtE updated github.com/KurtE/imxrt-size that you originally made?
Could have sworn that some of the comments earlier in this thread already did mention that you started the imxrt-size stuff...Yes
I don't use it anymore.
Edit: Would have been nice to see my name there - but OK, not really needed for such a dumb program with a few lines.
// from the linker
// extern unsigned long _stextload;
extern unsigned long _stext;
extern unsigned long _etext;
// extern unsigned long _sdataload;
extern unsigned long _sdata;
extern unsigned long _edata;
extern unsigned long _sbss;
extern unsigned long _ebss;
// extern unsigned long _flexram_bank_config;
extern unsigned long _estack;
void DumpMemoryInfo() {
#if defined(__IMXRT1062__)
uint32_t flexram_config = IOMUXC_GPR_GPR17;
Serial.printf("IOMUXC_GPR_GPR17:%x IOMUXC_GPR_GPR16:%x IOMUXC_GPR_GPR14:%x\n",
flexram_config, IOMUXC_GPR_GPR16, IOMUXC_GPR_GPR14);
Serial.printf("Initial Stack pointer: %x\n", &_estack);
uint32_t dtcm_size = 0;
uint32_t itcm_size = 0;
for (; flexram_config; flexram_config >>= 2) {
if ((flexram_config & 0x3) == 0x2) dtcm_size += 32768;
else if ((flexram_config & 0x3) == 0x3) itcm_size += 32768;
}
Serial.printf("ITCM allocated: %u DTCM allocated: %u\n", itcm_size, dtcm_size);
Serial.printf("ITCM init range: %x - %x Count: %u\n", &_stext, &_etext, (uint32_t)&_etext - (uint32_t)&_stext);
Serial.printf("DTCM init range: %x - %x Count: %u\n", &_sdata, &_edata, (uint32_t)&_edata - (uint32_t)&_sdata);
Serial.printf("DTCM cleared range: %x - %x Count: %u\n", &_sbss, &_ebss, (uint32_t)&_ebss - (uint32_t)&_sbss);
Serial.println("Now fill rest of DTCM with known pattern"); Serial.flush(); //
// Guess of where it is safe to fill memory... Maybe address of last variable we have defined - some slop...
for (uint32_t *pfill = (&_ebss + 1); pfill < (&itcm_size - 10); pfill++) {
*pfill = 0x01020304; // some random value
}
#endif
}
void EstimateStackUsage() {
#if defined(__IMXRT1062__)
uint32_t *pmem = (&_ebss + 1);
while (*pmem == 0x01020304) pmem++;
Serial.printf("Estimated max stack usage: %d\n", (uint32_t)&_estack - (uint32_t)pmem);
#endif
}
Yes
I don't use it anymore.
Not a problem... There is now a readme...As I said, not a big problem - but if you copy 99% of a whole program, modify just a very few lines and upload to another platform( Github) a little info there (Github) is nice.
Here, it's not needed. Here, with copying some lines or functions, I'm 100% with you.
Thanks
[...]
DTCM:
491520 Bytes (480 kB)
- 12992 Bytes (12 kB) global variables
- 1340 Bytes (1 kB) [COLOR=#b22222][I]max. stack so far[/I][/COLOR]
=========
477188 Bytes free (466 kB), 14332 Bytes in use (13 kB).
[...]
Its been so long now since I read the overtempt seq but I do remember that when a reset triggers the T4 sets a register value for overtemp and was wondering at the time if we could then use that to shut it down. Have to reread that RM again - argh!!! I think it was in SNVS section have to go back again so don't hold me to that.That's a good point.
Maybe we can also extend startup.c so that it shuts down after reboot(?)