Moving ISRs to ITCM RAM
Before I go on to give advice here, let me state for the record that i’ve never tried to do with an ARM core device and GCC what you’re describing here, but I’m familiar in a general sense with the concept of placing a section of code that is “loaded” in ROM/FLASH and then copied/relocated to RAM, and have done this with different toolchains and MCUs other than the STM32.
I think you have the linker script syntax correct - in particular, the bit at the end of the .itcm_text section declaration (>ITCM_RAM AT >FLASH) is critical. You want to make sure that your itcm-destined code is loaded into ROM (flash), but is located in ITCM_RAM.
I think what you’re looking for is the appropriate attribute syntax that you add to all functions that you want placed in a non-standard section. Here’s what it would look like:
int foo(int bar) __attribute__((section(".itcm_text"))) { // Code }
You’ll need to add the attribute directive shown in the example above to each function or variable declaration that you want to have placed in the .itcm_text section.
You might want to modify your linker command file to add some symbol definitions that will make it easier for your code to find (and copy) the .itcm_text section to ITCM_RAM
.itcm_text : { . = ALIGN(4); itcm_text_start = .; *(.itcm_text) /* Fast-executing code */ *(.itcm_text*) /* Fast-executing code */ . = ALIGN(4); itcm_text_end = .; } >ITCM_RAM AT >FLASH
When it comes time to copy the ITCM code in ROM to ITCM_RAM, you should be able to do something like this:
// The "variables" referenced here don't actually contain anything meaningful - they are defined as symbols // within the linker script. To extract the value assigned to each of these symbols, you need to take the // address-of them (use the & address-of operator); e.g.: // unsigned int section_start = (unsigned int) &itcm_text_start; extern const unsigned char itcm_text_start; // Make these uint8_t/char so they are treated as byte pointers when address-of'ed extern const unsigned char itcm_text_end; unsigned int itcm_text_size = (unsigned int) (&itcm_text_end - &itcm_text_start); // Pointer math should will work if these are declared as a char/byte type unsigned char *itcm_ram_addr = ??? // Fill this in - could also get it from linker symbol if you add one memcpy(itcm_ram_addr, &itcm_text_start, itcm_text_size);
Caveat: I’ve written the above “off the cuff” after doing a little research - I’ve not actually tried or tested any of it. I’ve probably got one or more of the details wrong. I may need to do something like this in one of my own projects I’ll be working on soon so I figured I’d start to research it now and possibly answer laltmann’s question at the same time.