嵌入式软件面试经(自用)

嵌入式软件实习 · 八股文复习手册

面向:嵌入式软件(MCU 方向)实习/校招面试 · 单片机 + RTOS 为主

用法:先盖住答案自己讲一遍 → 对答案 → 标记讲不出的 。每题都能直接拿去问 AI 展开。

优先级图例:★★★ 几乎每场必问 · ★★ 常考 · ★ 加分/拉开差距

答题三层(面试官真正想听的):

  1. 是什么(定义/原理)
  2. 对比与场景(和谁比、什么时候用、坑在哪)
  3. 我项目里怎么用/怎么炸过(结合项目,最好带数字或踩坑故事)

0. 针对你简历的"必被深挖点"

面试官会照着你简历上的词逐条问。下面每个词都准备了题,答不出就等于简历吹牛:

简历里的词 对应章节 你必须能讲清
CAN、OTA、Bootloader 四、七 帧格式/仲裁、Flash 分区与跳转
LVGL 移植 七 怎么移植、怎么和驱动分层、帧率优化到 25fps
RT-Thread 六 内核机制、IPC、你项目里怎么用
STM32H743 MPU + D2 域 SRAM 六、十一 为什么放 D2、MPU 配了什么
K210 人脸识别 + 串口协议 + 状态机 四、十 协议怎么定、状态机怎么切
ZigBee / WiFi / 机智云 四 多节点怎么组网、数据怎么上云
研读数据手册定位硬件故障 十二 准备好 2 个真实踩坑案例

一、C 语言 ★★★

Q1. volatile 的作用?哪些地方必须用?

  • 告诉编译器该变量可能被"编译器看不见的地方"修改,禁止优化(不缓存到寄存器),每次访问都真的读内存。
  • 必须用:① 硬件寄存器映射指针 ② 中断(ISR)与主循环共享的变量 ③ 多任务共享的标志位。
  • 常与 const 组合:const volatile ------ 只读寄存器(程序不能写,但硬件会改)。
  • 追问(高频坑):加了 volatile 就线程安全了吗?
    → 不是 。volatile 只保证"每次真读内存",不保证原子性、不提供内存屏障 。i++(读-改-写)多任务下仍会出错,计数类要么加临界区,要么用原子操作。

Q2. static 的三个作用? ★★★

  • 修饰局部变量 :存储位置从栈→静态区,生命周期变成整个程序,但作用域仍在本函数内(函数间不共享)。
  • 修饰全局变量 :链接属性变 internal,只在本文件可见(避免命名冲突)。
  • 修饰函数:同上,只在本文件可见。

Q3. const 和 #define 的区别? ★★

  • #define 是预处理文本替换 ,无类型检查、不占内存、调试看不到符号;const 是编译期变量,有类型检查、有作用域。
  • 建议:常量优先 const/enum,宏只在条件编译和必要的宏函数里用。

Q4. const 修饰指针的几种写法怎么读? ★★

  • const int *p:p 可改,*p 不能改(指向常量)。
  • int * const p:p 不能改,*p 可改(常指针)。
  • const int * const p:都不能改。
  • 口诀:const 在 * 左边管指向内容,在右边管指针本身。

Q5. #define 和 typedef 的区别? ★★

  • typedef 是给类型起别名,编译期处理,有类型语义。
  • #define 是文本替换 ,预处理期。典型反例:#define PTR int* 然后 PTR a, b; → int* a, b;(b 是 int 不是指针!),而 typedef int* PTR; 则 a、b 都是指针。

Q6. sizeof 和 strlen 的区别? ★★★

  • sizeof 是运算符,编译期算出字节数,对数组返回整个数组大小。
  • strlen 是函数 ,运行期数到 '\0' 为止。
  • 陷阱:char *p = "abc"; sizeof(p)=4/8; strlen(p)=3。数组当参数传进函数会退化成指针 ,sizeof 就不再是数组大小。

Q7. 指针和数组的区别? ★★

  • 数组名是地址常量(不能自增),数组是真实存在的连续空间。
  • 指针是变量,可以移动;指针可以是 NULL,数组名不行。
  • sizeof(数组) = 总大小;sizeof(指针) = 指针本身大小。

