This is a patch to the current v8.0.0 code that does the following two things:
- Global variables and Stack in separate RAM section:
Any global variables are surrounded with a macro portRAM_ATTRIB{...} now. This macro is defined in FreeRTOSConfig.h to move any variables to their own section. We use this to move any OS specific variable to the CCM of STM32F4xx or similar MCUs (CCM is a block of RAM that is directly coupled to the CPU to reduce the number of accesses to the memory MCU wide bus). Downside: No more DMA access to stack variables.
- Header cleanup
We use FreeRTOS as an external library in our projects. In order to clean up the include namespace, we moved all library includes to a sub path "freertos/", to minimize the global (include) namespace pollution. We would really like to see this change in a future version of {Free/...}RTOS.
The patch has been tested with STM32F407/STM32F417 controllers using Heap2, GCC 4.8.3 and no MPU. The patch comes as a diff file generated using " diff -rwd v8.0.0 v8.0.0orig > freertos8.0.0_ccm_header.diff" with the modified code in v8.0.0 and the original code in v8.0.0orig. The following lines need to be added to FreeRTOSConfig.h:
#if defined(USE_CCM_HEAP) && USE_CCM_HEAP
//Place heap and stack in CCM (STM32F4xx: 64KB, STM32F3xx: 8KB, STM32F{1,2}: none
#define STRCMPMCUM4 strcmp(MCU,"cortex-m4") //GCC extension
#if $STRCMPMCUM4 != 0
#error No CCM support in non cortex-m4 MCUs
#endif
#undef STRCMPMCUM4
#define portRAM_ATTRIBUTE(XXX) XXX __attribute__ ((section (".ccm." #XXX)))
#define portRAM_ATTRIBUTESIZE(XXX,SIZE_XXX) XXX[SIZE_XXX] __attribute__ ((section (".ccm." #XXX)))
#define portRAM_ATTRIBUTEINIT(XXX) XXX __attribute__ ((section (".ccminit." #XXX)))
#define portRAM_ATTRIBUTESIZEINIT(XXX,SIZE_XXX) XXX[SIZE_XXX] __attribute__ ((section (".ccminit." #XXX)))
#else
#define portRAM_ATTRIBUTE(XXX) XXX
#define portRAM_ATTRIBUTESIZE(XXX,SIZE_XXX) XXX[SIZE_XXX]
#define portRAM_ATTRIBUTEINIT(XXX) XXX
#define portRAM_ATTRIBUTESIZEINIT(XXX,SIZE_XXX) XXX[SIZE_XXX]
#endif
The macros "USE_CCM_HEAP=1" and "MCU=cortex-m4" must be defined to use CCM.
Further the linker file has to be extended by the following lines to correctly place the variables:
_eidata = ( _sidata + SIZEOF(.data) + 4);
.ccm_init : AT ( _sidata + SIZEOF(.data) + 4)
{
. = ALIGN(4);
_sccm_init = .;
*(.ccminit.*)
. = ALIGN(4);
_eccm_init = .;
} >CCMRAM
.ccm_noinit (NOLOAD) :
{
. = ALIGN(4);
_sccm = .;
*(.ccm.*)
. = ALIGN(4);
_eccm = .;
} >CCMRAM
And the startup.s file has to copy the initialized variables from flash to the RAM:
movs r1, #0
b LoopCCMCopyDataInit
CopyCCMDataInit:
ldr r3, =_eidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCCMCopyDataInit:
ldr r0, = _sccm_init
ldr r3, =_eccm_init
adds r2, r0, r1
cmp r2, r3
bcc CopyCCMDataInit
freertos8.0.0_ccm_header.diff