为什么这是量产面试的"必答题"
Bootloader 和 OTA,是嵌入式面试里区分度极高的考点。
原因很简单:从"会写 Bootloader"到"能设计量产级 OTA 方案",中间隔着几个数量级的工程复杂度。
会写 Bootloader 的人很多。跳转代码网上一搜就有,中断向量表重映射、MSP 设置、跳转函数,这几个步骤背下来就能写出来。
但能设计量产级 OTA 的人不多。因为量产 OTA 要解决的,不是"怎么跳转",而是"升级失败不变砖"。
面试官问 Bootloader 和 OTA,就是在判断你是"会写跳转代码"还是"能设计升级方案"。
这篇文章,我挑几个高频面试题,逐题拆解。
一、Bootloader 跳转:怎么从 Bootloader 跳到 App
面试题
Bootloader 怎么跳转到 App?
面试官在判断什么
你知不知道跳转的完整步骤
你知不知道为什么每一步都需要
你有没有踩过"跳转成功但 App 跑不起来"的坑
背过的答案
设置 MSP 为 App 起始地址的值,设置 VTOR 为 App 起始地址,然后跳到 App 的复位处理函数。
用过的答案
跳转分五步:
第一步,关闭所有中断。
__disable_irq()。因为 App 的中断向量表还没生效,如果此时有中断触发,会跳到 Bootloader 的处理函数。第二步,关闭 SysTick 和清除 NVIC。 SysTick 要关掉,所有挂起的中断标志要清除。否则跳转后可能有中断立即触发。
第三步,反初始化 HAL。 如果用了 HAL,
HAL_DeInit()把外设恢复到复位状态。第四步,设置 MSP 和 VTOR。 App 起始地址的前 4 个字节是初始栈顶指针,第 5-8 字节是复位处理函数地址。设置 MSP 为前 4 字节的值,设置 VTOR 为 App 起始地址。
第五步,跳转到复位处理函数。
看起来简单,但有两个容易忽略的点:
第一,中断优先级分组。 如果 Bootloader 设置了中断优先级分组(比如
HAL_NVIC_SetPriorityGrouping),App 可能假设了不同的分组。跳转前应该把中断优先级分组恢复为默认值。第二,跳转失败的处理。 如果跳转后 App 立即 HardFault,系统会卡死。健壮的做法是:跳转前在某个 RAM 地址写入"跳转标志",App 启动后清除。如果 Bootloader 复位后发现标志还在,说明上次跳转失败,进入恢复模式。
我在项目里踩过一个坑:跳转代码看起来没问题,但 App 一运行就 HardFault。
排查发现,App 编译时的链接地址还是默认的
0x08000000,没有改成0x08008000。即使把它烧到0x08008000,内部所有绝对地址引用都指向0x08000000附近。跳转本身是成功的,但 App 一开始执行就访问了错误的地址。这个坑的教训是:Bootloader 和 App 的