Q8. 结构体内存对齐规则?sizeof 怎么算? ★★★

  • 规则:① 每个成员的偏移量是自身对齐数的整数倍 ;② 结构体总大小是最大对齐数的整数倍 ;③ 对齐数 = min(成员大小, 编译器对齐参数)。
  • 例子(32 位,默认 4 对齐):
    • struct {char c; int i;} → c@0,i 填充到 4,共 8 字节。
    • struct {int i; char c;} → 共 8 字节(尾部补齐)。
    • struct {char a; int b; char c;} → 共 12 字节。
  • 加分 :调整成员顺序可省空间;#pragma pack(1) / __attribute__((packed)) 可压缩,用于协议打包,代价是可能拆成多次总线访问、M0 上非对齐访问会 HardFault。
  • 追问 :协议通信不要直接强转结构体发送,要显式按字节序逐字段序列化。

Q9. union(联合体)和 struct 的区别? ★★

  • union 所有成员共享同一块内存,大小 = 最大成员大小(再按对齐取整);同一时刻只有一个成员有效。
  • 用途:省内存、类型双关(判断大小端、寄存器位域访问)。

Q10. 位域是什么? ★

  • 结构体成员可指定占几位(unsigned int flag:1;),用于硬件寄存器映射 和协议帧定义。缺点:布局依赖编译器。

Q11. 怎么判断大小端? ★★

  • 大端:高字节存低地址。小端:低字节存低地址(x86、Cortex-M 都是小端)。
  • 判断法:
c 复制代码
union {int i; char c;} u = {1};
printf("%d\n", u.c);   // 小端输出 1,大端输出 0
  • 通信里跨平台必须约定字节序,常用 htonl/ntohl 或手动移位打包。

Q12. C 程序的内存分区? ★★★

  • 栈:局部变量、函数参数(自动分配释放,可能溢出)。
  • 堆 :malloc/free(手动管理,易泄漏/碎片)。
  • .data:已初始化的全局/静态变量。
  • .bss(ZI-data) :未初始化/零初始化的全局/静态变量,启动时统一清零。
  • .rodata / .text:常量、字符串字面量、代码。
  • 追问 :为什么 .bss(ZI-data)不占镜像大小?→ 都是 0,镜像里不用存,启动时把该 RAM 区清零即可。

Q13. 野指针、内存泄漏、栈溢出? ★★

  • 野指针:指针未初始化 / 指向已释放内存 → 用完置 NULL,free 后置 NULL。
  • 内存泄漏:malloc 后没 free(嵌入式慎用动态内存,优先静态内存池)。
  • 栈溢出:栈太小或递归过深 → 现象是跑飞/HardFault,靠填充魔数、栈水位检测定位。

Q14. 函数指针 / 回调函数? ★★

  • void (*fp)(int); 是函数指针,可用于回调、驱动分层、状态机跳转表、命令表。
  • 你项目里的"指令解析 + 状态机调度"就是典型用法。

Q15. 带参宏的陷阱? ★

c 复制代码
#define SQ(x) x*x      // SQ(1+2) → 1+2*1+2 = 5 错!
#define SQ(x) ((x)*(x)) // 正确:每个参数加括号,整体加括号
  • 还有副作用问题:#define MAX(a,b) ((a)>(b)?(a):(b)),MAX(i++,j++) 会自增两次。

Q16. 编译的四个过程? ★★

  • 预处理 (.i:展开宏、头文件、条件编译)→ 编译 (.s:生成汇编)→ 汇编 (.o:生成目标文件)→ 链接 (可执行/.hex/.bin:合并段、分配地址)。

二、常用手写代码题 ★★

Q17. 手写 memcpy(考虑重叠用 memmove)

c 复制代码
void *my_memcpy(void *dst, const void *src, size_t n) {
    char *d = (char *)dst;
    const char *s = (const char *)src;
    while (n--) *d++ = *s++;
    return dst;
}
// memmove:若 dst 在 src 后方且重叠,需从尾部倒着拷贝

Q18. 手写 strcpy / strlen

c 复制代码
size_t my_strlen(const char *s) {
    const char *p = s;
    while (*p) p++;
    return p - s;
}
char *my_strcpy(char *dst, const char *src) {
    char *r = dst;
    while ((*dst++ = *src++));
    return r;
}

