C Global在ISR中宣布

时间:2015-06-11 21:11:16

标签: c arm embedded cortex-m codewarrior

我正在为其ARM系列微控制器评估飞思卡尔的Kinetis Design Studio。我正在寻找一个example作为我的第一个“闪烁LED”项目的基础。当使用我的主程序和ISR(如计数器)之间共享的变量时,我通常会在main.c中定义一个volatile全局,并在ISR中将其引用为extern。他们的例子显示完全相反,他们也不使用volatile关键字。我从来没有见过这样做过。这有优势吗?顺便说一句,我的程序无论哪种方式都可以正常工作。

2 个答案:

答案 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),但使用它!