现在的问题是如何做到最好。
目前的方法是将链接脚本(gnu ld)中的RAM地址替换为外部RAM的地址。
这种方法的问题是,在初始化期间,由于FSMC尚未初始化,芯片必须在内部RAM上运行。
似乎工作,但一旦pvPortMalloc运行,我们得到一个硬故障,这可能是由于取消引用伪造地址,我们可以看到变量在系统初始化时没有正确初始化(这是有道理的,我猜想,因为内部RAM根本没有使用,当它可能应该是)。
我意识到这是一个模糊的问题,但是在Cortex M4 MCU的外部RAM中运行代码时的一般方法是什么,更具体的STM32F4?
谢谢
FreeRTOSConfig.h 中的 configTOTAL_HEAP_SIZE 符号指定。 FreeRTOS使用它的 pvPortMalloc 函数在这个内存区域中分配任务堆栈,因此这里的主要目标是将FreeRTOS堆区放入外部SRAM。
FreeRTOS堆内存区域定义在 heap _ *。c 中(除 heap_3.c 使用标准库malloc并且没有定义任何自定义堆区),该变量称为 ucHeap 。您可以使用您的编译器扩展来设置其部分。对于GCC,这可能类似于:
$ b $ pre $ static uint8_t ucHeap [configTOTAL_HEAP_SIZE] __attribute__((section(.sram_data)) );
现在我们需要配置链接器脚本来将此自定义部分放置到外部SRAM中。有几种方法可以做到这一点,这取决于你使用的工具链。对于GCC来说,一种方法是为SRAM定义一个存储区域,然后为。sram_data添加一段以加入SRAM区域,如下所示: p>
内存$ b $ p
{
...
/ *定义SRAM区域* /
sram:ORIGIN =< SRAM_START_ADDR>,LENGTH =< SRAM_SIZE>
}
部分
{
...
/ *定义.sram_data部分并将其放入sram区域* /
.sram_data :
{
*(。sram_data)
}> sram
...
}
这会将 ucHeap 区域放置在外部SRAM中,而所有其他文本和数据区域将放置在默认的内存区域(内部闪存和RAM)。
几个注释:
另一个(也可能更简单的)解决方案是将ucHeap变量定义为指针而不是数组,如下所示:
static uint8_t * const ucHeap =< SRAM_START_ADDR>;
这不需要任何特殊的链接器脚本编辑,所有内容都可以放在默认的部分。请注意,通过此解决方案,链接程序不会明确地为堆保留任何内存,并且会丢失一些潜在有用的信息/错误(如堆区不适合ext RAM)。但只要你在外部RAM中只有 ucHeap ,并且你的 configTOTAL_HEAP_SIZE 小于外部RAM大小,很好。
We have a thesis project at work were the guys are trying to get external RAM to work for the STM32F417 MCU.The project is trying out some stuff that is really resource hungry and the internal RAM just isn't enough.
The question is how to best do this.
The current approach has been to just replace the RAM address in the link script (gnu ld) with the address for external RAM.
The problem with that approach is that during initialisation, the chip has to run on internal RAM since the FSMC has not been initialized.
It seems to work but as soon as pvPortMalloc is run we get a hard fault and it is probably due to dereferencing bogus addresses, we can see that variables are not initialized correctly at system init (which makes sense I guess since the internal RAM is not used at all, when it probably should be).
I realize that this is a vague question, but what is the general approach when running code in external RAM on a Cortex M4 MCU, more specifically the STM32F4?
Thanks
解决方案FreeRTOS defines and uses a single big memory area for stack and heap management; this is simply an array of bytes, the size of which is specified by the configTOTAL_HEAP_SIZE symbol in FreeRTOSConfig.h. FreeRTOS allocates tasks stack in this memory area using its pvPortMalloc function, therefore the main goal here is to place the FreeRTOS heap area into external SRAM.
The FreeRTOS heap memory area is defined in heap_*.c (with the exception of heap_3.c that uses the standard library malloc and it doesn't define any custom heap area), the variable is called ucHeap. You can use your compiler extensions to set its section. For GCC, that would be something like:
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".sram_data")));
Now we need to configure the linker script to place this custom section into external SRAM. There are several ways to do this and it depends again on the toolchain you're using. With GCC one way to do this would be to define a memory region for the SRAM and a section for ".sram_data" to append to the SRAM region, something like:
MEMORY { ... /* Define SRAM region */ sram : ORIGIN = <SRAM_START_ADDR>, LENGTH = <SRAM_SIZE> } SECTIONS { ... /* Define .sram_data section and place it in sram region */ .sram_data : { *(.sram_data) } >sram ... }
This will place the ucHeap area in external SRAM, while all the other text and data sections will be placed in the default memory regions (internal flash and ram).
A few notes:
Another (and possibly simpler) solution would be to define the ucHeap variable as a pointer instead of an array, like this:
static uint8_t * const ucHeap = <SRAM_START_ADDR>;
This wouldn't require any special linker script editing, everything can be placed in the default sections. Note that with this solution the linker won't explicitly reserve any memory for the heap and you will loose some potentially useful information/errors (like heap area not fitting in ext RAM). But as long as you only have ucHeap in external RAM and you have configTOTAL_HEAP_SIZE smaller than external RAM size, that might work just fine.
这篇关于STM32F4在外部RAM中运行FreeRTOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!