全局变量在嵌入式系统编程(C)中是否令人不悦?

时间:2018-02-04 13:44:00

标签: variables static coding-style embedded conventions

我多年前就已经了解到,在应用领域,全球变量是一个“不好的”。或者"对#34;不满意,所以习惯于避免使用它们并且几乎不使用它们。

在嵌入式世界中,它们似乎在处理硬件中断时几乎是不可避免的。它们也必须是易失性的,这样如果编译器看到它们在正在运行的程序中从未被触及,它们就不会优化它们。

这两个陈述都是真的吗?有没有办法在我描述的情况下避免这些变量而不会向后弯曲太远?

1 个答案:

答案 0 :(得分:1)

  

似乎在嵌入式世界中,当   它涉及到硬件中断。他们也必须   使其变得易失,以便编译器不会对其进行优化   看到它们永远不会在正在运行的程序中被触碰。

     

这两个陈述都正确吗?有办法避免那些   在我描述的情况下变量没有向后弯曲得太远?

这些陈述都不正确。

首先,让我们澄清一下,全局变量是指具有外部链接的文件范围变量。这些是可以用extern关键字调用的变量,也可以是错误地调用的变量。

关于第一句话:

  

似乎在嵌入式世界中,当   涉及到硬件中断。

使用硬件中断时,可以避免使用全局变量。正如其他人在评论中指出的那样,嵌入式环境中的全局变量并不少见,但也不鼓励使用它们,尤其是在您有能力实施适当的封装的情况下。 This article(有人在您的问题的注释中提供)实际上包含一个读者答复,该答复提供了一个很好的示例,说明不可能正确实现封装(您不必走得太远,这是第一个示例) )。

关于第二个陈述:

  

还必须使它们可变,以便编译器不会优化它们,如果它   看到它们永远不会在正在运行的程序中被触碰。

这个说法,让我们说“几乎是真的”。编译器知道何时需要访问变量的内存位置(从内存写入数据或从内存读取数据),因此,当打开优化功能时,它将避免不必要的内存访问。 volatile关键字告诉编译器不要这样做,这意味着每次使用该变量时都会访问该内存位置。

在需要使用volatile关键字的情况下

  • 全局变量已更新中断
  • 在多线程应用程序中由多个线程访问的全局变量
  • 映射内存的外设寄存器

对于被中断更新的全局变量,volatile关键字势在必行,因为中断可以随时发生,我们不想错过该更新。 对于不会被中断更新并且应用程序是单线程的全局变量,volatile关键字是完全不必要的,并且实际上会减慢代码速度,因为您每次都将访问该变量的内存位置!

  

在我描述的情况下,有没有一种方法可以避免那些变量而不会向后弯曲太多?

答案确实取决于。可能最重要的是,从此设计更改中您将获得什么收益?另外,这是一个专业的项目,是一个学校项目,还是一个娱乐项目?

根据我作为工程师的经验,上市时间通常是公司开发新产品时最担心的事情。通常会有一些遗留的代码在研究和开发阶段就被开发人员所使用,并且“行之有效”,那么为什么要花时间来修复未损坏的东西呢?认真地说,最好是一个很有说服力的论点,否则不要浪费您的时间。

根据我的教育经验,花时间回去实施适当的设计理念并进行文档记录绝对是值得的,但前提是您确实有时间这样做!如果您临近最后期限,请不要冒险。如果您领先于游戏,那就去做吧。这将是不止一种的方式。

最后,要正确封装硬件中断的中断服务程序(ISR),您需要将其放置在实际的设备驱动程序(CAN,UART,SPI等)中。仅应通过设备驱动程序和设备驱动程序来促进与ISR的所有通信。 ISR和设备驱动程序之间共享的变量应声明为staticvolatile。如果需要从外部访问这些变量中的任何一个,则可以在驱动程序的公共API中创建设置程序和获取程序。 Check this answer out for a general guideline to follow.