Q19. 判断大小端(见 Q11)

Q20. 宏求数组元素个数

c 复制代码
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))  // 仅对真数组有效,指针无效

Q21. 位操作

c 复制代码
#define SET_BIT(x,n)    ((x) |=  (1u << (n)))
#define CLR_BIT(x,n)    ((x) &= ~(1u << (n)))
#define TOGGLE_BIT(x,n) ((x) ^=  (1u << (n)))
#define GET_BIT(x,n)    (((x) >> (n)) & 1u)

Q22. 链表(手撕链表基本躲不掉)

  • 必会:创建节点、尾插 、头插 、删除节点 、反转链表 、判环(快慢指针) 、合并两个有序链表。
  • 嵌入式里链表常用于任务/设备管理、消息队列底层,所以面试官爱考。

Q23. 字符串反转 / 数组去重 / 冒泡·快排


三、STM32 / MCU 基础 ★★★

Q24. STM32 上电到 main 的过程? ★★★

  1. 上电复位,从向量表第 0 项取 MSP 初值(栈顶地址)。
  2. 从向量表第 1 项取 Reset_Handler 地址并跳转。
  3. Reset_Handler → 调 SystemInit(配时钟)→ __main → 把 .data 从 Flash 搬到 RAM、把 .bss 清零 → 调 main()。

Q25. GPIO 有哪几种模式?推挽和开漏的区别? ★★★

  • 输入:浮空、上拉、下拉、模拟。
  • 输出:推挽、开漏;复用推挽、复用开漏。
  • 推挽:能主动输出高和低,驱动能力强。
  • 开漏 :只能拉低,高电平靠外部上拉 ,可实现线与 、电平转换 、总线共享 → I2C 必须用开漏。

Q26. 为什么 I2C 用开漏 + 上拉? ★★

  • 多设备共享两条线,开漏实现线与:任一设备拉低总线就为低,避免推挽"一个拉高一个拉低"造成短路。
  • 上拉电阻提供高电平;阻值影响上升沿速度与功耗(常见 4.7k)。

Q27. 中断和轮询的区别?什么时候用哪个? ★★

  • 轮询:CPU 主动查状态,简单但浪费 CPU、实时性差。
  • 中断:事件触发,CPU 不用等,实时性好、效率高。
  • 高频大量数据用 DMA 更进一步(不占 CPU)。

Q28. 中断服务函数(ISR)里要注意什么? ★★★

  • 快进快出,别做耗时操作。
  • 不能用会阻塞的 API (如带阻塞的 RTOS 调用、malloc)。
  • printf 慎用(不可重入、慢),非要打印用无锁/环形缓冲方式。
  • 与主循环共享的变量加 volatile。
  • 带 RTOS 时中断里只能调 xxxFromISR 版本 API。

Q29. 中断优先级怎么理解? ★★

  • Cortex-M 用 NVIC,优先级数值越小优先级越高。
  • 分抢占优先级 (能打断别人)和子优先级(同抢占级谁先,不能互相打断)。
  • 用 HAL_NVIC_SetPriorityGrouping 划分位数。

Q30. 时钟树 / 主频怎么配? ★★

  • HSE/HSI → PLL 倍频 → SYSCLK → AHB/APB 分频。
  • 你自己的坑 :GY906 温度跳 1037.55/-273.15,根因是 SystemClock_Config 配成 8MHz 而非 64MHz,串口/时序全错。这就是绝佳的项目排障案例。

Q31. Flash 擦除后是什么值?能按字节写吗? ★★

  • 擦除后是 0xFF;写之前必须先擦除(只能 1→0)。
  • 写入按对齐单位:F1 半字(16bit)、F4 字(32bit)、H7 更宽,不能随意按字节写。
  • Flash 有擦写寿命,频繁写用 EEPROM/外部 Flash。

Q32. ADC 采样精度由什么决定? ★

  • 分辨率(12 位 = 0~4095)、参考电压、采样时间、输入阻抗、是否过滤波。
  • 电压 = adc * Vref / 4095。

