☰
嵌入式开发入行指南:先混进去再学,实际门槛比想象低
2026/9/30 1:09:12 网站建设 项目流程

嵌入式开发这个行当,外面的人看着觉得门槛高得吓人,里面的人心里都清楚,真正干活用的东西跟学校里教的那套、跟招聘启事上写的那堆要求,中间隔着一道巨大的鸿沟。我见过太多人,简历上写着精通C语言、熟悉数据结构、了解操作系统原理,结果连个串口收发都调不通,连个GPIO的高低电平都测不明白。也见过不少人,压根没正经学过嵌入式,就是硬着头皮投了简历,面试的时候连蒙带猜,进去之后边干边学,半年下来反而成了团队里最靠谱的那个。这个标题说的“先混进去再说”,不是教你弄虚作假,而是说这个行业的实际门槛远比表面看起来低,真正卡住大多数人的不是技术本身,而是那道心理上的坎。

我自己就是半路出家。当年从别的方向转过来,面试官问的问题我有一半答不上来,但我会的东西恰好是他们项目里马上要用的,就这么进去了。进去之后才发现,组里五个人,真正科班出身的就一个,其他人都是各种野路子转过来的。有从硬件转的,有从PC端开发转的,甚至还有从测试转的。大家共同的特点就是:遇到问题能查、能试、能熬,而不是一开始就什么都会。所以这篇东西,我想把“混进去”这件事拆开揉碎了讲清楚——到底什么叫混,怎么混,混进去之后怎么活下来,以及那些招聘要求里没写但实际工作中天天在用的东西到底是什么。

1. 招聘要求上的嵌入式跟实际干活用的嵌入式,差了多少

1.1 招聘启事里的“精通”到底值几个钱

你随便打开一个招聘网站,搜嵌入式开发,看到的岗位要求基本是这么个套路:精通C/C++,熟悉ARM体系结构,掌握Linux内核驱动开发,了解RTOS原理,有通信协议开发经验,熟悉硬件原理图阅读,具备独立解决问题的能力。这一串看下来,感觉没个三五年功底根本不敢投。但实际情况是,大部分嵌入式岗位的日常工作,跟上面这些“精通”“掌握”“熟悉”之间,重合度可能连百分之三十都不到。

我待过的第一个做嵌入式产品的团队,主要工作内容是维护一个基于Cortex-M3的控制器固件。每天干的事情是什么?改改状态机逻辑,调调串口协议解析,看看ADC采样值对不对,偶尔用示波器抓个波形确认时序。什么Linux内核驱动、什么ARM体系结构,根本用不上。用的芯片是STM32F103,开发环境是Keil,调试工具是J-Link,就这些。招聘的时候写“熟悉ARM体系结构”,实际意思是你知道Cortex-M3是ARMv7-M架构、知道它的中断向量表怎么放、知道NVIC怎么配置,就够了。不需要你去研究流水线怎么排、分支预测怎么做。

这不是个例。我后来跟做应用层开发的朋友聊,他们那边用Qt做界面,跑在Linux上,招聘要求写“精通C++、熟悉Qt框架、了解嵌入式Linux系统”,实际工作就是拖控件、连信号槽、调调样式表。真正涉及系统底层的东西,有专门的BSP团队在搞,应用层的人根本碰不到。所以你看,招聘要求是把整个嵌入式链条上所有岗位的技能点堆在一起写出来的,你不需要全都会,你只需要会其中一小块,就能进去。

1.2 面试官真正在筛的是什么

既然技术要求没那么高,那面试到底在面什么?我后来自己也当过面试官,回过头看,筛人的核心标准其实就三条:第一,你能不能把一个问题说清楚,哪怕这个问题你没做过;第二,你遇到不会的东西,第一反应是查还是懵;第三,你之前做过的东西,跟我们现在要做的有没有一点关联。

第一条特别重要。很多人技术底子不错,但表达一塌糊涂。问他做过什么项目,他说“就做了一个温湿度采集”,然后没了。你再问用的什么传感器、什么接口、数据怎么处理的、遇到什么问题,他答得磕磕巴巴。这种人面试官不敢要,因为嵌入式开发大量时间是在跟别人沟通——跟硬件工程师确认引脚定义,跟测试确认复现步骤,跟产品确认需求边界。你连自己做过的项目都讲不清楚,怎么指望你跟别人协作。

