嵌入式写好一行代码,真不简单
内容提要
嵌入式编程的步骤包括从PC机器编程的视角看待嵌入式问题、学习嵌入式编程思想和将PC机器思想与嵌入式思想结合应用于实际项目。中国的嵌入式编程人员要么理论薄弱但实践经验丰富,要么理论扎实但实践经验相对较少。嵌入式系统中的代码需要对各个环节有清楚的了解。
延伸解读
中断频繁开关的隐藏代价
文中串口驱动例子显示,在循环中反复调用关中断、开中断的函数,虽然保护了全局变量,却可能因关中断时间过长而错过高速UART中断。3Mbps下每字节仅3.3微秒,100MHz ARM约执行150条指令,而关中断和中断服务本身消耗指令较多,导致数据丢失。这提醒开发者,临界区应尽量短,或在高频中断场景下调整查询节奏。
硬件时序不能只靠“看起来对”
14094串转并芯片要求时钟高低电平各持续10纳秒,同事的代码只延时了高电平,低电平没有保证,导致时好时坏。这说明嵌入式代码必须对照器件手册的时序参数,不能仅凭逻辑正确就认为可行。尤其当IO模拟时序时,需同时考虑高、低电平持续时间,并防范中断插入带来的不确定性。
可移植延时需对抗编译器优化
文中指出,用空循环实现延时可能被编译器优化掉,导致时序要求无法满足。真正可移植的做法是像Linux那样,上电时测量nop指令执行时间,再结合防止优化的编译指令(如GCC的volatile asm("nop;"))实现纳秒级延时。这要求开发者理解工具链行为,而不仅是写出功能正确的代码。
理论与实践脱节的双重困境
文章提到,国内嵌入式工程师常分为两类:实践经验丰富但理论薄弱,或理论扎实但电路等实践知识欠缺。前者可能凭经验写出看似合理却忽略中断响应的代码,后者可能不熟悉硬件时序细节。两个案例都表明,嵌入式开发需要同时理解软件逻辑、RTOS内核行为与硬件电气要求,缺一不可。
Q&A
嵌入式编程从PC编程过渡需要哪几个步骤?
分为三步:第一步是从PC机器编程的视角去看待嵌入式问题;第二步是学会嵌入式编程思想;第三步是将PC机器的思想和嵌入式思想结合起来,应用于实际项目当中。
中国嵌入式工程师通常有哪些背景特点?
很多嵌入式工程师来自自动控制、电子等相关专业,实践经验丰富但理论知识可能缺乏;计算机专业毕业生理论扎实但电路知识相对欠缺,且对嵌入式行业兴趣不高。总体而言,要么理论薄弱但实践丰富,要么理论扎实但实践较少,两者兼备的很少。
为什么在嵌入式系统中频繁关闭和打开中断会导致数据丢失?
频繁关闭和打开中断会占用CPU时间,导致CPU可能无法及时响应UART中断。例如在3Mbps波特率下,传输一个字节仅需3.3us,而关闭和打开中断的指令以及中断服务程序需要较多指令周期,可能错过中断,造成数据丢失。
如何修改代码以避免因频繁关中断导致串口通信不稳定?
可以在循环中加入延时,例如DelayUs(20),让CPU有时间执行中断代码,避免频繁关闭中断造成中断响应不及时,从而防止数据丢失。
在模拟串行通信时,为什么需要同时保证高电平和低电平的持续时间?
因为像14094这样的芯片要求clock的高电平和低电平都持续一定时间(如10ns)。如果只延时高电平而忽略低电平,当CPU没有中断插入时,低电平持续时间不足,导致芯片工作不正常。
如何编写可移植的延时循环以避免编译器优化?
可以使用纳秒级延时函数如DelayNs(10),并利用编译器防止优化的指令或关键字,例如GCC中的volatile asm(“nop;”),确保延时循环不被优化掉,保证时间精度。