Q33. 看门狗(IWDG/WWDG)原理? ★★

  • 独立看门狗由内部低速时钟驱动,程序定时"喂狗",超时未喂就复位。
  • 防跑飞/死锁,喂狗要放在"确认系统健康"的地方,别放中断里盲目喂。

四、通信总线 ★★★

Q34. UART / I2C / SPI 的区别?各自场景? ★★★(经典必考对比题)

UART I2C SPI
线数 2 (TX/RX) 2 (SCL/SDA) 4 (SCK/MOSI/MISO/CS)
同步 异步 同步 同步
双工 全双工 半双工 全双工
速率 中 低 高
拓扑 点对点 多设备(地址) 多设备(片选)
场景 调试/模块通信 传感器/EEPROM Flash/屏/高速外设

Q35. UART 数据帧结构和波特率? ★★★

  • 帧:起始位(1) + 数据位(5~9) + 校验位(0/1) + 停止位(1/2)。
  • 波特率 = 每秒传输位数;两端必须一致,不一致会乱码。
  • 计算:BRR = fCK / (16 × 波特率),16 倍过采样,还有小数部分修正(USARTDIV 的整数+小数)。

Q36. UART 怎么收不定长数据? ★★

  • 方案:DMA + 空闲中断(IDLE) ------ DMA 搬运,总线空闲中断触发后算本次收到多少字节,再处理。比一字节一中断效率高。这条面试很爱问,你项目里用了多路串口,准备好。

Q37. SPI 的 4 种模式(CPOL/CPHA)? ★★

  • CPOL 决定空闲电平(0 低 / 1 高),CPHA 决定在哪个边沿采样(0 第一个边沿 / 1 第二个边沿)。
  • Mode0~3。主从必须配置一致,否则数据错。

Q38. I2C 时序 / 卡死怎么排查? ★★

  • 起始/停止条件、ACK/NACK、时钟拉伸(clock stretching)。
  • 卡死常见原因:从设备把 SDA 拉死 → 补救:发 9 个时钟脉冲让从机释放,或复位 I2C 外设。
  • 上拉电阻缺失/阻值不对也会导致通信失败。

Q39. CAN 为什么常用于汽车?帧格式? ★★★(你项目①核心)

  • 优势:差分传输抗干扰 、多主仲裁 、错误检测强(CRC+位填充+ACK)、可靠性高、成本低。
  • 差分:CAN_H/CAN_L,显性(逻辑0) 覆盖隐性(逻辑1) ,两端各 120Ω 终端电阻。
  • 帧:标准帧(11 位 ID)/ 扩展帧(29 位 ID);数据帧含仲裁段、控制段(DLC)、数据段(0~8)、CRC、ACK、帧结束。

Q40. CAN 仲裁怎么工作? ★★★

  • 非破坏性按 ID 仲裁:多个节点同时发,ID 小的(显性位多)获胜,输的节点自动退出、等下次。ID 越小优先级越高。

Q41. CAN 波特率怎么计算? ★★

  • 位时间 = 1 个位分成的若干 Tq:Sync + BS1 + BS2,采样点通常在 75%~87.5%。
  • 波特率 = 1 / (Tq × (1 + BS1 + BS2)),Tq = (预分频+1) / fCAN。
  • 你自己的坑 :CAN 调不通往往就是波特率算错。这是你现成的排障案例。

Q42. CAN 的过滤器、错误处理? ★★

  • 过滤器:只接收关心的 ID,减轻 CPU 负担(掩码/列表模式)。
  • 错误管理:TEC/REC 计数,主动错误→被动错误→总线关闭(Bus-Off) 三态。

五、DMA ★★

Q43. DMA 是什么?为什么要用? ★★★

  • 直接内存访问:不经过 CPU 在内存与外设间搬数据,CPU 可干别的。
  • 用于:串口大批量收发、ADC 连续采样、SPI 刷屏、PWM 驱动 LED。
  • 概念:通道/请求映射、优先级、正常模式 vs 循环模式 、传输完成/半传输中断。

Q44. 用 DMA 驱动 WS2812 的原理? ★★(你项目④做过)

  • WS2812 靠脉宽编码 :0 码/1 码占空比不同。用定时器 PWM 输出对应占空比波形,用 DMA 把预先算好的比较值(CCR) 连续搬进寄存器,实现不占 CPU 的精确时序输出。

