我正在为其ARM系列微控制器评估飞思卡尔的Kinetis Design Studio。我正在寻找一个example作为我的第一个“闪烁LED”项目的基础。当使用我的主程序和ISR(如计数器)之间共享的变量时,我通常会在main.c中定义一个volatile全局,并在ISR中将其引用为extern。他们的例子显示完全相反,他们也不使用volatile关键字。我从来没有见过这样做过。这有优势吗?顺便说一句,我的程序无论哪种方式都可以正常工作。
答案 0 :(得分:4)
缺少的volatile
是一个错误(albeit a common one),它本身应该是质量警告。选择实例化全局的选择是任意的,但从内聚的角度来看,保持与中断相关的数据与中断是有意义的。也就是说,使用global data本身就是可疑质量和实践的标志。
使用数据封装的更好模式是:
interrupt.c
...
volatile static int counter = 0 ;
void interruptHandler()
{
counter++ ;
}
int interruptCounter{ return counter } ;
interrupt.h
...
extern int interruptCounter() ;
...
main.c中
#include "interrupt.h"
...
int icount = interruptCount() ;
...
答案 1 :(得分:1)
我不知道codewarrior套件。但是,通常,volatile
告诉编译器变量在程序代码给出的正常控制流之外被更改。
从历史上看,嵌入式编译器非常宽容不使用'volatile'和/或实现一些策略来支持那些不了解优化并且“忘记”volatile
的经验不足的程序员。然而,这将导致代码严重优化,特别是对于ARM平台而言(HC08& Co MCU的问题不大,无论如何都必须从内存加载每个变量)。
尽管可能CW仍然是宽容的,但是像gcc这样高度优化代码的编译器并不是那么宽容和优化得更加激进。如果您忘记volatile
或此类编译器的障碍,例如,最终可能会出现一个空的主循环。
即使如果您的代码现在运行良好,一旦启用优化或更改次要(可能不相关)方面,这可能会更改。
非常好意味着来自长期嵌入式开发人员的建议:使用volatile
。稀疏地使用它并深思熟虑(可以找到更多细节here),但使用它!