第二条是潜力判断。嵌入式这个领域,芯片型号成千上万,外设五花八门,你不可能什么都做过。面试官问一个你没接触过的模块,比如“你用过CAN总线吗”,你没用过很正常。但如果你能说“我没用过CAN,但我用过SPI和I2C,我知道它们都是串行通信,CAN应该是差分信号、多主架构,具体寄存器配置我得查手册”,这就加分了。面试官要的就是这个态度——知道怎么从已知推未知,知道去哪里找答案。

第三条是匹配度。有时候你技术一般,但之前做的项目跟岗位需求高度重合,那你就比技术更好但不匹配的人有优势。比如岗位是做电机控制的,你之前正好做过PWM调速,哪怕你其他方面弱一点,面试官也愿意要你,因为你能快速上手。

1.3 那些“不会但可以学”的东西,其实占了大头

我统计过自己从入行到现在用过的技能,真正在面试前就已经掌握的,可能只有百分之二十。剩下的百分之八十,都是进去之后现学的。举几个具体的例子。

RTOS。我第一份工作用的是FreeRTOS,之前完全没接触过。进去第一周,老大扔给我一本FreeRTOS的官方手册,说“把这几个API看一下,任务创建、信号量、队列,然后把这个采集任务改成用RTOS调度”。我就硬着头皮看,看完照着例子改,改完跑起来发现任务切换有问题,再回去查优先级配置,折腾了两天搞定了。现在你问我FreeRTOS,我能讲得很清楚,但当时就是边做边学。

通信协议。Modbus、CANopen、自定义串口协议,这些我都是工作中用到了才去了解的。Modbus还好,协议简单,网上资料多。CANopen就复杂一些,对象字典、PDO、SDO这些概念,我是对着CiA 301文档啃了好几天才搞明白的。但这些东西,你让我面试前自学,我肯定学不进去,因为没有实际场景,学了也记不住。

硬件调试。看原理图、用示波器、焊板子、飞线,这些技能学校里教得很少,但工作中天天用。我第一次用示波器抓I2C波形的时候,连触发怎么设都不知道,还是硬件工程师手把手教的。后来自己调多了,慢慢就熟了。现在给我一个板子,我至少能判断出供电正不正常、晶振起没起振、复位信号对不对。

这些东西,招聘要求上可能就一句话带过,但实际工作中占用的时间最多。而它们恰恰是最容易“混”进去之后再学的,因为脱离了具体项目,你学起来既没动力也没方向。

2. “混进去”之前,你至少得把这几样东西攥在手里

2.1 C语言不用学到精通,但指针和内存必须门儿清

嵌入式开发主要用C语言,这个大家都知道。但“会C语言”和“能做嵌入式”之间,差的是对指针和内存的理解。你不需要把C标准委员会的文件都读一遍,但下面这些东西必须清楚。

指针的本质是什么?它就是一个存地址的变量。嵌入式里面到处都是指针,因为你要直接操作寄存器。比如你想让GPIOA的第5个引脚输出高电平,你得这么写:

*(volatile uint32_t *)0x40020014 |= (1 << 5);

这一行代码里面,0x40020014是GPIOA输出数据寄存器的地址,(volatile uint32_t *)把这个地址强制转换成指向32位无符号整数的指针,前面的*是取这个地址的内容,|=是置位操作。如果你不理解指针和地址的关系,这行代码你看着就是天书。

内存方面,你得知道栈和堆的区别,知道全局变量和局部变量存在哪里,知道什么是内存对齐。嵌入式系统资源有限,栈空间可能只有几KB,你如果在中断服务函数里定义一个大的局部数组,栈直接溢出,程序跑飞。这种问题我遇到过不止一次,现象是程序莫名其妙进HardFault,查半天才发现是栈不够用。

还有volatile关键字。很多初学者不知道它是干嘛的,觉得加不加无所谓。但在嵌入式里,访问硬件寄存器必须加volatile,否则编译器优化的时候可能把你的读写操作优化掉。比如你写一个延时循环:

