Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用C++;_C++_Embedded_Arm_Cortex M3 - Fatal编程技术网

C++ 如何使用C++;

C++ 如何使用C++;,c++,embedded,arm,cortex-m3,C++,Embedded,Arm,Cortex M3,cortex M3处理器启动文件允许您指定专用于堆栈和堆的RAM数量。对于C++代码库,有一个一般的经验法则,或者也许有一些更明确的方法来确定堆栈和堆大小的值吗?例如,您是计算唯一对象的数量和大小,还是使用编译后的代码大小 cortex M3处理器启动文件 允许您指定 专用于堆栈和 堆 这不是Cortex-M3的特性,而是开发工具链提供的启动代码。这是Keil ARM-MDK默认M3启动文件的工作方式。这有点不寻常;更常见的情况是指定堆栈大小,链接器在堆栈和静态内存分配之后的任何剩余内存都将成为

cortex M3处理器启动文件允许您指定专用于堆栈和堆的RAM数量。对于C++代码库,有一个一般的经验法则,或者也许有一些更明确的方法来确定堆栈和堆大小的值吗?例如,您是计算唯一对象的数量和大小,还是使用编译后的代码大小

cortex M3处理器启动文件 允许您指定 专用于堆栈和 堆

这不是Cortex-M3的特性,而是开发工具链提供的启动代码。这是Keil ARM-MDK默认M3启动文件的工作方式。这有点不寻常;更常见的情况是指定堆栈大小,链接器在堆栈和静态内存分配之后的任何剩余内存都将成为堆;这可以说是更好的,因为您不会得到一个不可用的内存池。您可以修改它并使用替代方案,但您需要知道自己在做什么

如果您使用的是Keil ARM-MDK,那么链接器选项--info=stack和--callgraph会将信息添加到映射文件中,以帮助进行堆栈需求分析。描述了这些技术和其他技术

如果您使用的是RTOS或多任务内核,则每个任务都有自己的堆栈。操作系统可能提供堆栈分析工具,Keil的RTX内核查看器显示当前堆栈使用情况,但不显示峰值堆栈使用情况(因此基本上没有用,它只适用于具有默认堆栈长度的任务)

如果必须自己实现堆栈检查工具,通常的方法是使用已知值填充堆栈,并从高位地址开始检查该值,直到找到第一个不是填充字节的值,这将给出堆栈的likley高潮标记。您可以实现执行此操作的代码,也可以从调试器手动填充内存,然后在调试器内存窗口中监视堆栈使用情况

堆要求将取决于代码的运行时行为;您必须自己分析,但是在ARM/keilrealview中,当C++的
new
抛出异常时,将调用MemManage异常处理程序;我不确定
malloc()
是否会这样做,或者只是返回NULL。您可以在异常处理程序中放置断点,或修改处理程序以发出错误消息,以在测试期间检测堆耗尽。还有一个函数可用于输出堆信息。它的界面有点笨重,我将其包装为:

void heapinfo()
{
typedef int (*__heapprt)(void *, char const *, ...);
    __heapstats( (__heapprt)std::fprintf, stdout ) ;
}

编译后的代码大小没有帮助,因为代码既不在堆栈中运行,也不在堆中运行。Cortex-M3设备通常在具有内置闪存和相对少量RAM的微控制器上实现。在此配置中,代码通常从闪存运行

堆用于动态内存分配。计算唯一对象的数量会给您一个粗略的估计,但您还必须考虑使用动态内存分配的任何其他元素(使用C++中的
new
关键字)。通常,在嵌入式系统中避免动态内存分配是因为堆大小难以管理


堆栈将用于异常处理例程期间的变量传递、局部变量和上下文保存。通常很难了解堆栈的使用情况,除非代码分配了一大块本地内存或一个大对象。一种可能有用的技术是为堆栈分配所有可用RAM。使用已知模式填充堆栈(0x00或0xff不是最佳选择,因为这些值经常出现),运行系统一段时间,然后检查堆栈以查看使用了多少。诚然,这不是一个非常精确和科学的方法,但在许多情况下仍然有用。

最新版本的IAR编译器有一个功能,可以根据对代码的静态分析(假设没有任何递归)确定所需的堆栈大小


如果你没有一个确切的数字,一般的方法是尽可能大,然后当你开始耗尽内存时,开始修剪堆栈,直到你的程序由于堆栈溢出而崩溃。我希望这是一个笑话,但这是通常的做法。

减少直到崩溃是一种快速的特别方式。您还可以使用已知值(例如0xCCCC)填充堆栈,然后通过扫描0xCCCC来监视堆栈的最大使用量。 这是不完美的,但比寻找崩溃要好得多


其基本原理是,减少堆栈大小并不能保证堆栈溢出会吞噬一些“可见”的东西。

这与特定CPU体系结构相比更特定于编译器和运行库。但最重要的是,是你的代码决定了内存的使用。使用MMU或数据断点来捕获堆栈溢出。可能重复的@Ben:Cortex-M3没有MMU,但它有数据访问硬件断点支持,这在测试期间可能会有所帮助,但在部署时可能不会有帮助。@Michael:考虑到Clifford答案中特定于工具链的组件,我不认为这在功能上是重复的。尽管如此,这仍然是一个有用的指针。事实上,这确实是确定大多数堆栈大小的方式,这确实让我们的行业感到尴尬!