makefile - interpreting arm-none-eabi-size output - am I over any limit? t4.1

Status
Not open for further replies.

nmz787

Member
I am having weird issues, adding a function call from one file (serial handler) to another file's function that just has a Serial.println in it causes my teensy4.1 to fail to "live". By live I mean the serial port (/dev/ttyACM0) doesn't show up and I get no response on the ethernet.

I'm using a makefile to build and upload, and there's this part of the output:
Code:
$ make upload
-e [CXX]	src/serial.cpp
-e [LD]	mytoy.elf
-e [HEX]	mytoy.hex
   text	   data	    bss	    dec	    hex	filename
 305456	  39132	 334756	 679344	  a5db0	mytoy.elf

assuming those are in bytes, we're under the 8MB and 1MB flash/RAM limits shown here:
https://www.pjrc.com/teensy/techspecs.html

but I'm not sure I'm interpreting that correctly.

At this point since there's no JTAG interface, I'm at a loss for how to go about debugging where things are going (so horribly) wrong.
 
A lot going on not shown - must be some good reason to have a lone .println() in a second file?

But putting that same function in the same file causes no trouble?
 
assuming those are in bytes, we're under the 8MB and 1MB flash/RAM limits shown here:
https://www.pjrc.com/teensy/techspecs.html
but I'm not sure I'm interpreting that correctly.

I use the following linker parameters in my makefiles:
Code:
-Wl,[COLOR="#FF0000"][B]--print-memory-usage[/B][/COLOR],--gc-sections,--relax -T$(CORE_BASE)/imxrt1062.ld

with the --print-memory-usage the linker will generate a much nicer size output. E.g.:
Code:
Memory region         Used Size  Region Size  %age Used
            ITCM:         32 KB       512 KB      6.25%
            DTCM:       14080 B       512 KB      2.69%
             RAM:       12384 B       512 KB      2.36%
           FLASH:       23892 B      1984 KB      1.18%

And, as defragster mentioned, without any code it is a bit difficult to support you.
 
I use the following linker parameters in my makefiles:
Code:
-Wl,[COLOR="#FF0000"][B]--print-memory-usage[/B][/COLOR],--gc-sections,--relax -T$(CORE_BASE)/imxrt1062.ld

That's exactly what I was looking for, thanks!
Code:
Memory region         Used Size  Region Size  %age Used
            ITCM:        160 KB       512 KB     31.25%
            DTCM:        353 KB       512 KB     68.95%
             RAM:       12416 B       512 KB      2.37%
           FLASH:      345120 B      7936 KB      4.25%
            ERAM:          0 GB        16 MB      0.00%

and while it doesn't fix my code, it's one less rock unturned.
 
A lot going on not shown - must be some good reason to have a lone .println() in a second file?

But putting that same function in the same file causes no trouble?

The actual code that I want to call is to setup the MD_AD9833 library... it seems that when I comment the "begin" code for that out, or conversely comment out the EthernetBonjour.run() call in my loop()... that my serial console boots up. The only thing I notice in the EthernetBonjour code is a lot of malloc/free calls, but nothing else that jumps out at me as causing something so strange as what I'm experiencing.

I'm not sure if I should pare down my codebase to provide a shareable example, or if I should just give up! Or look elsewhere in my code for, presumably, memory corruption.
 
It seems this does point to a problem:
Code:
            ITCM:        160 KB       512 KB     31.25%
            DTCM:        353 KB       512 KB     68.95%

ITCM (code) and DTCM (prealloc RAM) are in in RAM1 of 512KB. The 1MB of memory is not contiguous into RAM2

For memory layout see:: pjrc.com/store/teensy40.html
calc shows :: 100.2% and 513KB
That leaves negative room ... and the stack will come down.

Some code needs to be marked to stay in flash with FLASHMEM - some or all of a 32KB block until it drops 32KB and shows 128KB in ITCM
Or some RAM buffers need to shrink or move to DMAMEM/RAM2 with malloc.

@luni: --print-memory-usage is cool it works in board.txt on the .ld line. Not as complete for ITCM usage as (windows program) imxrt-size.exe with linker showing:
Code:
Memory region         Used Size  Region Size  %age Used
            ITCM:         64 KB       512 KB     12.50%
            DTCM:       17216 B       512 KB      3.28%
             RAM:       24736 B       512 KB      4.72%
           FLASH:       68484 B      7936 KB      0.84%
            ERAM:          0 GB        16 MB      0.00%

versus imxrt-size.exe - also showing the Stack room:
Code:
FlexRAM section ITCM+DTCM = 512 KB
    Config : aaaaaaaf (DDDDDDDDDDDDDDII)
    ITCM :  49720 B	(75.87% of   64 KB)
    DTCM :  17216 B	( 3.75% of  448 KB)
    Available for Stack: 441536
OCRAM: 512KB
    DMAMEM:  24736 B	( 4.72% of  512 KB)
    Available for Heap: 499552 B	(95.28% of  512 KB)
Flash:  68480 B	( 0.84% of 7936 KB)
 
Last edited:
It seems this does point to a problem:
Code:
            ITCM:        160 KB       512 KB     31.25%
            DTCM:        353 KB       512 KB     68.95%

