当前位置: 华文星空 > 知识

C语言开发单片机为什么大多数都采用全局变量的形式?

2020-05-23知识

作为一个和MCU,SOC芯片相伴多年的老程序猿,也来分享一下答主个人对全局变量这个问题的看法。 总的来说,对于大多数程序员来说全局变量可谓是又爱又恨 不用吧 ,很多场合下使用全局变量的确能够节省很多编码力气,毕竟可以减少函数间的参数及数据传递; 用吧 ,很多时候对于多任务或者说多线程场景,必须考虑互斥问题。对于Ram资源寸土寸金的MCU来说,更是需要小心谨慎。比如定义太大的全局变量,可能有时候就是放不到Ram资源中。

网图,侵删

嵌入式开发过程中,也曾经遇到过两个与全局变量有过交集的故事,现在回头想想也是很有思考的价值和意义。写在这里和大家一起分享分享。

第一个故事:老代码中过多的全局变量,导致维护起来非常麻烦 。答主刚入职的时候,从事的是嵌入式软件平台的代码维护工作,可以说 前人留下的很多代码绝对配得上「屎山」的名声 。其中一条就是,各种全局变量满天飞。先不说各种spinlock,rwlock的保护解保护,单说用SI列举出来的索引点,看着满屏的extern真的让人头大。每次但凡要修改一点代码,就要全项目到处查找这个全局变量还漏下了哪里没修改到。好在后期项目组开展了代码优化工作,答主直接憋着一口气把这些陈年污垢都给清除掉了。

第二个故事:超级大的全局变量,导致代码编译失败 。记得和别人一起做嵌入式消费产品的时候,有个软件开发的同事,特别喜欢用全局变量定义各种功能。但是他真的忽略了stm32那瘦弱的小身板真的放不下他的 巨大无比的结构体数组 。在stm32上,弄个结构体全局变量就够够了。还要弄个数组,相当令人发指!编译不通过,就修改堆和栈的大小,好不容易编译通过了。结果一运行的时候,多任务跑起来后各种不正常。耗费了好久发现,堆栈太小了,任务的变量发生了踩踏!!!

讲了这么多,并不是想妖魔化全局变量。 全局变量用好了,是个非常好的伙伴,但是用的不好,那绝对是史诗级别的灾难 。在答主的个人编码经验里, 对于全局变量主要遵循三点

  1. 能不用尽量不用,尤其对于多线程多任务的场景下。使用任务通信机制进行数据传递+局部变量存储,基本可以满足开发需要。
  2. 如果必须使用,那么一定要限定起作用的模块。不要随便一个新加入的模块,一个extern就将全局变量透漏出去,以后维护起来又要被人骂屎山。
  3. 如果一个模块中的全局变量超过了3个,那么把他们放到一个结构体中。引用的时候一个extern足矣,不要一堆一堆的extern看着眼睛疼。

回到题主最后的问题: 很多时候使用全局变量并不一定是性能的问题,更多是的是程序猿想方便快捷的实现多模块下数据共享的问题 。至于提到的各种开发板或者demo程序使用全局变量过多的问题, 从答主的角度来看,这些代码仅仅作为示意使用,也就是说怎么方便怎么来,让大家看懂怎么用就行 。而在真正的嵌入式产品,至少在答主经历和参与开发的各类嵌入式产品中,没有像这么大肆使用全局变量的情况。

以上,仅代表个人观点,仅供题主参考。