How To Maximize Memory Teensy 4.0

Thundercat

Well-known member
Hi all,

I've got a gigantic sketch over 30,000 lines of code in a Teensy 4.0. As might be expected I'm running out of memory for files, to the point I'm getting concerned I can continue development of the product using the sketch.

Of course I've moved large arrays into DMAMEM, but I still need more room.

Here's the most recent build results, using the "Fast" option in the compiler:

Opening Teensy Loader...
Memory Usage on Teensy 4.0:
FLASH: code:358632, data:1628768, headers:8984 free for files:35232
RAM1: variables:49856, code:356832, padding:3616 free for local variables:113984
RAM2: variables:21312 free for malloc/new:502976

I only have a few small images in the sketch, so besides the size of the code itself, what's eating the memory are the many fonts I've loaded. And yes I've reduced them as much as I can, but I can only reduce them so much.

What I'm wondering is, how can I move, for example, fonts into another area to maximize file usage? Could fonts be put into DMAMEM?

Sorry if this is an easy question; I'm trying to wrap my head around the memory system here and how to manage it better.

FYI I loaded the sketch into a Teensy 4.1 and still had same issue; regardless the 8MB memory size, the file memory was nearly eaten up again mostly by the fonts.

Thanks for any insights.

Mike

PS yes I'm aware I can compile for smallest code size, but I'm still limited here with not enough room leftover for additional development ideas I'd like to implement.
 
Memory Usage on Teensy 4.0:
FLASH: code:358632, data:1628768, headers:8984 free for files:35232
RAM1: variables:49856, code:356832, padding:3616 free for local variables:113984
RAM2: variables:21312 free for malloc/new:502976

FYI I loaded the sketch into a Teensy 4.1 and still had same issue; regardless the 8MB memory size, the file memory was nearly eaten up again mostly by the fonts.

I don't understand what you mean when you say "file memory was nearly eaten up again" on T4.1. Are you saying that your sketch is 2MB on T4.0, but somehow consumes 8MB on T4.1?

There is no way to load code/data directly into RAM. You can only copy code/data from FLASH to RAM at run-time. You could use the built-in SD on T4.1 to hold your fonts, or add an SD to your T4.0 system.
 
Compress your font files and decompress to heap / DMAMEM at boot? You don't say how you "reduced" them, so maybe you already did that! If not, I could only find this thread on the forum ... obviously you'd want to compress offline, make source files from the result, and only decompress on the Teensy.

Otherwise, add a (Q)SPI Flash chip?

Don't understand how you manage to end up with a Teensy 4.1 having its memory "nearly eaten up" - it has 4x the Flash, so as long as your fonts are in FLASHMEM there should be loads of space for them, compared to a 4.0
 
I don't understand what you mean when you say "file memory was nearly eaten up again" on T4.1. Are you saying that your sketch is 2MB on T4.0, but somehow consumes 8MB on T4.1?

There is no way to load code/data directly into RAM. You can only copy code/data from FLASH to RAM at run-time. You could use the built-in SD on T4.1 to hold your fonts, or add an SD to your T4.0 system.

Hi, thanks for the message. No, I'm not saying it took 8MB on a Teensy 4.1 and 2MB on a Teensy 4.0. What I meant was, it took the same amount of space on the Teensy 4.1 as it does on the Teensy 4.0 (which you would expect), but, the Teensy 4.1 was also nearly out of memory like the Teensy 4.1, which confused me because I thought I had 6MB more to work with on it. But obviously it doesn't allocate that memory automatically.

Hence my question is there a way to tell the MCU where to load things?

Thanks for the info on the SD card of the Teensy 4.1; I suspected as much but have not spent time with this yet.
 
Compress your font files and decompress to heap / DMAMEM at boot? You don't say how you "reduced" them, so maybe you already did that! If not, I could only find this thread on the forum ... obviously you'd want to compress offline, make source files from the result, and only decompress on the Teensy.

Otherwise, add a (Q)SPI Flash chip?

Don't understand how you manage to end up with a Teensy 4.1 having its memory "nearly eaten up" - it has 4x the Flash, so as long as your fonts are in FLASHMEM there should be loads of space for them, compared to a 4.0

Thanks much. What I meant by "reduced them" was eliminated any fonts I could get away with eliminating. Not compressing them.

I will look into your suggestion about compressing, very interesting, thanks so much.

And I don't understand either how it could run out of memory either. The font files are loading into PROGMEM - is this the same as FLASHMEM?

I'm sorry if that's so basic; I'm trying to understand...thanks.
 
Thanks much. What I meant by "reduced them" was eliminated any fonts I could get away with eliminating. Not compressing them.
That's what I'd expected ... but it's always worth checking!
I will look into your suggestion about compressing, very interesting, thanks so much.

And I don't understand either how it could run out of memory either. The font files are loading into PROGMEM - is this the same as FLASHMEM?

I'm sorry if that's so basic; I'm trying to understand...thanks.