Q45. DMA 和 Cache 的一致性问题? ★

  • 带 Cache 的核(M7/M4):DMA 直接改内存,CPU 可能读到 Cache 里的旧值 → 需要 clean/invalidate Cache,或把 DMA 缓冲区放到非 Cache 区(你项目④的 H743 + D2 域 SRAM 就与此相关)。

六、RTOS(RT-Thread / FreeRTOS)★★★

Q46. 任务有哪几种状态?怎么切换? ★★★

  • 就绪 / 运行 / 阻塞(等信号量/延时)/ 挂起。
  • 调度时机:时间片用完、被更高优先级抢占、主动阻塞/延时、事件到来被唤醒。

Q47. 调度算法? ★★★

  • 抢占式 + 同优先级时间片轮转,永远运行最高优先级就绪任务。
  • FreeRTOS 用优先级位图 + 就绪链表 实现 O(1) 调度。

Q48. 裸机 vs RTOS?什么时候用 RTOS? ★★★

  • 裸机:任务少、逻辑简单、实时性要求确定 → 前后台 + 状态机够用。
  • RTOS:多任务并发、有阻塞等待、模块解耦时用,能简化复杂时序,但引入栈开销、调度开销、共享资源保护问题。

Q49. 信号量 / 互斥量 / 事件 / 消息队列 的区别? ★★★(高频对比题)

  • 二值信号量:事件通知/同步(ISR 里 give,任务里 take)。
  • 计数信号量:管理多个同类资源(如缓冲池)。
  • 互斥量(Mutex) :有所有者 ,用于临界资源保护,带优先级继承;不能用于中断。
  • 事件集/事件标志组 :一个任务等多个事件组合。
  • 消息队列 :传递数据(拷贝/引用),可跨任务/中断。
  • 任务通知:最轻量最快的"单任务"通知方式。

Q50. 优先级反转是什么?怎么解决? ★★★(最高频 RTOS 题)

  • 场景:低优先级任务 L 持锁 → 高优先级 H 等锁被阻塞 → 中优先级 M 抢占 L → H 被 M 间接挡住。
  • 解决:① 优先级继承 (持锁的 L 临时提升到 H 的优先级,FreeRTOS 的 Mutex 自动做)② 优先级天花板(持锁即提升到可能用该锁的最高优先级)。
  • 工程根治:缩短临界区、别嵌套锁、别持锁阻塞、少用大锁。

Q51. 临界区怎么保护? ★★

  • 关中断(简单但影响实时性)、关调度/调度锁、用互斥量。
  • Cortex-M3/M4 用 BASEPRI 寄存器屏蔽指定优先级以下的中断,比全关中断温和。

Q52. 中断里能用 RTOS 的 API 吗? ★★★

  • 只能用在中断安全版本 (FreeRTOS 的 xxxFromISR,RT-Thread 的 rt_xxx_from_isr/带 _isr 后缀)。
  • 绝不能在 ISR 里调用会阻塞的 API。

Q53. 任务栈多大合适?栈溢出怎么发现? ★★

  • 一般几百字节~几 KB,按最深调用 + 局部变量估算,宁大勿小。
  • 检测:① FreeRTOS uxTaskGetStackHighWaterMark() 看栈水位 ② configCHECK_FOR_STACK_OVERFLOW ③ 栈填充魔数(0xA5)看被踩到哪。

Q54. 上下文切换做了什么? ★★

  • 保存当前任务的寄存器 + 返回地址到该任务栈,切到新任务的 TCB/栈,恢复其寄存器。
  • M3/M4 用 PSP 存任务栈、MSP 存中断/内核栈。

Q55. 死锁怎么产生、怎么避免? ★★

  • 四条件:互斥、持有并等待、不可抢占、循环等待。
  • 避免:加锁顺序统一、用超时、一次拿全、减少嵌套锁。

七、Bootloader / OTA / 启动 ★★(加分项,你项目①核心)

Q56. Bootloader 跳转到 APP 的关键步骤? ★★★

  1. 校验 APP 有效(CRC/魔数)。
  2. 关总中断(跳转前必须)。
  3. 设 MSP = APP 向量表0(栈顶)。
  4. 设 SCB->VTOR = APP 起始地址(重定位向量表)。
  5. 取向量表1(Reset_Handler)地址并跳转。

