我也可以推荐这本书嵌入式C作者:迈克尔·J·庞特和嵌入式系统编程作者:迈克尔·巴尔。
在我作为嵌入式开发人员 14 年的经验中,我了解到“实践”通常不适用于嵌入式系统。当书上说使用这种或那种模式时,如果您有无限的内存和 CPU 能力,那就是真的。
去年,当我为一家大公司设计新的固件平台时,我不得不打破几乎所有设计规则。您需要问自己,一个众所周知且被接受的解决方案是否最适合您的项目,但会牺牲代码大小或速度?要记住的事情。
本地还是全球?
声明变量之前请三思。局部变量是在运行时在堆栈上创建的,而全局变量是在系统启动时创建的。
const存储在flash中,占用空间并且与索引数组具有相同的访问时间。如果不需要用指针引用它们,最好使用类型转换定义:
#define kState_Idle (unsigned char)4
这将在汇编代码中的 4 中进行编译,而不是将其作为只读变量从闪存中获取。
不要使用 double 或 float,它们非常慢。请改用整数数学。不惜一切代价避免使用数学库:)
在循环内访问的局部变量(例如 for、while 等)会减慢速度,将它们声明为寄存器变量以提高速度。
使用节来放置代码
C/C++ 框架将所有变量(包括常量)复制到 RAM。如果是只读变量会浪费很大的空间。字符串也属于这一类,例如“Hello world”。
对于 C++ 来说,模板是非常重要的,RTTI 和异常也是如此。躲开它!!
重载和变形将使您通过良好的规划真正走得更远,您的代码将紧凑而快速。
图书馆
根据微控制器的大小,您可能会避免包含任何 STL。我们制作了自己的 get()、put()、printf() 等版本,以减少代码大小。
使用硬件
不要忘记研究您的微控制器/CPU,以 100% 充分利用硬件。例如,不要使用 memset 或 memcpy 填充内存,而是使用 DMA(如果有)。
还要研究装配。控制器通常有专门的指令,需要几行 C/C++ 代码才能完成。您可以用汇编语言编写自己的 C 函数,将它们连接到您的 C/C++ 代码中。很好的例子是位设置/清除指令或块操作指令。
检查控制器正在使用的数据大小。例如,如果它是 16 位系统,则即使您声明了 char,它也可能始终读取 16 位。在这种情况下,读取 char 比读取 Short 需要更长的时间,因为它必须进行额外的屏蔽。
Memory
请记住,内部 RAM 比外部 RAM 快得多。您可以将变量甚至代码放入内部 RAM 中以加快速度。
闪存通常比 RAM 慢,尤其是写入。然而,放置经常访问的只读变量通常不会造成任何影响。编译器通常会检测经常使用的变量并分配一个内部寄存器。
testing
通常不可能在不影响性能的情况下足够快地将调试信息发送到主机系统。在这些情况下,创建一个内部调试缓冲区来存储您的信息并在事后对其进行分析。
通过切换硬件引脚来测量执行时间,它需要一条汇编指令,并且对执行速度几乎没有影响。使用逻辑分析仪或示波器监视引脚。我们在常用函数中寻找 ns 以提高整体性能。
自动生成的代码文档也是查找“奇怪”设计或解决方案的好方法。我们使用 Doxygen 和 Graphviz 来生成类图和关系。在这里我们得到了一个很好的概述,并且可以很容易地发现“过时的”类或未更新的子系统(我们使用了敏捷开发方法)
嗯..我可以永远继续下去,写一本关于这个的书:)
我们使用 C++ 中的上述建议,在 20k RAM(RTOS、变量、通信缓冲区和堆)和 64k Flash(引导块、应用程序代码和 2 个闪存盘)上制作了一台打印机,打印速度为 150mm/s。
祝你好运!