嵌入式面试体检清单:C 语言、中断、总线、RTOS 与项目排障
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
C 语言与内存
- volatile 在嵌入式里有哪些典型使用场景?
- 结构体内存对齐规则是什么?如何计算 sizeof?
- 栈溢出常见现象有哪些?你怎么定位?
- 野指针和悬空指针区别是什么?
- 大小端如何判断?协议解析时要注意什么?
- 你项目里哪次因为内存或指针出问题?你是怎么定位的?
中断与并发
- 中断上下文和任务上下文有什么限制差异?
- ISR 里为什么不能做耗时操作?
- 临界区有哪些保护手段?分别适什么场景?
- 中断优先级和抢占怎么理解?
- 轮询、中断、DMA 传输如何选型?
- 这个数据为什么放中断里收、任务里处理?共享变量怎么保护,只靠 volatile 够不够?
MCU 与总线
- MCU 从上电复位到进入 main() 经历哪些步骤?
- I2C 通信基本时序是什么?出现 NACK 怎么处理?
- SPI 四种模式含义是什么?片选如何管理?
- UART 如何处理粘包、半包和丢字节?
- CAN 仲裁机制是什么?为什么不是「谁先发谁优先」那么简单?
- 看门狗怎么配才有意义?喂太勤会有什么问题?
RTOS
- FreeRTOS 任务状态有哪些?调度何时触发?
- 信号量和互斥量区别是什么?
- 什么是优先级反转?如何解决?
- 哪些 FreeRTOS API 能在中断中调用?
- 你的任务是怎么拆的?为什么这个用队列不用全局变量?出过优先级反转吗?
项目与排障
- 掉线重连怎么做?半包粘包怎么处理?
- DMA 丢数怎么查?HardFault / 死机标准排查路径是什么?
- 看门狗、日志、版本回滚有没有考虑?
《参考解析》
-
volatile 的三类场景讲全,才算真懂:它约束的是编译器优化,不提供原子性和内存屏障。三类典型场景是硬件寄存器(值可能被外设改写,编译器不能把它缓存进寄存器)、中断与任务共享的变量(ISR 里改、主循环里读,不加 volatile 可能读到寄存器里的旧值)、以及无锁的多线程共享标志。高频追问是「加了 volatile 是不是就线程安全了」——不是,
volatile只保证每次真的去内存读,读改写仍可能交错,计数类共享变量还要靠临界区或原子操作。 -
内存对齐要能算,也要知道为什么:规则是每个成员的偏移量必须是自身对齐数的整数倍,结构体总大小是最大对齐数的整数倍,对齐数取成员自身大小与编译器对齐参数(常见 4 或 8)中的较小值。之所以要对齐,一是 CPU 访问未对齐地址可能触发异常或拆成多次总线访问(Cortex-M 上部分指令要求对齐),二是对齐后的单次访问是原子的。答题时顺手说一句「调整成员顺序能省空间」「跨平台传输不要直接发结构体、要按字节序逐字段序列化」,就跳出了背公式的层次。
-
中断上下文的边界是嵌入式最容易被追问塌的地方:ISR 运行在特权上下文里,抢占的是当前任务,所以不能阻塞、不能睡眠、不能等锁、不能跑长循环,
printf这类会走缓冲和信号量的调用尤其危险。能做的事是把数据收下、把事件投递出去——给队列、放信号量、置标志位,把重活留给任务。临界区三种手段的取舍也要说清:关中断最硬但影响实时性,关调度只挡任务间竞争(挡不住 ISR),拿锁灵活但要注意持锁时间;共享变量只加 volatile 挡不住并发写。 -
总线题按「时序 → 机制 → 异常 → 选型」四步答:I2C 要能画起始和停止条件、讲清第 9 个时钟的 ACK / NACK、时钟拉伸和 7 位寻址(同一条总线上地址不冲突的从机都能挂,实际数量受总线电容 400pF 限制)。NACK 的排查顺序是先确认从机地址和上电状态,再看时序与上拉,必要时用逻辑分析仪抓波形;总线拉死通常是某个从机把 SDA 拉低不放(复位时序错乱、供电异常、从机死机),恢复手段是从机复位或主机补 9 个时钟把它顶出去。SPI 则要讲清 CPOL / CPHA 四种模式、片选管理和全双工,以及没有应答机制导致只能靠协议层校验。
-
RTOS 要讲成设计选择,不是教材目录:任务状态、优先级、调度时机的定义背下来只算入门,面试官想听的是「你项目里为什么这么拆」。信号量与互斥量的区别要落到所有权和优先级继承——信号量是计数与同步工具,互斥量带所有者、可用于优先级继承;优先级反转是低优先级任务持锁、被中优先级任务抢占、把高优先级任务堵在锁上的现象,解法是优先级继承(互斥量)或优先级天花板,根本解法是缩短临界区、避免多把锁嵌套。
-
看门狗要配得有意义:喂狗点必须放在「系统真的健康」的判据之后——比如主循环完整跑完一轮、关键任务都在心跳上报,而不是在定时器中断里无脑喂。喂太勤(比如放在高优先级中断里)会把死锁、任务饿死这类故障一起喂掉,看门狗就只剩复位功能。要能说清复位后怎么留痕(备份寄存器写故障码、日志落 flash)以及怎么定位是哪一步卡住。
-
项目排障的答法是固定的五步:现象 → 假设 → 验证 → 结论 → 改动。面试官要的是可复现的推理链,不是「后来就好了」。常见追问都有标准动作:掉线重连要讲退避策略与幂等;半包粘包要在协议里带长度字段或用固定帧头帧尾;DMA 丢数要查缓冲区大小与完成中断的竞争、以及内存对齐和 cache 一致性;HardFault 先看 LR / PC / 栈回溯,再对照是空指针、越界还是对齐异常。把异常路径、日志和指标补齐,比再堆一个同质化 Demo 收益高得多。
-
简历上写过的词就是承诺:「了解过 Linux」和「负责过驱动联调」在面试官耳朵里是两个级别,写了设备树、字符设备、platform 模型就得扛住 probe 路径、file_operations、设备树覆盖原则这些追问。时间紧的话按这个顺序压:C 与内存 → 中断边界与选型 → UART / SPI / I2C(车载工控再加 CAN)→ RTOS 调度与同步 → 按目标岗补 Linux 驱动,最后把一个主项目挖到能讲清模块划分、数据流和故障案例。