嵌入式系统/嵌入式系统基础
嵌入式系统编程不同于普通的PC编程。在许多方面,嵌入式系统的编程就像25年前的PC编程。系统的硬件通常选择最便宜的,以尽可能降低设备成本。为了使编程更容易,每个单元多花一美元,可能会导致数百万美元的损失。相比之下,雇佣一名程序员额外工作一个月很便宜。这意味着程序员必须使用速度慢的处理器和低内存,同时还要应对大多数PC应用程序中不存在的效率需求。以下是嵌入式领域特有的问题列表。
嵌入式开发只占总编程的一小部分。与PC世界不同,嵌入式架构数量众多,PC世界只有1个指令集,而Unix世界只有3或4个主要指令集。这意味着工具更昂贵。这也意味着它们的功能更少,开发程度更低。在一个大型的嵌入式项目中,你几乎总能在某个地方找到某种编译器错误。
调试工具是另一个问题。由于你不能总是在嵌入式处理器上运行通用程序,因此你也不能总是在它上面运行调试器。这使得修复程序变得困难。JTAG端口等特殊硬件可以部分解决这个问题。但是,如果你在系统控制真实世界硬件(如电机)时停止在断点处,则可能导致设备永久损坏。因此,从事嵌入式编程的人员很快就会成为使用串行IO通道和错误消息样式调试的大师。
为了节省成本,嵌入式系统经常使用最便宜的处理器来完成任务。这意味着你的程序需要尽可能高效地编写。在处理大型数据集时,内存缓存未命中等在PC编程中无关紧要的问题可能会对你造成伤害。幸运的是,这种情况不会经常发生 - 使用合理高效的算法来开始,只有在必要时才进行优化。当然,由于与调试器无法正常工作的原因相同,普通的分析器也不能很好地工作。因此,需要更多的直觉和对软件和硬件架构的理解才能有效地优化。
内存也是一个问题。出于相同的成本节约原因,嵌入式系统通常使用它们能使用的最小内存。这意味着它们的算法必须对内存效率(与PC程序不同,你会经常为了内存而牺牲处理时间,而不是相反)。这也意味着你不能承受内存泄漏。嵌入式应用程序通常使用确定性内存技术,并避免默认的 "new" 和 "malloc" 函数,以便更容易地查找和消除泄漏。
程序员期望的其他资源可能根本不存在。例如,大多数嵌入式处理器没有硬件FPU(浮点运算单元)。这些资源要么需要在软件中模拟,要么完全避免。
嵌入式系统经常控制硬件,必须能够实时响应它们。无法做到这一点可能会导致测量误差,甚至损坏硬件(如电机)。资源的缺乏使得这个问题更加困难。几乎所有的嵌入式系统都需要能够优先处理某些任务,并且能够为了高优先级任务(如硬件控制)而推迟/跳过低优先级任务(如用户界面)。
许多嵌入式项目在其程序员中强制执行禁止使用浮点的规则。
定点算术和其他替代方法通常比浮点算术更好。
我们将讨论这些优势,并在后面的章节中详细介绍定点和浮点数。