欣旺达 嵌入式软件工程师 二面 面经

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处理其他任务。

工作原理:

  1. CPU配置DMA通道(源地址、目标地址、传输长度、触发源)
  2. 外设产生DMA请求信号
  3. DMA控制器仲裁后,总线控制权交给DMA
  4. 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编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。

全部评论

相关推荐

03-30 00:09
吉林大学 C++
点赞 评论 收藏
分享
林后润:听说他们有kpi,要到了简历编号就不理人了
27届求职交流
点赞 评论 收藏
分享
评论
2
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务