Running Code from RAM2 on Teensy 4.0

Evgeni

Member
Hi all,

I'm working on a project where I need to load and execute code dynamically from an SD card. Specifically, I’m allocating memory in RAM2 using malloc(), copying precompiled function code into that memory region, and then trying to call it via a function pointer.

The code seems to load fine, but when I try to call the function pointer, the Teensy 4.0 crashes after a few seconds (when attempting to run the set function but it doesn't run it).

Digging through the i.MXRT1062 reference manual, I came across the IOMUXC_GPR_GPR17 register, which appears to control executable regions among other things. In my current setup (after loading the SD card code and initializing everything else), this register ends up having the value 0xAAAAAAAF.

I’m wondering:

  1. Can you run executable code from RAM2 on the Teensy 4.0?
  2. Do I need to modify IOMUXC_GPR_GPR17 to make this possible?
  3. Is there anything else that needs to be configured to allow execution from RAM2?
 
This isn't due to GPR17, that only controls how the first 512KB of ram are configured (RAM1). The problem that you are running into is that the RAM2 section is set as non-executable in the MPU. The MPU is not a Teensy-specific feature, it's part of a standard ARM Cortex-M CPU so the details can be found in their technical manuals.
 
Look for the configure_cache() function in startup.c, around line 310.

Arduino IDE stores the core library files in a hidden folder, {AppData} on Windows, ~/Library on MacOS, ~/.arduino15 on Linux, so you may need to do a special search to find the startup.c file on your computer. When you do, before trying changes just add a simple syntax error and click Verify in Arduino IDE. Getting the syntax error confirms you're editing the correct file. It's easy to end up wasting a lot of time wondering why your edits don't have any effect if you end up using the wrong file, so this quick syntax error test can save you some frustration.

For the actual edit, just remove "NOEXEC" from the pair of register writes for the memory region where you wish to execute code.
 
Thank you so so much Paul!

After some digging I found out that I also need to disable the D and I cache with SCB_DisableICache(); and SCB_DisableDCache();

But either way now that I am able to run code from the OCRAM comes the next challenge of interacting with outside variables and structures. Do you happen to know how to do that?
 
After some digging I found out that I also need to disable the D and I cache with SCB_DisableICache(); and SCB_DisableDCache();
That's going to cost you a lot of performance. It shouldn't be necessary if you handle the caches correctly; copy the executable code to its destination then flush it from the data cache and invalidate the instruction cache on the same range.

But either way now that I am able to run code from the OCRAM comes the next challenge of interacting with outside variables and structures. Do you happen to know how to do that?
That's a huge question with no simple answer, especially given we have no idea how you're compiling the dynamic code in the first place - is it relocatable or does it have to be in a fixed location? What binary format is it stored in?
 
That's going to cost you a lot of performance. It shouldn't be necessary if you handle the caches correctly; copy the executable code to its destination then flush it from the data cache and invalidate the instruction cache on the same range.
Only when i disabled the caches was I able to run the code from ram. Later when I am able I'm going to look into enabling the caching.

That's a huge question with no simple answer, especially given we have no idea how you're compiling the dynamic code in the first place - is it relocatable or does it have to be in a fixed location? What binary format is it stored in?
Im going to attach the code that i use to compile and move the code onto the SD card automatically.

  • The build.sh is used to compile the .c code and output it as .bin file
  • The compile.py is used to automatically do the building and move the project onto the SD card.
  • The boot.c file is simple code that turns on an LED.
  • The teensy.ld file is the linker file.
If needed later i can attach the platformio project that is loaded onto the teensy flash.
 

Attachments

  • proj.zip
    2.2 KB · Views: 6
Back
Top