嵌入式面试的断层:功能能讲、底层就空,差的是体系结构那一层
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- 写过 UART/SPI/I2C,能收发就够了吗?面试官还会关心什么?
- SPI 的四种模式(CPOL/CPHA)怎么区分?片选和时钟频率要注意什么?
- I2C 总线被从机拉死(SDA 一直被拉低)怎么恢复?
- UART 出现 overrun、framing error 分别说明什么,该怎么处理?
- 项目里写了「实时」,最坏路径和优先级设计是怎么定的?
- 复位之后到 main 之前发生了什么?带 Bootloader 时又不一样在哪?
- 同样做过一个项目,为什么有人能接住追问、有人一追就空?
《参考解析》
「能收发」只是功能层,面试官要的是体系结构层。 功能层的回答是「我调通了 SPI,能读到传感器数据」;体系结构层的回答是「为什么选 SPI 而不是 I2C、时钟极性相位怎么配、片选和时钟频率的边界在哪、出错时怎么恢复、DMA 用了没有、最坏一次传输多久」。同一个项目,两种讲法的信息量差一个量级。所以准备的时候不要按「我做了什么功能」列清单,要按「这个模块依赖哪些机制、这些机制的边界在哪」列。
SPI 的四种模式,先记采样边沿再记名字。 CPOL 决定空闲时时钟是高还是低,CPHA 决定在第一个还是第二个边沿采样。组合起来四种模式里最常用的是模式 0(CPOL=0、CPHA=0,空闲低、上升沿采样)和模式 3(CPOL=1、CPHA=1,空闲高、下降沿采样)。选错模式的现象很典型:读回来的数据整体错位一位或全是 0xFF/0x00,而不是「随机乱码」。片选要注意的是:多从机时每个从机独立 CS,CS 拉低到第一个时钟之间要留建立时间,传输结束到 CS 拉高要留保持时间;有的器件要求 CS 在整帧期间保持低电平,不能在字节之间抖动。时钟频率的上限由从机器件手册给(常见几十 MHz),但实际能跑多快还受走线长度、上拉、探头负载影响,所以调试时先降频跑通再往上试。
I2C 总线锁死是现场高频故障,恢复手法要能说出来。 典型场景是主机在从机还在驱动 SDA 为低的时候复位了,之后主机发停止位也拉不高 SDA,总线就卡住。恢复办法是主机把 SCL 当成普通 GPIO,手动打 9 个时钟脉冲,让从机把剩下的位(包括 ACK 位)发完从而释放 SDA,然后补一个停止条件;如果 9 个时钟之后 SDA 还是低,就要怀疑硬件(从机掉电、上拉缺失、器件损坏),这时候只能断电复位或加总线隔离。预防手段是把超时和错误计数写进驱动,别让一次卡死拖住整个任务。
UART 的三种错误分别指向不同层。 overrun 是接收寄存器里的数据还没被读走、新字节又来了,说明软件取数太慢或中断被长时间关闭——这类错误在高波特率 + 大量关中断的代码里特别常见,解决方向是改用 DMA 接收或缩短临界区。framing error 是停止位没在该出现的位置出现,通常是波特率不匹配、时钟误差累积、或者线路干扰/电平不匹配,先核对双方波特率和分频误差,再查电平转换和共地。noise error 是采样时检测到多位跳变,指向干扰,要查走线、屏蔽和终端匹配。答这类题的关键是「错误码 → 物理原因 → 处理策略」三段,而不是「我会打开错误中断」。
错误处理要分层,不能只有「重试」。 一层是驱动层:超时、ACK 缺失、校验失败,做有限次重试并计数;二层是协议层:帧头/长度/CRC 校验,丢弃坏帧并请求重发(如果协议支持);三层是业务层:连续失败到阈值就降级(用上一次的有效值、切备用传感器、进安全状态)并上报错误码。三层都写清楚,才叫「有错误处理」。面试官常追问的是「重试几次、间隔多少、失败了怎么办」——给不出数字往往说明这块是抄来的。
「实时」必须能给最坏路径。 定义一个任务的响应时间:从事件发生(中断置位)到任务处理完的时间,等于中断延迟 + 调度延迟 + 被高优先级任务抢占的时间 + 被低优先级任务持锁阻塞的时间 + 自身执行时间。要做的事有三件:给关键任务排优先级(周期越短、截止时间越紧的优先级越高,也就是速率单调的思路)、把临界区压到最短并记录最长关中断时间、用栈高水位验证余量。能报出「这个任务最坏 2 ms 响应、我们要求 5 ms」的人,比说「我们用了 RTOS 所以是实时的」的人可信得多。
启动链路是「体系结构层」的门槛题。 上电先从向量表取初始 MSP 和复位入口,进 Reset_Handler 后做最小时钟与 Flash 等待周期配置,再把 .data 从 Flash 拷到 RAM、.bss 清零,跑 C/C++ 运行时初始化,最后进 main。带 Bootloader 的时候,前面还多一步「判断启动源」:Bootloader 自己先跑完这套流程,校验应用镜像(CRC/签名)、必要时做升级或回滚,然后改 MSP、设 VTOR 指向应用的向量表、跳到应用的复位入口。能讲清 VTOR 为什么要重定位、跳转前为什么要关中断和清外设,这一题就答满了。
为什么有人接不住追问。 差别不在知识量,而在准备方式。有效的方式是把每个模块做成一条「追问链」:这个机制解决什么问题 → 不用它会怎样 → 用错了会出现什么现象 → 出了 bug 从哪里查 → 项目里哪段代码能对应上。五问走一遍,任何一层被追问都能落到你写过的代码和见过的现象上。反过来,只背结论(「要加上拉」「要用 DMA」「要关中断」)的人,被问第二层就没有依据了。
最后一句提醒: 简历上写的每个技术词,都要能配一个「我踩过的坑 + 我怎么定位的」。面试官顺着这几个词往下问,问到的正是这些。