联芸科技嵌入式软件一面:启动方式与 SPI/IIC/串口区别
- 轮次
- 一面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 编译烧录程序后,程序是从哪块启动的?Boot0、Boot1 分别对应什么启动方式与启动位置?
- 项目里被管理的这些中断是单核的还是多核的?
- 调试时为什么选择单步断点?如果是不熟悉的项目,单步调试效率很低,可以用什么方式?
- SPI、IIC、串口有什么区别?
- 围绕项目深挖:说到 PID 时反复追问「灵敏度」——PID 里的灵敏度指什么,怎么衡量和调整?
- 自我介绍 + 项目介绍。
《参考解析》
启动方式:引脚采样决定复位后的取指地址
STM32 这类 MCU 在复位时(SYSCLK 的第 4 个上升沿前后)会采样 BOOT1、BOOT0 引脚,把结果锁存进启动模式寄存器,决定地址 0x0000_0000 被映射到哪块存储器:
- BOOT0 = 0:主 Flash(
0x0800_0000区),跑用户程序,量产后就是这个状态; - BOOT0 = 1、BOOT1 = 0:系统存储器(System memory),里面是原厂固化的 Bootloader,支持 USART / CAN / USB DFU 之类的 ISP 下载;
- BOOT0 = 1、BOOT1 = 1:内嵌 SRAM,用于调试或极小体积的程序。
完整链条是「引脚采样 → 存储区映射 → 从该区首 4 字节取 MSP 初值、第 4~8 字节取复位向量 → 跳 Reset_Handler」。如果项目里做过 IAP,还要补一句:跳转前关中断、复位外设、把 SCB->VTOR 改成新程序的向量表偏移,否则中断会跳回老固件。面试官问这题通常是想确认你有没有真的从手册里读过启动流程,而不是只背了三种模式的名字。
中断是单核还是多核:先看中断控制器,再看亲和性
Cortex-M 的中断由 NVIC 统一管理,本身就是核内的,多核 MCU(比如双核 M4+M0、M7+M4)一般是每个核各有一个 NVIC,跨核唤醒要用 IPI(核间中断)、硬件信号量或 mailbox,共享外设的中断只能挂到其中一个核上,另一个核要通过消息/共享内存拿数据。Cortex-A 则走 GIC:Distributor 负责分发,Redistributor / CPU Interface 负责投递给具体核,中断分 SGI(软件生成,核间)、PPI(每核私有,如本地定时器)和 SPI(共享外设中断,可配亲和性)。所以回答时要落到「这颗芯片的中断控制器是什么、共享中断的亲和性怎么配、跨核怎么同步」这三点上。RTOS 侧同理:FreeRTOS 的 AMP 方案每个核跑一份独立的调度器,SMP 方案共用一个就绪队列但每个核有自己的 idle 任务,临界区要么关本核中断(BASEPRI)要么配自旋锁。
不熟悉的项目怎么高效调试:单步之外还有很多手段
单步断点适合逻辑清晰的小范围定位,代码量大、时序敏感的场合它反而是最慢的。更高效的路子:
- 先二分缩小范围:用宏开关或注释把模块砍掉一半,看现象是否还在,几轮就能锁定到函数级;
- 打日志:把
printf重定向到 SWO/ITM(不占串口、不阻塞太久),或者在中断里只往环形缓冲写、退出中断后再输出;中断里直接串口打印很容易拖垮时序; - 数据断点 / 观察点(watchpoint):变量被谁改了一看就知道,比从头单步快一个数量级;配合条件断点
if (idx == 37)定位偶发问题; - RTOS 感知调试:FreeRTOS 的调试插件能直接看每个任务的状态、栈水位、阻塞在哪个对象上;
- 示波器 / 逻辑分析仪:SPI、IIC、UART、CAN 的时序问题,波形一眼就能看出片选、ACK、采样点是否正常;
- 故障现场:HardFault 时打印
CFSR、HFSR、BFAR和异常栈帧里的 PC/LR,再用arm-none-eabi-addr2line映射回源码行; - 主机侧能跑的部分用
-fsanitize=address、valgrind、静态检查工具先清一遍。
SPI / IIC / 串口的区别
| 维度 | SPI | IIC | UART |
|---|---|---|---|
| 线数 | 4 线:SCLK / MOSI / MISO / CS(可多 CS) | 2 线:SCL / SDA,开漏需上拉 | 2 线:TX / RX,交叉连接 |
| 同步方式 | 同步(有时钟线) | 同步(有时钟线) | 异步,靠双方约定波特率 |
| 拓扑与寻址 | 一主多从,片选选通,无地址 | 多主多从,7/10 位地址,支持总线仲裁 | 点对点(RS485 可挂总线) |
| 速率 | 常见几 MHz ~ 几十 MHz | 100k / 400k / 3.4M | 115200 ~ 几 Mbps |
| 双工 | 全双工 | 半双工 | 全双工 |
| 协议开销 | 无 ACK、无帧头帧尾,最省 | 每字节一个 ACK,有起始/停止/重复起始 | 每字节约 10 bit(起始+数据+校验+停止) |
| 典型场景 | Flash、屏幕、ADC、无线模组 | EEPROM、传感器、PMIC、RTC | 调试口、4G/BT 模组、GPS |
一句话总结区别:SPI 靠片选、IIC 靠地址、串口靠约定波特率。再补一句坑:IIC 的 SDA/SCL 必须上拉,总线电容和上拉阻值决定波形上升沿;SPI 高速时要注意走线长度和采样边沿(CPOL/CPHA 四种模式)。
PID 的「灵敏度」到底在问什么
这题大概率是双方对术语理解不一致。可以顺着两条线答,并主动澄清:
- 如果是参数灵敏度:
Kp越大,误差一出现输出就冲得越猛,对被控量变化更敏感,但容易超调和振荡,太小则响应迟缓、静差大;Ki决定消除稳态误差的快慢,太大会积分饱和,需要做抗饱和(输出限幅 + 积分钳位或 back-calculation);Kd对误差变化率敏感,能增加阻尼、压超调,但对采样噪声极其敏感,实际要串低通滤波。 - 如果是被控对象灵敏度:那是输出变化量对输入变化量的比值,可以用开环阶跃测出来——加 5% 的阶跃,看稳态输出变化多少,估出一阶增益和时间常数,再据此整定。
- 诚实说法比硬答更好:「我没听过 PID 里叫灵敏度的说法,我理解您想问的是参数对误差的响应强度 / 被控对象的敏感度,我说一下我的理解」。面试里的定义澄清不算扣分,答偏方向才扣分。
项目深挖与自我介绍(放在最后)
项目讲述按「需求 → 我的模块边界 → 关键设计取舍 → 联调过程 → 可量化结果」组织,主动交代芯片型号、RTOS、通信用了哪些协议。面试官顺着 PID 追问时,重点不是背公式,而是说清当时怎么整定、采样周期多少、超调多少、遇到振荡怎么改的——有具体数字的复盘最能建立信任。