对于硬件设计人员来说,编写代码来测试硬件是否正常工作或者在资源受限的情况下开发硬件和嵌入式软件通常是有意义的或者是必要的。嵌入式开发人员选择的语言仍然是C,尽管工具和结构化编程取得了进步,但还是会一次又一次地出现基本错误。为了避免这些C语言编程的陷阱,这里有9个给硬件工程师的C语言技巧。
提示1——不要使用“goto”语句
大约二十年前,当计算机编程还处于初级阶段时,程序流是由“goto”语句控制的。这些语句允许程序员中断当前代码行,直接进入不同的代码段。
编程语言最终开始结合函数的思想,这允许程序中断到一段代码,但不需要另一个goto语句,当完成时,函数返回到函数调用后的下一条指令。
提示 #2 – 使用 for(;;) 或 while(1)
如果 goto 不可用,一些硬件工程师可能想知道如何为程序创建无限循环。毕竟,这可能是通过创建返回到 main 顶部的 goto 语句来完成的。答案是利用 C 语言中已经内置的循环语句; for和while。
技巧3——对工作使用适当的条件语句
除了代码的可读性之外,程序执行时间在很大程度上取决于为做出决策而选择的条件结构的类型。许多嵌入式开发工程师熟悉简单if语句的用法;然而,有时工程师没有意识到,如果第一个条件不正确,可以使用else或else if语句。这可以节省处理器的时间,因为不必计算另一个条件语句。
if/else if/else语句可能并不总是合适的。如果有许多可能的条件需要检查,则使用switch语句可能更合适。这允许处理器评估语句,然后从一系列答案中选择下一步应该做什么,而不是不断评估一堆条件。
技巧4——避免使用汇编语言
微处理器的自然语言是汇编语言指令。用低级机器语言编写程序可以为处理器产生更有效的代码;然而,经验表明,编写汇编语言会导致误解。误解会导致不适当的维护或者更糟,结果是系统被错误覆盖。因此,一般的建议是避免使用汇编语言。事实的真相是,现在大多数编译器每天都在编译非常高效的代码。用像C/C++这样的高级语言开发会产生更有组织的结构,更容易理解和维护,其结果是总体上更好的代码。
也就是说,仍然有适合使用汇编语言的时候,但是这种时候很少。第一个推荐时间可能是在开发引导加载程序时。在这种情况下,嵌入式开发人员在启动过程中,可能需要优化决定启动应用程序或启动加载程序的速度。在这种情况下,分支决策的汇编代码可能是有意义的。另一个是在开发对DSP有严格时序要求的控制环路时。为了使器件的每个时钟周期有序,用汇编语言编写控制循环可能是有意义的。如果手头的任务适合使用汇编,确保它被很好地文档化,以便将来的开发者(或者你自己的将来版本)可以理解代码在做什么。
技巧5——利用模块化
当作者接手一个由硬件工程师开始的新项目时,最常见的经历之一就是糟糕的代码组织。在这些应用中,一切都是全局的,函数是稀疏的,goto语句支配着代码的组织。15年前,这是一种规范,但现在不是了!用C/编程使工程师们能够把他们的代码分解成独立的功能模块。这简化了代码的导航,但也开始允许工程师使用面向对象的技术,如封装。在有意义的地方,将代码组织成逻辑模块。这将需要更多的时间(几分钟!),但从长远来看,这将节省许多漫长的夜晚和调试的痛苦!
技巧6——使用描述性的变量名
编写易于理解和维护的优秀软件的障碍之一是变量的命名惯例。为了保持变量名的简洁性,嵌入式开发人员通常会创造出只有他们才能理解的简短、晦涩的助记符。现代语言允许在变量名中包含100个字符。为了把事情说清楚,就像俗话说的“直言不讳”而不是别的什么。这将使变量名不仅对开发人员显而易见,对未来的维护团队也是如此。
技巧7——少用#pragma语句
在C语言中,有一种特殊类型的语句叫做#pragma。这些语句通常处理非标准的语法和功能。应该尽可能避免使用它们,因为它们是非标准的,不能从一个处理器移植到下一个处理器。一些编译器可能需要它们来完成一些任务,比如定义一个中断服务例程。在这些情况下,可能没有办法使用#pragma。如果可能的话,将#pragma语句放在一个或几个模块中。这将有助于确保在移植代码时,只有几个地方可以更新代码,而不是分散在整个代码库中。这将有助于防止第一次编译移植代码时出现噩梦。
技巧8——错误并不总是像它们看起来的那样
调试C程序时要注意的一个问题是编译器错误。根据编译器的复杂程度,当检测到一个错误时,这个错误经常出现在程序中编译器没有指出的地方。其原因与编译器生成程序的步骤有关。错误的类型通常是相当一致的,所以工程师可以寻找几个错误,十有八九是错误。
注意丢失的#include文件。这可能会导致嵌入式开发人员看到一行非常好的代码,但是因为没有包含必要的头文件,编译器会将其标记为错误,这表明有些内容没有定义。
l 注意丢失的分号。写C代码最常见的错误之一就是忘记分号(;)在语句的末尾。
l 注意丢失的括号(})。括号是另一个常见的错误,要么是因为意外遗漏,要么是因为输入错误变成了不同的字符。
l 注意遗漏的逗号(,)。在复杂的定义中,很容易忘记逗号!
一般来说,当一个奇怪的编译器错误出现时,看看在那一行之前编译了什么。很可能这就是错误所在!它可能是一行,半页或者在一个完全不同的文件中。但是不要放弃!有了一些经验,找到困难的最终成为第二天性。
技巧9——优秀的程序员不一定写更少的代码行
一个普遍的误解是,一个好的程序员比一个普通的程序员能写更少的代码行来做一些事情。不要被这个想法所迷惑!一个好的程序员有一个经过深思熟虑和结构化的代码库,变量被很好地命名和封装,系统中很少有全局变量,函数应该简短明了。如果代码看起来很混乱,写多行代码会更清楚,那么就写吧!在嵌入式开发中,一个好的程序员写干净的代码,容易理解和维护,而不是最少的代码行!