ITCM (code) and DTCM (prealloc RAM) are in in RAM1 of 512KB. The 1MB of memory is not contiguous into RAM2

For memory layout see:: pjrc.com/store/teensy40.html
calc shows :: 100.2% and 513KB
That leaves negative room ... and the stack will come down.

Some code needs to be marked to stay in flash with FLASHMEM - some or all of a 32KB block until it drops 32KB and shows 128KB in ITCM
Or some RAM buffers need to shrink or move to DMAMEM/RAM2 with malloc.

great point! I was assuming that moving the the Makefile would still give me the benefit of however the Arduino GUI alerted me (I think) in the past about exceeding memory limits (when I was making super large buffers at one point a while ago).

Adding
Code:
FLASHMEM
before each function in the MD_AD9833 signal generator library reduced the ITCM percentage to 25%, and now things are all working!




@luni any tricks for enabling the Makefile to enforce the memory-available calculation?
 
@luni any tricks for enabling the Makefile to enforce the memory-available calculation?

I might be completely wrong, but as I understand it, ITCM and DTCM share a common 512kB RAM (RAM1). So, you need to make sure that the sum of ITCM and DTCM is not larger that 512kB. The linker script assigns 512kB to both regions (there probably is a very good reason for this) so the linker assumes there is enough memory and doesn't warn you in this case. I would be very surprised if the Arduino IDE knows more than the linker and warns you in those cases...

KurtE is maintaining a windows exe which analyzes the .elf file to get more info about memory usage (https://github.com/KurtE/imxrt-size). You could call it from your makefile. But I don't know if this takes the shared memory correctly into account

But again, linker scripts are far out of my comfort zone, better wait until someone with more insight answers this.
 
Good morning all,

Actually the tool mentioned started off with @FrankB - And I did some quick and dirty updates to it to show the data I was interested in.

As @defragster showed:
Code:
FlexRAM section ITCM+DTCM = 512 KB
    Config : aaaaaaaf (DDDDDDDDDDDDDDII)
    ITCM :  49720 B	(75.87% of   64 KB)
    DTCM :  17216 B	( 3.75% of  448 KB)
    Available for Stack: 441536
OCRAM: 512KB
    DMAMEM:  24736 B	( 4.72% of  512 KB)
    Available for Heap: 499552 B	(95.28% of  512 KB)
Flash:  68480 B	( 0.84% of 7936 KB)
The code looks at how the DTCM/ITCM will be configured: Config : aaaaaaaf (DDDDDDDDDDDDDDII)
The first part is the raw register values that are used to configure... The second part in () is the Easier to understand part.
The DTCM/ITCM are allocated in 32KB blocks of memory (16 of them) D is data I is instruction.

So that is what is used in the ITCM/DTCM lines below where ITCM is actually 64kb and DTCM is 448KB...
The program computes the Stack size as the actual size of data minus the allocated size and if not > 0 the program will return an error condition.

As for Linker scripts, It is also out of my comfort level as well. I think that maybe again Frank had an alternate one that only put stuff in ITCM that was marked fastrun....
But I have not looked.
 
@luni - p#8 not wrong :: see p#6 - for sure ITCM and DTCM are in an isolated 512KB - on a TCM BUS full speed with the processor clock.

And in fact the IDE has a trick to monitor that TCM usage and has a coded 'WARN at 99%' in boards.txt :: teensy41.build.warn_data_percentage=99

Since it was linux - and not sure if imxrt-size.exe had a version for that ... I just mentioned the concept - not the author - but yes that was a Frank_B creation.

speaking of imxrt-size: Looks like it could add a section for ERAM pre-alloc like the linker does? And as noted once @KurtE, the current imxrt-size has a debug print for stack that shows on all MCU's it seems outside the ifdef 1062.
 
And in fact the IDE has a trick to monitor that TCM usage and has a coded 'WARN at 99%' in boards.txt :: teensy41.build.warn_data_percentage=99
Interesting, do I understand correctly that it actually calculates the sum of ITCM and DTCM and warns if this is > 99% of 512Mb?
 
Interesting, do I understand correctly that it actually calculates the sum of ITCM and DTCM and warns if this is > 99% of 512Mb?

I am guessing it is pretty simple looking at the output:
Code:
"C:\\arduino-1.8.13\\hardware\\teensy/../tools/arm/bin/arm-none-eabi-size" -A "C:\\Users\\kurte\\AppData\\Local\\Temp\\arduino_build_837806/CSI_41_main.ino.elf"
Sketch uses 95448 bytes (1%) of program storage space. Maximum is 8126464 bytes.
Global variables use 123572 bytes (23%) of dynamic memory, leaving 400716 bytes for local variables. Maximum is 524288 bytes.
Sketch uses 95448 bytes (1%) of program storage space. Maximum is 8126464 bytes.
Global variables use 123572 bytes (23%) of dynamic memory, leaving 400716 bytes for local variables. Maximum is 524288 bytes.
It probably just looks at size of data/512kb and will warn then. As we can see from above sketch, it exceeded the sum and I don't believe it gave warnings... Maybe it did, but...
 
Status
Not open for further replies.
Back
Top