https://www.pjrc.com/store/teensy41.html#memory is helpful, though it's quite likely you already found it. Pretty sure PROGMEM is to data as FLASHMEM is to code.

Both Teensy 4.x have the same RAM, 2 chunks of 512MB each, so it sounds as if that's what you're actually running out of, in which case decompressing fonts from Flash to RAM will definitely be a Bad Thing! You don't seem to be hurting that badly for RAM from the link report, there's still 100kB of RAM1 for the stack, and most of RAM2 for heap / DMAMEM. Of course, with the latter, one can't see how much heap your application allocates at run-time.

Can you post a super-cut-down version of your code, which e.g. just prints the first 50 values from every font file to the serial port? I realise you don't want to post 30k lines of proprietary code, I wouldn't either.
 
That's what I'd expected ... but it's always worth checking!
Thanks! And thanks again for the post link.

Both Teensy 4.x have the same RAM, 2 chunks of 512MB each, so it sounds as if that's what you're actually running out of, in which case decompressing fonts from Flash to RAM will definitely be a Bad Thing! You don't seem to be hurting that badly for RAM from the link report, there's still 100kB of RAM1 for the stack, and most of RAM2 for heap / DMAMEM. Of course, with the latter, one can't see how much heap your application allocates at run-time.
Useful, thanks so much.

Can you post a super-cut-down version of your code, which e.g. just prints the first 50 values from every font file to the serial port? I realise you don't want to post 30k lines of proprietary code, I wouldn't either.

Not sure exactly what you're asking here - the code is broken into many many different loops and each one has its own void and set of fonts; most of the font data loaded is there to support user interaction such as changing names of things, hence lots of each font is loaded as I don't know what the users will want to be able to name with what letters. I have experimented with cutting down the fonts to just letters I needed for large fonts (I have a couple of 144 point fonts), but other than that I'm not sure how to compress them. I'll take a look at the link you provided.

So is it fair to say that once the RAM is used up, it's used up?

Is it possible to add a memory chip to the Teensy 4.0 re: your comment "Otherwise, add a (Q)SPI Flash chip?"

Thanks again, I totally appreciate your help and everyone's suggestions here are great.

Mike
 
Is there a way I can use the "new/malloc" area listed: "RAM2: variables:21312 free for malloc/new:502976"

Also is there a way to load some of the fonts into DMAMEM?

Sorry again if this is obvious...

Mike
 
You can move fonts to RAM2 at runtime. You can't locate anything into RAM at compile time. All of your code and data goes into FLASH, and it can be copied to RAM during boot or setup or anytime you want, but it still needs to fit into FLASH. Loading a sketch to Teensy means storing the entire sketch in FLASH.
 
Joe, that is so helpful! Thanks so much! Even though I'm programing now for a year, there's still so much I don't know or understand; most of these forum posts here confuse me so much, but you've made this very clear! So thanks!

It sounds like I may need to start using Teensy 4.1 and buy the additional RAM chips and solder them in; this would definitely make more room for the program code, correct?

Again, thanks!
 
It sounds like I may need to start using Teensy 4.1 and buy the additional RAM chips and solder them in; this would definitely make more room for the program code, correct?

There is more room for code because T4.1 has 8 MB of program FLASH, whereas T4.0 has 2 MB of program FLASH. The two pads on the bottom of T4.1 can be used for PSRAM and/or more FLASH, but neither of those increases the maximum possible sketch size. The sketch can ONLY be stored in the program FLASH. If you add another FLASH chip on the bottom of T4.1, you can use it to store data, either with a file system like you would have on an SD card, or with low-level writes if you want. If you add PSRAM to the bottom of T4.1, you can use it to store large data sets at run-time, but not at compile time. Hopefully your sketch (including all the fonts you want) will fit in the 8 MB program FLASH on T4.1.
 
If your fonts are marked as PROGMEM, then they will stay in flash and never use up your precious RAM. What symptoms are you observing to lead you to believe you are running out of RAM?
 
There is more room for code because T4.1 has 8 MB of program FLASH, whereas T4.0 has 2 MB of program FLASH. The two pads on the bottom of T4.1 can be used for PSRAM and/or more FLASH, but neither of those increases the maximum possible sketch size. The sketch can ONLY be stored in the program FLASH. If you add another FLASH chip on the bottom of T4.1, you can use it to store data, either with a file system like you would have on an SD card, or with low-level writes if you want. If you add PSRAM to the bottom of T4.1, you can use it to store large data sets at run-time, but not at compile time. Hopefully your sketch (including all the fonts you want) will fit in the 8 MB program FLASH on T4.1.

I'm sure the sketch will more than easily fit, as it already fits on a Teensy 4.0.

I totally appreciate your kindness Joe, and I know these are newbie questions and you've been very understanding and clear, so many, many thanks! It sounds like if I need more room I will absolutely need to move to a Teensy 4.1, which I can do.

This product has been one evolution after another, and over time it gets better and better with support and help like yours.

So again, thanks!