Q57. IAP 和 ISP 的区别? ★★

  • ISP:用芯片自带的 BootROM + 串口/USB 下载(出厂固件)。
  • IAP:程序运行时自己擦写 Flash 升级,即 OTA 的核心。

Q58. Flash 分区怎么做?OTA 怎么防变砖? ★★★

  • 典型:Bootloader 区 + APP 区(可再分 APP_A/APP_B 双备份)+ 参数/标志区。
  • 防变砖:升级前校验完整性和签名、升级标志写 Flash、失败可回滚到旧版本、断电续传。

Q59. LVGL 怎么移植?帧率怎么优化? ★★

  • 移植:提供显示驱动(刷屏接口)、输入驱动、时基(tick)、配置 lv_conf.h。
  • 帧率优化(你答到 25fps):优化刷屏通道(SPI 提速/DMA)、只刷新脏矩形、减少重绘、降低色深/图片解码开销、双缓冲。

八、中断 / 异常 / 排障 ★★★

Q60. HardFault 怎么排查? ★★★(面到必加分)

  • 定位:在 HardFault_Handler 里读栈里的 PC/LR/xPSR ,判断出错的是主栈(MSP)还是任务栈(PSP),再反汇编定位出错指令/变量。
  • 常见原因:空指针/野指针、数组越界、栈溢出、非对齐访问、除零、访问未使能的外设时钟、跳转非法地址。
  • 工具:J-Link 看寄存器、CmBacktrace 库自动回溯。

Q61. 程序跑飞怎么办? ★★

  • 查栈溢出、指针越界、中断标志没清导致的重复进中断、时钟/外设未初始化、看门狗喂狗位置不当。

Q62. 怎么看一个 bug 是硬件还是软件? ★★

  • 用示波器/逻辑分析仪看引脚波形:电源纹波、时钟、总线时序。软件逻辑对就查硬件(虚焊、上拉缺失、供电)。

九、操作系统 / 计算机网络(部分公司)★★

Q63. 进程和线程的区别? ★★

  • 进程有独立地址空间、资源;线程共享进程资源、切换开销小。

Q64. TCP 和 UDP 的区别? ★★

  • TCP:面向连接、可靠、有序(三次握手/四次挥手);UDP:无连接、快、不可靠。
  • 视频流/实时控制常用 UDP;配置/文件传输用 TCP(你项目④的 RTMP 基于 TCP)。

Q65. 三次握手为什么不是两次? ★

  • 防止已失效的连接请求迟到后server误建连接;确认双方收发能力都正常。

十、无线 / 云端(你项目③④)★★

Q66. WiFi / BLE / ZigBee / LoRa / 4G 的区别与场景? ★★

  • WiFi:高带宽、功耗高、局域网 → 网关/数据上传。
  • BLE:低功耗、短距、低带宽 → 可穿戴/近场。
  • ZigBee:低功耗、自组网多跳、低带宽 → 传感器组网(你项目③)。
  • LoRa:远距离、极低功耗、低带宽 → 野外/农业(你项目④)。
  • 4G:广域、需基站、功耗高 → 远程回传。

Q67. 多节点怎么组网、数据怎么上云? ★★(照你项目③讲)

  • 子节点(ZigBee) → 中控单片机汇聚 → WiFi/ESP8266 → 云平台(机智云/阿里云) → 手机 APP 显示与控制。
  • 讲清:协议、汇聚节点角色、上云协议(MQTT/HTTP)。

Q68. 用过的云平台?数据怎么存? ★

  • 阿里云 / 机智云 / OneNET;数据可存时序库,用规则引擎转发。

十一、ARM 架构 / 体系结构 ★(拉开差距)

Q69. Cortex-M 系列区别? ★

  • M0/M0+:小核、无 MPU(部分)、无 Cache;M3:带 MPU、无 FPU;M4:带 FPU(单精度);M7:高性能、双精度 FPU、Cache、TCM。

Q70. MSP 和 PSP 是什么? ★★

  • 两个栈指针:MSP 主栈 (中断/内核用),PSP 进程栈(RTOS 任务用)。任务切换时切 PSP。