for(int i = 0; i < 1000; i++);

如果i没加volatile,编译器可能直接把这个循环删了,因为觉得你没用它。加上volatile之后,编译器就知道这个变量可能被外部改变,不能优化。

2.2 能看懂原理图,比会画PCB重要得多

嵌入式软件工程师不需要会画板子,但必须能看懂原理图。因为你要根据原理图确定引脚怎么配置、外设怎么连接、通信接口用哪个。看不懂原理图,你就不知道你的代码该操作哪个寄存器。

看原理图其实不难,核心就是搞清楚几件事:芯片的供电引脚接在哪里、晶振接在哪个引脚、复位电路怎么设计的、你要用的外设(比如LED、按键、传感器)接在哪个GPIO上、通信接口(UART、I2C、SPI)的引脚是怎么分配的。

我刚开始看原理图的时候,最头疼的是网络标号。一张图上密密麻麻的标号,不知道哪个连哪个。后来学会了用PDF阅读器的搜索功能,搜一个标号,所有出现的地方都高亮出来,顺着看就能理清连接关系。还有一个技巧是看芯片的数据手册,里面有个引脚定义表,对照着原理图看,很快就知道每个引脚是干嘛的。

提示:看原理图的时候,先找芯片的电源和地,确认供电正常;再找晶振和复位,确认系统能跑起来;最后找你关心的外设。这个顺序能帮你快速定位问题。

2.3 会用万用表和示波器,调试效率翻倍

万用表和示波器是嵌入式调试的两把利器。万用表主要用来测通断、测电压。比如你怀疑某个引脚没输出,拿万用表一量,电压不对,那就说明要么配置错了,要么硬件有问题。示波器主要用来看波形,比如UART的TX线有没有数据出来、I2C的时钟和数据线时序对不对、PWM的占空比是不是你设的值。

我第一次用示波器的时候,连探头怎么校准都不知道。后来硬件同事教我,先把探头接到示波器自带的方波输出上,调补偿电容,让方波看起来是平的,这才算校准好。然后测信号的时候,触发模式选边沿触发,触发电平调到信号幅度的中间,这样波形才能稳定显示。

还有一个坑是地线。示波器的探头有信号夹和地夹,地夹必须接到被测电路的地上,否则测出来的波形全是噪声。我见过有人只夹信号不接地,然后抱怨波形不对,折腾半天才发现是地没接。

2.4 至少玩过一款主流芯片的开发板

面试的时候,你说你学过嵌入式,面试官肯定会问你用过什么芯片。如果你说“我学过51单片机”,那基本就凉了,因为现在工业界很少用51了。你至少得玩过一款主流的ARM Cortex-M芯片,比如STM32。

STM32的好处是资料多、社区活跃、工具链成熟。你买个最小系统板,照着教程把GPIO、UART、定时器、ADC、I2C、SPI这些外设都跑一遍,基本上就对嵌入式开发有个概念了。跑一遍的意思不是把例程下载进去看现象,而是自己写代码,配置寄存器,处理中断,解决问题。

比如点灯,你不要用库函数,直接操作寄存器试试。先使能GPIO时钟,再配置引脚为推挽输出,然后写ODR寄存器控制高低电平。这一套下来,你对时钟树、寄存器操作、位操作的理解会深刻很多。之后再学库函数或者HAL库,就知道它们底层在干什么。

如果你时间充裕,还可以玩玩RTOS。在STM32上跑个FreeRTOS,创建两个任务,一个闪灯一个串口打印,看看任务调度是怎么回事。这个经历写在简历上,比“熟悉C语言”有说服力得多。

3. 简历和面试里的“混”,是有技术含量的

3.1 简历怎么写才不像培训班出来的

培训班出来的简历有个特点:项目经历写得特别全,什么智能家居、物联网网关、四轴飞行器,每个项目都用了十几种技术,但一问细节就露馅。面试官看多了这种简历,一眼就能认出来。所以你的简历要反着来——项目不用多,一两个就行,但每个项目都要能讲出细节。

