物联网创客指南:MCU设计的最佳实践和除错技巧
堆栈是从"内存顶部"或物理RAM中最高可用地址开始的内存区域,然后向下计数,直到达到堆栈限制。如果您定义了太多的局部变量,或者您的代码通过使用递归或其他嵌套函数动态创建这些变量,那么您的堆栈空间会被占满。
全局变量是在模块级别的所有函数和其他代码块之外定义的变量。编译器自动为heap上的全局声明的变量分配内存,这是堆栈外的主内存池的一部分,如果您尝试分配太多的RAM,将会产生编译器错误。但是,在代码中使用malloc()命令可以动态地在运行时在堆中分配RAM。
在具有有限RAM的嵌入式处理器上使用recursion或malloc()命令是一个冒险的任务!你必须理解你的代码将需要多少递归尝试(或malloc()调用)以便解决问题,然后设计一个永远不会用尽堆栈空间的解决方案。
如果您在代码中定义所有变量并让编译器确定如何自动管理内存,您将遇到较少的超出堆栈或堆的问题。即使有这样的预防措施,如果你的代码几乎是可用的RAM大小,当你编译和构建你的代码,你将需要学习如何监视堆栈和堆的大小,这部分内容超出本节的范畴。
7)全局静态变量和局部静态变量的差异
使用关键字"static"定义的变量表示不同范围的不同内容。在内部函数中,static关键字用在变量的前面,以记住它在函数调用之间的值。它具有一种"粘性",你可以在函数的第一次调用时初始化它,然后让它保持其值,而不是每次函数执行时重新初始化非静态变量。在全局范围,所有变量都是"粘性"的,因为它们只在运行时开始时初始化一次,然后记住它们的值。但是,放置在全局变量前面的static关键字指示编译器该变量对于该模块是本地的,并且不被外部模块使用。对于同一个"static"关键字,这是一个完全不同的含义。
8)volatile和extern的含义及如何相互影响
只要变量和函数在模块中未声明为static,它们就可以在该模块外部使用,并在其他模块中使用。为了告诉编译器你打算在模块中使用相同的变量,你在一个模块中定义一个常规方法的变量,并在设计中所有其他模块的定义之前添加关键字"extern"。现在,您设计中的所有模块都可以访问同一个变量。但是,如果设计中的其他模块中的一个模块意图修改最初定义的位置之外的变量的值,则必须在该变量前面添加关键字"volatile"。这个volatile关键字告诉编译器该变量可以在模块之外更改,并阻止优化器删除似乎没有效果的语句。
此外,当使用Release版本和Debug版本时,使用volatile非常重要。当优化设置增加时,编译器将主动尝试压缩不必要的代码。这意味着您需要防止编译器这样做,通过使用volatile关键字可以改变当前范围之外的任何变量。
- Silicon Labs展示高级计量无线解决方案(02-24)
- 物联网的最大挑战,在于“最后一寸”元件端(09-07)
- 主流ZigBee芯片大盘点(3):Silicon labs EM35x(07-25)
- 单片机选型有诀窍:根据数值选择低功耗MCU(04-24)
- 简化嵌入式设计的无线连接解决方案(05-09)
- Silicon Labs 32 位微控制器的 10 大技术特点(02-10)