欣旺达 嵌入式软件工程师 二面 面经
1. 详细介绍你做过的最复杂的一个嵌入式项目,系统架构是怎样的?
回答思路:按硬件平台 → 软件架构 → 关键模块 → 难点解决 的顺序展开。
示例框架:
- 硬件:主控芯片型号、外设(传感器、通信模块、存储)
- 软件:裸机/RTOS、任务划分、驱动层/应用层分离
- 通信:内部总线(SPI/I2C/UART)、外部协议(MQTT/CAN/Modbus)
- 难点:实时性保证、低功耗设计、数据可靠性
重点说清楚你个人负责的部分,以及遇到的问题和解决方案。
2. 项目中遇到过最难的Bug是什么?怎么定位和解决的?
回答思路:选一个有代表性的,按 现象 → 排查过程 → 根因 → 解决方案 展开。
常见嵌入式疑难Bug类型:
- 内存越界/栈溢出导致随机崩溃
- 中断与主循环共享数据竞争
- 时序问题导致通信偶发失败
- 低功耗唤醒后外设状态异常
排查工具:JTAG/SWD调试器、逻辑分析仪、示波器、串口打印、看门狗复位日志。
关键点:体现系统性排查思路,而不是靠运气碰到答案。
3. ARM Cortex-M的异常/中断优先级机制是怎样的?
Cortex-M使用NVIC(嵌套向量中断控制器)管理中断:
- 优先级分为抢占优先级(Preempt Priority)和子优先级(Sub Priority)
- 抢占优先级高的中断可以打断正在执行的低优先级ISR(中断嵌套)
- 子优先级只在抢占优先级相同时决定响应顺序,不能嵌套
- 优先级数值越小,优先级越高
- 优先级分组由SCB->AIRCR寄存器的PRIGROUP字段控制
// STM32 HAL示例:配置优先级分组 HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); // 4位全用于抢占优先级 // 设置某中断优先级 HAL_NVIC_SetPriority(USART1_IRQn, 2, 0); // 抢占2,子优先级0 HAL_NVIC_EnableIRQ(USART1_IRQn);
FreeRTOS中:configMAX_SYSCALL_INTERRUPT_PRIORITY 以上的中断不受RTOS管理,不能调用FreeRTOS API。
4. 详细讲一下DMA的工作原理,项目中是如何使用DMA的?
DMA(Direct Memory Access)允许外设与内存之间直接传输数据,无需CPU参与,释放CPU处理其他任务。
工作原理:
- CPU配置DMA通道(源地址、目标地址、传输长度、触发源)
- 外设产生DMA请求信号
- DMA控制器仲裁后,总线控制权交给DMA
- DMA完成数据搬运,传输完成后触发中断通知CPU
三种传输模式:
- 普通模式:传输完成后停止
- 循环模式:自动重装,适合连续采样(ADC、音频)
- 乒乓模式:双缓冲交替,处理一个缓冲区时另一个继续接收
// UART DMA接收示例(STM32 HAL)
HAL_UART_Receive_DMA(&huart1, rx_buf, BUF_SIZE);
// DMA传输完成回调
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
// 处理rx_buf中的数据
process_data(rx_buf, BUF_SIZE);
}
5. Flash和RAM在嵌入式系统中分别存放什么?链接脚本是怎么工作的?
存储分布:
.text |
Flash |
代码段、常量、中断向量表 |
.rodata |
Flash |
只读数据(const变量、字符串字面量) |
.data |
Flash(初值) + RAM(运行) |
已初始化全局/静态变量 |
.bss |
RAM |
未初始化全局/静态变量(清零) |
Stack |
RAM |
函数调用栈 |
Heap |
RAM |
动态内存分配 |
链接脚本(.ld)的作用:
- 定义各段的起始地址和大小
- 指定.data段的加载地址(Flash)和运行地址(RAM)
- startup代码在main之前将.data从Flash复制到RAM,将.bss清零
MEMORY {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}
SECTIONS {
.text : { *(.text*) } > FLASH
.data : { *(.data*) } > RAM AT > FLASH /* 加载在Flash,运行在RAM */
.bss : { *(.bss*) } > RAM
}
6. I2C和SPI协议的底层时序有什么区别?各自适合什么场景?
I2C:
- 两线制(SCL时钟、SDA数据),半双工
- 支持多主多从,通过7/10位地址寻址
- 起始条件:SCL高时SDA下降沿;停止条件:SCL高时SDA上升沿
- 每字节传输后需要ACK应答位
- 速率:标准100kHz、快速400kHz、高速3.4MHz
- 适合:低速、短距离、多设备挂载(传感器、EEPROM)
SPI:
- 四线制(SCK、MOSI、MISO、CS),全双工
- 一主多从,通过片选CS区分从设备
- 无应答机制,无地址概念
- 速率可达几十MHz甚至更高
- 适合:高速、大数据量传输(Flash、显示屏、ADC)
I2C时序:START | ADDR(7bit) |
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。