什么叫细节?比如你写“基于STM32的温湿度采集系统”,这太笼统了。你可以写“用STM32F103的ADC采集热敏电阻分压,通过查表法转换成温度值,用UART以自定义协议每秒钟上报一次数据,协议包含帧头、长度、数据、校验和”。这样写,面试官就知道你真的做过,因为查表法、自定义协议、校验和这些细节,没做过的人是编不出来的。

还有,简历上不要写“精通”,写“熟悉”或者“了解”就行。你写精通C语言,面试官问你函数指针和指针函数的区别,你答不上来,那就尴尬了。你写熟悉C语言,面试官问的问题会相对基础一些,你答上来了,反而超出预期。

项目经验少也没关系,你可以把课程设计、自学的小项目、甚至帮别人调过的一个小bug写上去。关键是你要能说清楚你做了什么、遇到什么问题、怎么解决的。面试官不在乎项目大小,在乎你是不是真的动手了。

3.2 面试被问到不会的问题,怎么接话

面试嵌入式岗位,遇到不会的问题太正常了。芯片型号那么多,外设那么杂,谁也不可能全做过。关键是你怎么接话。

错误示范:面试官问“你用过CAN总线吗?”你答“没用过。”然后就没下文了。这样面试官会觉得你沟通能力不行,或者学习意愿不强。

正确示范:你答“CAN总线我没实际用过,但我了解它是差分信号、多主架构、带仲裁机制。我之前用过RS485,也是差分信号,但RS485是单主多从,没有仲裁。如果项目需要,我可以很快上手,因为通信协议这块我有基础。”这样回答,既诚实,又展示了你的知识迁移能力,还表达了学习意愿。

还有一种情况是问题本身有坑。比如面试官问“volatile关键字的作用是什么?”你如果只答“防止编译器优化”,那只能算及格。你可以补充“它告诉编译器这个变量可能被外部改变,每次访问都要从内存读取,不能缓存在寄存器里。在嵌入式里,访问硬件寄存器、中断里修改的全局变量、多任务共享的变量,都要加volatile。”这样答,面试官就知道你不仅知道概念,还知道应用场景。

3.3 谈薪资的时候,别被“嵌入式工资低”吓住

网上总有人说嵌入式工资低,不如互联网。这话对也不对。纯做单片机开发的,工资确实不高,因为门槛相对低,竞争也激烈。但嵌入式范围很广,你做Linux驱动、做音视频编解码、做汽车电子,工资一点都不低。

对于刚入行的人来说,第一份工作的工资不是最重要的,重要的是能不能接触到核心的东西。你进一个做产品的公司,能从头到尾跟一个项目,从选型到量产,这个经验比多拿两千块钱值钱得多。我第一份工作工资很低,但那个团队让我独立负责了一个小项目的固件开发,从原理图评审到代码编写到产线测试,全流程走了一遍。这个经历让我在后面跳槽的时候,底气足了很多。

谈薪资的时候,你可以先问清楚工作内容。如果岗位是做维护、做边角料,那工资高也不要去,因为学不到东西。如果岗位能让你参与完整的产品开发,工资低一点也可以接受,就当交学费了。

4. 进去之后的前三个月,决定你能不能留下来

4.1 第一周:把开发环境跑通,把代码下载进去

新人入职第一周,最重要的不是看懂多少代码,而是把开发环境搭起来,把现有的代码编译通过,下载到板子上,能看到现象。这个过程中你会遇到各种问题:编译器版本不对、库文件缺失、下载器驱动没装、板子供电不对。这些问题看起来是小事,但如果你一周都搞不定,老大就会怀疑你的能力。

我的经验是,遇到环境问题,先看文档,再看同事的电脑是怎么配的,最后再问人。问人的时候不要问“为什么编译不过”,而要问“我编译的时候报了这个错,我试了A和B两种方法都不行,你觉得可能是什么原因”。这样别人知道你动过脑子了,也更愿意帮你。

还有一点,把遇到的问题和解决方法记下来。我有个习惯,每解决一个问题,就在笔记里记一条:现象是什么、原因是什么、怎么解决的。三个月下来,笔记里攒了几十条,后面再遇到类似问题,翻笔记就行,不用再问人。

4.2 第一个月:从小bug改起,建立信任

