C 全局在 ISR 中声明

C Global declared in ISR

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

我不知道codewarrior套件。但是,一般来说,volatile 告诉编译器变量在程序代码给出的正常控制流之外发生了变化。

从历史上看,嵌入式编译器对不使用 'volatile' and/or 相当宽容,实施了一些策略来支持不了解优化和 "forgot" volatile 的缺乏经验的程序员。然而,这将导致代码优化不佳,特别是对于 ARM 平台(对于 HC08&Co MCU 来说问题不大,无论如何都必须从内存中加载每个变量)。

虽然 CW 可能仍然那么宽容,但像 gcc 这样高度优化代码的编译器并不那么宽容并且优化得更加激进。例如,如果您忘记了 volatile 或此类编译器的障碍,您最终可能会得到一个空的主循环。

即使如果您的代码目前运行良好,一旦启用优化或更改次要(可能不相关)方面,这可能会改变。

一位长期嵌入式开发人员的忠告非常好:使用 volatile。稀疏地使用它并经过深思熟虑(可以找到更多详细信息),但要使用它!

缺少 volatile 是一个错误(albeit a common one) that itself should be a quality warning. The choice of where to instantiate a global is arbitrary, but from a cohesion point of view, it makes sense to keep data that relates to the interrupt with the interrupt. That said, the use of the 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() ;

    ...