Q71. MPU 是什么?H743 的 D2 域 SRAM 为什么要单独布局? ★★(你项目④核心)

  • MPU:内存保护单元,划分区域并设置访问权限和 Cache 属性,防止越界破坏。
  • H743 有多个 SRAM 域(如 AXI/D2/D3):不同域挂在不同总线上,可在 MPU 里单独配置 Cache 属性/权限 。把 DMA 缓冲或高频访问数据放到指定域并配好 Cache 策略 ,避免 Cache 一致性问题和总线争用。面试能讲清"为什么放 D2、MPU 设了什么属性"就非常出彩。

Q72. 异常向量表是什么?怎么重定位? ★★

  • 存各种异常/中断入口地址的表,默认在 Flash 起始。用 SCB->VTOR 改基址(OTA/Bootloader 跳转时用)。

十二、项目排障(STAR 法则)★★★

面试问"遇到什么困难/最自豪的项目",用 STAR :S ituation 背景 → T ask 任务 → A ction 你怎么做 → R esult 结果(带数字)。

你现成的两个案例(一定要背熟):

案例1:CAN 通信调不通

  • S:双 STM32 做 CAN 仪表盘,一直收不到数据。
  • T:定位是硬件还是软件。
  • A:查 TSR/ESR/MSR 寄存器判断发送状态和错误类型,核对位时序与波特率计算,排查 TJA1050 收发器供电/终端电阻。
  • R:发现是波特率配错,改正后通信正常(可补:稳定 25fps 刷新)。

案例2:GY906 红外测温温度乱跳(1037.55 / -273.15)

  • S:温度读到明显离谱的值。
  • T:找根因。
  • A:排除"增量编译混链"假设,读数据手册核对时序;确认是主频 8MHz 而非 64MHz (SystemClock_Config 与 RT-Thread 的 system_clock_config 不一致),导致 I2C/时序基准全错。
  • R:统一时钟配置后温度正常。
  • 这个案例体现"看数据手册定位配置错误",正好对应你自我评价那句。

准备框架,每个项目都能套:

  • 一句话项目是什么 + 解决什么
  • 你负责哪块(精确到模块/文件)
  • 最大难点 + 定位过程 + 修复结果(数字)
  • 如果重做会怎么改进(几乎必问,提前想)

备考节奏建议

  1. 先扫自己简历:简历上每个技术词,都要能讲"定义→对比→项目里怎么用"。讲不出的立刻补。
  2. 按优先级背:C 语言 → STM32 外设 → RTOS → 你的项目,这四块占 70%。
  3. 每题三层:定义 / 对比场景 / 项目结合。
  4. 手撕代码:链表、memcpy、字符串,提前手敲到熟练。
  5. 准备 1 分钟和 5 分钟两个版本的项目介绍。
  6. 一面考广度,二面考深度:二面多想"系统设计、问题定位、工程取舍"。

参考来源(详见文末链接):CVTE/小米/安克创新/江波龙等面经,牛客春招嵌入式汇总,CSDN/知乎嵌入式八股题库。

相关推荐
Xudde.1 小时前
PwnLab: init 靶机渗透测试(Vulnhub Writeup)
笔记·学习·安全·web安全
救救孩子把1 小时前
AI面试八股文-07_6-向量数据库索引详解
数据库·人工智能·面试·向量数据库·hnsw
学逆向的1 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
我命由我123451 小时前
Function Calling 模型
人工智能·python·学习·ai·学习方法·ai编程·ai写作
程序 代码狂人1 小时前
数据开发面试【问答完整版|带深挖追问 + 扩展回答】
面试·职场和发展
我是海飞2 小时前
使用杰理 AC7925B 实现 Windows电脑 USB 副屏
windows·单片机·电脑·嵌入式·杰理
别动我齐刘海2 小时前
实时控制学习2
linux·c++·人工智能·学习·算法
江华森2 小时前
Web漏洞与中间件框架漏洞实战详解
面试
我是海飞2 小时前
杰理 JL703N SDK 实现 AI 自动化调试:自动进入下载模式、下载、重启与日志抓取
人工智能·单片机·自动化·音视频·杰理