Arm 使用FreeRTOS的微控制器上未静态分配的RAM会发生什么情况
我正在用FreeRTOS做一个嵌入式项目,我只使用静态内存分配 查看我的链接器脚本,我发现以下内容占用了RAM空间:Arm 使用FreeRTOS的微控制器上未静态分配的RAM会发生什么情况,arm,embedded,microcontroller,freertos,Arm,Embedded,Microcontroller,Freertos,我正在用FreeRTOS做一个嵌入式项目,我只使用静态内存分配 查看我的链接器脚本,我发现以下内容占用了RAM空间: .data .bss \u用户\u堆\u堆栈 据我所知,链接过程中使用了\u user\u heap\u stack,以查看是否有足够的RAM空间用于用户指定的最小MSP堆栈大小。以下是我的链接器脚本中的一个相关片段: /* User_heap_stack section, used to check that there is enough RAM left */ ._
.data
.bss
\u用户\u堆\u堆栈
据我所知,链接过程中使用了\u user\u heap\u stack
,以查看是否有足够的RAM空间用于用户指定的最小MSP堆栈大小。以下是我的链接器脚本中的一个相关片段:
/* User_heap_stack section, used to check that there is enough RAM left */
._user_heap_stack :
{
. = ALIGN(8);
PROVIDE ( end = . );
PROVIDE ( _end = . );
. = . + _Min_Heap_Size;
. = . + _Min_Stack_Size;
. = ALIGN(8);
} >RAM
我相信MSP总是被初始化为指向RAM的末尾,而不管它的最小堆栈大小如何,并且从那里开始递减,数据被推送到堆栈上。我看到我的启动.S
文件将sp
配置如下:
_estack = 0x20004000; /* end of RAM */
Reset_Handler:
ldr sp, =_estack /* Atollic update: set stack pointer */
至于FreeRTOS任务,它们每个都有静态分配的堆栈空间,所以这与\u user\u heap\u stack
无关
我的问题是,在分配了RAM
.data
、.bss
和\u user\u heap\u stack
的情况下,我仍然有一些未分配的RAM,那么这些RAM会怎么样?有人用它吗?保留一些空闲RAM(即非静态分配的RAM)有用吗?还是只是浪费?或者,如果主堆栈的大小超过了\u Min\u stack\u size
?TL中指定的大小,那么它可能只是MSP使用的额外空间;DR-剩余的RAM由堆栈使用
或者,如果主堆栈的大小比_Min_stack_size中指定的要大,那么它可能只是MSP可以使用的额外空间 是的,这似乎是正确的。详见最后一段;不仅仅是堆栈更大 见:这部分,
_estack = 0x20004000; /* end of RAM */
Reset_Handler:
ldr sp, =_estack /* Atollic update: set stack pointer */
因此,至少引导sp将位于RAM的末尾
具有=.+_最小堆栈大小代码>只需确保堆栈最小,否则会发生链接器错误。您的堆栈实际上更大,并且至少在启动时使用它。我对FreeRTOS一无所知,但我怀疑这是系统堆栈,你有用户堆栈。ARM上的每个模式都有一个单独的堆栈。如果FreeRTOS有任何内存保护或特权级别,那么您将有多个堆栈。因此,一个任务崩溃(由于堆栈溢出等原因)不会使整个系统崩溃。只是tasksnote2堆栈已损坏,而不是管理整个系统的堆栈
将堆栈和堆放在一起是一个常见的习惯用法。堆向上,堆向下。这样,最小堆大小和最小堆栈大小都是虚构的。最终,当两者的大小都是总大小时,它们将发生碰撞。但是,如果堆栈进入堆逻辑空间或堆进入堆栈逻辑空间,只要它没有被另一个使用,事情可能会好起来。我所说的空格是指链接器文件中的常量,而不是实际使用中的值
注1:既浪费内存,又让RTOS代码与所有任务使用相同的堆栈,这有点疯狂。至少它不是一个健壮的操作系统
注2:我所说的任务是指一个可调度的实体。可能是进程、任务、线程、光纤等。TL;DR-剩余的RAM由堆栈使用
或者,如果主堆栈的大小比_Min_stack_size中指定的要大,那么它可能只是MSP可以使用的额外空间
是的,这似乎是正确的。详见最后一段;不仅仅是堆栈更大
见:这部分,
_estack = 0x20004000; /* end of RAM */
Reset_Handler:
ldr sp, =_estack /* Atollic update: set stack pointer */
因此,至少引导sp将位于RAM的末尾
具有=.+_最小堆栈大小代码>只需确保堆栈最小,否则会发生链接器错误。您的堆栈实际上更大,并且至少在启动时使用它。我对FreeRTOS一无所知,但我怀疑这是系统堆栈,你有用户堆栈。ARM上的每个模式都有一个单独的堆栈。如果FreeRTOS有任何内存保护或特权级别,那么您将有多个堆栈。因此,一个任务崩溃(由于堆栈溢出等原因)不会使整个系统崩溃。只是tasksnote2堆栈已损坏,而不是管理整个系统的堆栈
将堆栈和堆放在一起是一个常见的习惯用法。堆向上,堆向下。这样,最小堆大小和最小堆栈大小都是虚构的。最终,当两者的大小都是总大小时,它们将发生碰撞。但是,如果堆栈进入堆逻辑空间或堆进入堆栈逻辑空间,只要它没有被另一个使用,事情可能会好起来。我所说的空格是指链接器文件中的常量,而不是实际使用中的值
注1:既浪费内存,又让RTOS代码与所有任务使用相同的堆栈,这有点疯狂。至少它不是一个健壮的操作系统
注2:我所说的任务是指一个可调度的实体。可能是进程、任务、线程、光纤等。如果您可以验证代码中没有任何内容与之接触,那么代码中也没有任何内容与之接触(尽管通常情况下,C启动例程会在幕后将其归零)。有时使用的一种技术是使用一个神奇的值(可能通过修改启动代码来实现,而不是零)预先填充内存,运行一段时间,然后返回,然后查看发生了什么变化;问题是,这只显示您实际执行的代码路径的行为。有时,出于捕获溢出的希望,会将保护值放在已使用的值之间并进行检查,理论上,强制重新启动比在损坏状态下运行更好;但同样,这只会在事物主动变更时捕获它们,并且只有在检查程序及时看到它的情况下才会捕获。magic value方法是否通常假定一个活动的调试器连接?我设想您使用调试器运行代码,然后在使用调试器一段时间后返回并检查内存内容。如果我在现场部署系统,并且没有活动的调试连接,这将如何工作