Mike
 
Another question - do you think there's any value in trying to compress the fonts? Would this work, and then decompress them when needed? The fonts are what's killing me, but having nice fonts has made the product terrific, so I'm loathe to remove them at this point. But if I could just make some more room available, it would help a lot, as I have a great little screensaver I want mouse but I need to load a graphic that currently doesn't fit.

Thanks again,

Mike
 
If your fonts are marked as PROGMEM, then they will stay in flash and never use up your precious RAM. What symptoms are you observing to lead you to believe you are running out of RAM?

Hi Joe, I'm not being clear, sorry.

Here was the message:

Memory Usage on Teensy 4.0:
FLASH: code:358632, data:1628768, headers:8984 free for files:35232
RAM1: variables:49856, code:356832, padding:3616 free for local variables:113984
RAM2: variables:21312 free for malloc/new:502976

The "free for files" is at 35232 presently, but what I am needing is to load an image that is larger than that. The image file takes up almost the whole 320x240 LCD screen, so the image is a bit large. And the "free for files" has been dwindling as I've continued to write more code too. I can't compile "Fastest" anymore; only "Fast," as the "Fastest" doesn't fit anymore, and I'm afraid soon I'll have to do it the most compact size which I understand might be slower performance.

Again sorry if these are stupid/newbie questions; I've been reading a lot but not quite getting my head around all this yet.

Thanks for any insights.

Mike
 
If your fonts are marked as PROGMEM, then they will stay in flash and never use up your precious RAM. What symptoms are you observing to lead you to believe you are running out of RAM?

Thank-you thebigg. I'm not having any bad symptoms, just running out of room for coding at this point.
 
Essentially, the end result of a build (including all code and variables) has to fit into flash. You are running out of flash space. The only things you can do is 1) remove variables, 2) change the compiler optimisation to one which will hopefully reduce code size or 3) upgrade to T4.1

Compressing images (using, for example, jpg) is probably possible but will require you to include the decompression code in your image which will reduce free space even more. The ili9341 font format is already quite compressed.
 
Essentially, the end result of a build (including all code and variables) has to fit into flash. You are running out of flash space. The only things you can do is 1) remove variables, 2) change the compiler optimisation to one which will hopefully reduce code size or 3) upgrade to T4.1

Compressing images (using, for example, jpg) is probably possible but will require you to include the decompression code in your image which will reduce free space even more. The ili9341 font format is already quite compressed.

Very helpful thebigg, many thanks. It's as I feared, but I appreciate it and gives me a way forward.

Thanks!

Mike
 
Note with images, as @thebigg mentioned you can do something like JPG to hold your files, which might require a jpg decoder.

Or sometimes you can roll your own. I know @mjs513 and myself a while ago was playing with a sketch to take IMU input and draw stuff on a TFT, like an airplane horizon indicator.

For this I played around with a simple Run Length Encoded(RLE) set of bitmaps. As there were large areas with the same pixel values (like black). Encoding/decoding was pretty simple, count # colors in a row that were the same. Many ways to do it, In the case that we were doing it, I simply had a word with count and a word with color... Could be smarter with it and maybe only encode if count > N...

Other options are also built into most of the TFT libraries, to draw images with a fixed number of colors.
Code:
// writeRect8BPP - 	write 8 bit per pixel paletted bitmap
// writeRect4BPP - 	write 4 bit per pixel paletted bitmap
// writeRect2BPP - 	write 2 bit per pixel paletted bitmap
// writeRect1BPP - 	write 1 bit per pixel paletted bitmap
Where you have the option to encode your image for 2, 4, 16, or 256 colors and cut the number of bits used per pixel....

Good luck.
 
Note with images, as @thebigg mentioned you can do something like JPG to hold your files, which might require a jpg decoder.

Or sometimes you can roll your own. I know @mjs513 and myself a while ago was playing with a sketch to take IMU input and draw stuff on a TFT, like an airplane horizon indicator.

For this I played around with a simple Run Length Encoded(RLE) set of bitmaps. As there were large areas with the same pixel values (like black). Encoding/decoding was pretty simple, count # colors in a row that were the same. Many ways to do it, In the case that we were doing it, I simply had a word with count and a word with color... Could be smarter with it and maybe only encode if count > N...

Other options are also built into most of the TFT libraries, to draw images with a fixed number of colors.
Code:
// writeRect8BPP - 	write 8 bit per pixel paletted bitmap
// writeRect4BPP - 	write 4 bit per pixel paletted bitmap
// writeRect2BPP - 	write 2 bit per pixel paletted bitmap
// writeRect1BPP - 	write 1 bit per pixel paletted bitmap
Where you have the option to encode your image for 2, 4, 16, or 256 colors and cut the number of bits used per pixel....

Good luck.

Thanks Kurt!

You're forgetting one little salient fact: You're a genius! LOL! But true.

I appreciate the feedback; I'll do what I can and you all are amazing.

Thanks,

Mike
 
Back
Top