I really didn’t want to be engaged in code optimization, at the same time adding problems with finding new bugs. Therefore, it was timely remembered that this version of the microcontroller has an additional 64K RAM segment (CCM SRAM) on board, which has not been used in any way now. Eureka - here it is, the solution!
Unfortunately, it turned out to be not so simple.
Search results for a turnkey solution
The official documentation for CCMRAM provides examples for placing executable code, a stack, or individual variables in it.
Searching the forums yielded several links to different ways to use CCMRAM, but unfortunately, they were all different variations of the ways that were described in the official documentation. And all of them required shoveling through the source code to add attributes when declaring each function or variable.
For GCC, in my case, something like this:
__attribute__((section(".ccmram")));
In addition, some variables have a default value, which requires modifying the bootloader so that when the firmware starts, such variables are copied to a separate area for initialized or zeroed variables.
Well, the final difficulty was the limitations of CCMRAM itself. It hangs on a separate bus to which DMA has no access, and it was planned to use direct memory access very actively.
In other words, solving one problem, one could accidentally add a bunch of others, and dig into debugging to find the introduced bugs.
Fortunately, we managed to find a simple solution on the part of FreeRTOS.
The heap size was less than the size of the CCM RAM segment and the decision was self-evident - to move the heap to this partition.
And we managed to do this with minimal code changes.
- A new section is added to the ld file (in my case STM32F407VGTX_FLASH.ld):
.ccmram : { . = ALIGN(8); . = . + _Min_Heap_Size; . = ALIGN(8); } >CCMRAM
- In the section "._user_heap_stack" a line is commented or deleted
/* . = . + _Min_Heap_Size; */
Lines with _Min_Heap_Size are required for the linker to issue warnings in case of insufficient RAM size. - A single variable is added to the body of the program.
uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__((section(".ccmram")));
- And when building a project, a preprocessor definition is added
configAPPLICATION_ALLOCATED_HEAP=1
As a result - a bunch of FreeRTOS in CCM SRAM with a minimum number of edits in the source code!