第一个月,老大一般不会让你碰核心代码,而是让你改一些小bug或者加一些小功能。这时候不要嫌活小,要把每个小活都干漂亮。比如让你改一个LED闪烁的频率,你不仅要把频率改了,还要看看原来的代码有没有问题,能不能优化一下。你改完提交代码的时候,写清楚改了什么、为什么这么改、测试结果是什么。这样老大看你的代码提交记录,就知道你靠谱。

我见过一个新人,让他改一个串口打印的格式,他改完之后顺手把打印函数的缓冲区溢出问题也修了。虽然那个问题不是他负责的,但他发现了就修了,还在提交说明里写清楚了。老大看到之后,第二个月就让他参与核心模块的开发了。

4.3 第三个月:能独立负责一个模块,就算站稳了

三个月是个坎。如果你三个月后还不能独立负责一个模块,还需要别人手把手教,那可能就危险了。独立负责的意思是:给你一个需求,你能自己拆解成任务,自己设计实现方案,自己编码调试,遇到问题自己先想办法解决,实在解决不了再求助。

这个能力不是天生的,是练出来的。我的方法是:接到任务后,先别急着写代码,先想清楚几件事——这个模块的输入输出是什么、跟其他模块怎么交互、用什么数据结构、有没有现成的代码可以参考、可能遇到什么问题。想清楚了再动手,比上来就写要快得多。

还有,学会看数据手册和参考手册。嵌入式的很多问题,答案都在手册里。比如你配置一个外设不工作,先查手册看时钟使能了没有、引脚复用配置对了没有、寄存器位设对了没有。手册看多了,你就知道哪些地方容易出错,调试的时候直接往那些地方查。

5. 那些招聘要求上不写,但天天在用的东西

5.1 版本控制:Git不是可选项,是必选项

学校里做项目,代码都是自己一个人写,最多用U盘拷来拷去。但工作中,代码是团队协作的,必须用版本控制。现在主流的是Git,你至少得会这几个操作:clone、pull、commit、push、branch、merge。不用学到能处理复杂冲突的程度,但基本的流程要会。

我见过新人把代码改乱了,想回退到之前的版本,结果不会用Git,只能凭记忆手动改回去,改了半天还改错了。如果你会用Git,一条git checkout就搞定了。

还有一个习惯:每次提交代码之前,先git diff看一下自己改了什么,确认没有误改的地方。提交说明写清楚,不要写“修改bug”,要写“修复串口接收缓冲区溢出问题,当接收数据超过缓冲区大小时丢弃多余数据”。这样别人看提交记录就知道你干了什么。

5.2 调试手段:printf不是万能的,但没它万万不能

嵌入式调试,最常用的手段就是打印。串口打印、RTT打印、SWO打印,至少得会一种。串口打印最简单,但占用一个UART外设,而且速度慢。RTT是Segger的工具,速度快,不占外设,但需要J-Link调试器。SWO是ARM的调试接口,速度也快,但配置稍微复杂一点。

打印的时候要注意,不要在中断里打印太多东西,因为打印本身很耗时,可能导致中断响应不及时。也不要在高频调用的函数里打印,否则串口输出会成为瓶颈。我一般的做法是,在关键路径上打标记,比如进入某个状态打一个字符,退出打另一个字符,这样既能跟踪流程,又不会太影响性能。

除了打印,还要学会用调试器。单步执行、断点、查看变量、查看寄存器,这些基本操作要熟练。有时候打印看不出来的问题,用调试器一看寄存器就知道了。比如串口收不到数据,你打个断点看状态寄存器的RXNE位有没有置起来,就知道是硬件没收到还是软件没读。

5.3 阅读英文手册:逃避不了的基本功

嵌入式的芯片手册、协议文档、应用笔记,大部分是英文的。你可以英语不好,但你必须能借助翻译工具看懂技术文档。这不是能力问题,是态度问题。

我刚开始看英文手册的时候,一个词一个词查,看一页要半小时。后来看多了,常见的术语就那些:register、bit、enable、disable、interrupt、clock、reset、configure。看多了就快了。而且技术文档的句式很固定,看多了基本能猜出意思。

