答案 0 :(得分:3)
如果您运行的是最新版本的IAR EWARM,则会有一个内置工具,您会发现这些问题非常有用。
对于第一个问题,您需要在地图文件中搜索每个任务堆栈的名称。在这种情况下,地图文件并不是很有用,因为您可能最好在项目中搜索CPU_STK
类型,因为这样可以为您提供所有正确定义的堆栈的结果。如果您查看地图文件,可能会看到如下所示的行:
MainStack 0x20000000 0x1000 Data Lc main.o [1]
这意味着MainStack
(可能是MainTask
的堆栈)的大小为0x1000或4096字节。第一列是符号名称,第二列是地址空间中的位置,第三列是大小,第四列是类型(数据,代码),第五列是范围(Lc = local,Gb = Global),最后一列是它所在的对象模块。
如果您在项目中搜索CPU_STK
的实例,则可以找到以下内容:
static CPU_STK MainStack[4096];
这为您提供MainStack
大小为4096的相同信息,但通过搜索CPU_STK,它还会为您提供其他任务的结果,因此您可能会在结果中看到以下内容:
static CPU_STK MainStack[4096];
static CPU_STK AuxStack[512];
所以,现在你可以看到它还有AuxStack
(大概是AuxTask
),它是512字节。这将需要在地图文件中搜索特定的堆栈名称以获得结果,因此我会发现这更容易。
对于这个,您需要深入研究链接器配置文件或选项中的链接器部分。更简单的方法是通过选项。转到项目选项,然后转到左侧的链接器项。在配置选项卡下,选择编辑...,然后转到堆栈/堆选项卡。这将使您可以轻松访问IAR将用于在链接器中分配HEAP和CSTACK内存区域的大小。
或者,您可以深入了解.icf
文件,您可能会找到一组这样的行:
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x400;
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
它看起来也可能完全不同!很难给出一个广义的答案,所以你最好看看选项。但是,在上面的代码中,您可以看到CSTACK
和HEAP
的大小由文件前面定义的符号定义。您可以按照这些定义来获取大小。但是,你的链接器文件可能与此截然不同,正如我所说,很难给出一般答案。
较新版本的IAR具有很好的实用程序,可以确定任何函数所需的堆栈深度。在项目选项中,在“高级”选项卡的“链接器”下,可以选中“#34;启用堆栈使用情况分析"”。启用此功能后,您的地图文件将包含根功能及其最大调用链。例如,我的MainTask
看起来像这样:
Uncalled function
"MainTask" in main.o [1]: 0x0000ac41
Maximum call chain *?* 396 bytes
所以,这告诉我MainTask是一个未调用的函数(它不是直接调用,而是由函数指针调用,IAR无法自动解析),它需要396个字节的堆栈。在它下面,它将显示最多396个字节的调用链。
这个工具值得注意的是,如果你使用函数指针和间接调用,IAR就无法自动找出这些导致的位置。有一组pragma
指令可用于告诉它在间接调用点调用哪些可能的函数,并且您需要将它们放入以获得100%准确的堆栈深度。 / p>
另一种方法是在硬件上运行程序,但让OS监视器堆栈溢出。 Micrium有一个关于检测堆栈溢出的页面:Detecting Task Stack Overflows。此外,以下是有关函数的文档,以获取有关任务堆栈使用情况的信息:OSTaskStkChk()