提示:看英文手册的时候,先看目录和框图,了解整体结构;再看寄存器描述和时序图,了解具体细节;最后看例程和注意事项。不要从第一页开始逐字读,那样效率太低。

5.4 硬件协作:跟硬件工程师沟通的正确姿势

嵌入式软件工程师跟硬件工程师的协作非常频繁。你发现一个引脚输出不对,可能是软件配置问题,也可能是硬件连接问题。这时候你需要跟硬件工程师一起排查。

沟通的时候,不要说“你的板子有问题”,而要说“我测了这个引脚,软件配置是推挽输出高电平,但实际测出来是低电平,你帮我看看硬件上有没有什么影响”。这样对方更容易接受,也更愿意配合你排查。

还有,提问题的时候尽量提供完整的信息:芯片型号、引脚编号、软件配置、实测结果、你试过哪些方法。信息越全,硬件工程师越容易帮你定位问题。我见过有人只说“串口不通”,然后硬件工程师问半天才知道是哪个串口、哪个引脚、什么现象,效率极低。

6. 从“混进去”到“站稳脚”,心态比技术更重要

6.1 接受自己一开始什么都不会

很多人不敢投嵌入式岗位,是因为觉得自己什么都不会。但你要知道,没有人一开始什么都会。那些看起来游刃有余的老手,也是从什么都不会过来的。区别在于,他们接受了自己的无知,然后一点点去学。

我入职第一周,连公司的代码仓库怎么克隆都不知道,问同事的时候脸都红了。但问完之后我就知道了,下次就不用问了。三个月后,新来的同事问我同样的问题,我告诉他怎么操作,他也很感激。这个过程很正常,不要因为不会就觉得自己不行。

6.2 遇到问题先自己查,但不要死磕

嵌入式开发遇到的问题,大部分都能在网上找到答案。芯片厂商的官方论坛、Stack Overflow、各种技术博客,都是很好的资源。遇到问题先搜一下,很可能别人已经遇到过了。

但也不要死磕。如果你查了两个小时还没解决,那就该问人了。问人的时候,把你查到的信息、试过的方法、现在的现象都说清楚,这样别人帮你的时候也有方向。最怕的是那种闷头搞了一天,最后发现是一个很低级的错误,白白浪费时间。

6.3 保持学习,但不要盲目追新

嵌入式技术更新不算快,但也在变。新的芯片、新的协议、新的工具链,时不时就冒出来。你不需要每个都追,但你要保持学习的状态。比如RISC-V现在很火,你可以了解一下它的基本概念,但不一定要马上转过去。等工作中真的用到了,再深入学也不迟。

更重要的是把基础打牢。C语言、数据结构、操作系统原理、计算机组成原理,这些基础的东西,越扎实越好。因为不管技术怎么变,底层的东西是不变的。你基础好,学新东西就快;基础不好,学什么都费劲。

6.4 找到自己的方向,不要什么都想做

嵌入式范围很广,有做单片机的、做Linux的、做驱动的、做应用的、做算法的。你不可能什么都精通,也没必要什么都做。工作两三年后,你应该找到自己感兴趣的方向,然后深耕下去。

比如你对底层感兴趣,可以往驱动开发方向走,研究内核机制、设备模型、电源管理。如果你对应用感兴趣,可以往应用层开发走,研究框架设计、性能优化、跨平台适配。如果你对硬件也感兴趣,可以往系统架构方向走,做软硬件协同设计。

方向没有好坏,只有适合不适合。关键是你要在一个方向上积累足够的深度,这样才有竞争力。

我到现在还记得第一次独立解决一个死机问题的场景。那是一个跑在Cortex-M0上的小系统,偶尔会死机,概率很低,一天可能就一两次。我花了三天时间,用打印和调试器一点点缩小范围,最后定位到一个中断服务函数里访问了未对齐的地址。M0不支持非对齐访问,一访问就HardFault。改掉之后,再也没死过机。那个瞬间的成就感,比拿多少工资都强。嵌入式这个行当,门槛确实有,但没你想的那么高。先进去,再慢慢学,你会发现那些看起来吓人的东西,拆开了看也就那么回事。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询