ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

面试高频考点 02:看门狗 / 启动模式 / 复位 / Bootloader 面试要点

面试高频考点 02:看门狗 / 启动模式 / 复位 / Bootloader 面试要点 适用人群和我一样正在准备 2026 秋招的嵌入式方向同学——前几篇专栏把看门狗、启动流程、OTA 都讲过基础了但面试官一追问你项目里看门狗怎么用的、“复位和上电有啥区别”、“Bootloader 跳转前要做什么”还是容易卡壳读完你能得到① 把看门狗/复位/Boot/Bootloader 四块串成一条面试答线② 知道每块的标准答法怎么答才不像背书③ 把前面核心概念_03/05、OTA_02/04、低功耗_03里讲过的东西拧成面试视角而不是再讲一遍原理这一篇是 “面试高频考点” 专栏的第 2 篇紧接面试_01的下一篇指向。技术细节我不重复全文只点一句详见 XXX重点放在为什么这么问、坑在哪、怎么答得让面试官觉得你是真踩过。一、看门狗面试要点呼应 核心概念_05 低功耗_03IWDG/WWDG 的完整原理见嵌入式核心概念/核心概念_05_看门狗详解.mdIWDG 在低功耗里的影响见低功耗与电源管理/低功耗_03_实测功耗测量与电源树选型.md。这里只讲面试视角。1.1 IWDG vs WWDG——别只会背一个独立一个窗口面试官最爱开的场“说一下 IWDG 和 WWDG 的区别。”——背书答法是一个独立一个窗口到此为止。懂了的答法是把这张表甩出来 主动补一句所以我项目里用的是 IWDG因为……对比项IWDG独立看门狗WWDG窗口看门狗时钟源LSI独立低速 RCF4 约 32 kHz精度差17~47 kHzAPB1依赖主时钟精度高主时钟挂了仍工作这就是独立的含义也挂它靠 APB1喂狗时机超时前任意时刻喂都行必须在窗口内喂喂早了也复位最大超时F4 约32.8 sLSI 32k、PR256、RLR4095短得多ms 级APB1/4096/8 量级检测什么死机、跑飞死机 跑太快程序跑飞可能跑得反而快典型场景通用防死机安全关键必加严格时序监控、关键控制回路⚠️ 最大超时这条新手最容易答错。F407 的 IWDG 最长约32.8 s不是几秒这个数字在低功耗_03里我亲手算过4096 × 256 ÷ 32000 ≈ 32.8 s。但 LSI 精度差实际可能只有 20 多秒——这也是为什么想睡 10 分钟会被狗咬醒。1.2 IWDG 在 Stop/Standby 里继续计数吗——高频追问继续。这条低功耗_03已经踩过坑了这里再强调一遍因为面试官特别爱追问这一句来筛做过和背过的IWDG 由LSI驱动进 Stop 模式后LSI 不停、IWDG 继续计数。进 Standby 模式IWDG也继续只要 LSI 还在IWDG 就停不下来除非整个掉电。软件启动 IWDG 后关不掉只能复位才能停这是硬件设计——防止程序跑飞误关狗。⚠️ 这就是低功耗_03那句别为了’更安全’随手开一个把设备反复重启的看门狗的来历。长睡场景比如 10 分钟醒一次采个温开了 IWDG30 秒就被复位一次设备永远在睡→被狗咬醒→重启→睡→再被咬根本跑不到你要的周期。长周期睡眠要么别开 IWDG改用 RTC 唤醒 软件状态自检要么把一次长睡切成若干段 20 s 的短睡每段醒来喂一次狗再继续睡。1.3 为什么不能为了安全随手开 IWDG——这条面试直接给加分接上一条面试官追问那是不是所有项目都该开 IWDG别答是。正确答法“不是。IWDG 是最后防线不是越多越好。我做过一个低功耗气象节点10 分钟醒一次如果开了 IWDG30 秒就被复位一次根本睡不到 10 分钟。所以我那个项目没用 IWDG改用 RTC 定时唤醒 主循环里做’上次采样时间戳’自检——如果距上次采样超过 15 分钟还没采说明卡住了主动NVIC_SystemReset()。安全不是只有看门狗一条路关键是’死机了能不能恢复’RTC 软件自检在低功耗场景比 IWDG 更合适。”这段话一出口面试官立刻知道① 你真做过低功耗② 你被 IWDG 咬过③ 你知道安全不是教条。比项目必加 IWDG高级多了。1.4 喂狗放哪——主循环 / 单独任务别放 ISR这是面试官筛写过裸机 vs 写过 RTOS的分水题。裸机喂狗放主循环每轮喂一次。/* 平台STM32 裸机IWDG 超时 1 s */intmain(void){HAL_Init();SystemClock_Config();MX_IWDG_Init();/* PR64, RLR625 → 约 1 s */for(;;){read_sensor();process_data();HAL_IWDG_Refresh(hiwdg);/* 每轮喂一次 */}}RTOSFreeRTOS用专门的监控任务喂狗其他任务用标志位通知我还活着——只有所有关键任务都活着才喂。核心概念_05有完整代码这里不重复。绝对不能放 ISR主程序死循环了但定时器中断还在跑结果狗永远被中断喂着看门狗永远不触发复位——等于没装。这是新手最常犯的错核心概念_05坑 2 讲过。⚠️ RTOS 里的进阶做法监控任务用task_alive[]数组其他任务定期置位自己的活着标志监控任务全部活着才喂。这样单任务死掉也能复位。这条答出来面试官就知道你不止写过裸机喂狗。1.5 “你项目里看门狗怎么用的”——标准答法模板这道题几乎必问别只说我开了 IWDG。完整答法四段场景什么项目、为什么必须加安全关键远程无人值守。选型IWDG 还是 WWDG为什么绝大多数学生项目 IWDG 就够。参数超时多少、为什么这个值要 主循环最坏执行时间留余量。喂狗策略裸机主循环喂 / RTOS 监控任务条件喂。我的标准答法你可以照着改你自己的项目“我做个多士炉控制继电器加热那种——程序死机继电器会一直闭合有火灾风险所以第一件事就是加 IWDG。选 IWDG 不选 WWDG因为我要的是’死机了能断电’不需要严格时序监控。超时设 1 s主循环最坏一圈约 200 ms留了 5 倍余量。喂狗放主循环每轮喂一次裸机工程没上 RTOS。死机后最多 1 s 自动复位断电人感觉不到但火没起来。”四段都有有数字、有余量理由、有安全结论——这就是踩过坑的味儿。二、复位类型Reset别只会说上电复位启动流程的硬件动作见嵌入式核心概念/核心概念_03_启动流程详解.md这里讲复位这个动作本身有几种类别。2.1 STM32 的复位家族——一张图先看清┌─── 上电复位 POR ─────────┐ │ │ 外部电源刚上 ───────►│ (VDD 从 0 升到阈值) │──► 整片复位 │ 掉电复位 PDR │ │ (VDD 跌到阈值以下) │ └──────────────────────────┘ 外部 NRST 引脚 ─────► NRST 复位 (手动按键 / 外部复位芯片) WWDG 超时 ───────────► 窗口看门狗复位 IWDG 超时 ───────────► 独立看门狗复位 软件 NVIC_SystemReset() ──► 软件复位 Stop/Standby 唤醒 ────► 部分外设复位 内核复位(Standby 等同复位)这么多复位类型核心区别就一句话“哪些东西被清零了”。复位类型内核寄存器SRAM时钟标志位RCC_CSRPOR/PDR复位复位清零复位RCC_FLAG_PORRSTBOR欠压复位复位清零复位RCC_FLAG_BORRSTNRST复位复位保留复位RCC_FLAG_PINRSTIWDG 复位复位复位保留复位RCC_FLAG_IWDGRSTWWDG 复位复位复位保留复位RCC_FLAG_WWDGRST软件复位复位复位保留复位RCC_FLAG_SFTRSTStop 唤醒仅内核部分外设保留按需恢复RCC_FLAG_LPWRRSTStandby 唤醒复位复位清空复位查PWR_CSR的 WUF非 RCC_CSR 复位标志⚠️关键认知只有 POR/PDR/BOR 和 Standby 唤醒会清空 SRAM其它复位 SRAM 内容保留除非启动代码主动清。这就是为什么核心概念_03里启动文件要清零 .bss——硬件不一定帮你清得软件兜底。新手最常以为复位 全清零这是错的。Standby 唤醒比较特殊它走的是唤醒事件而非复位事件所以要查PWR_CSR的 WUF 标志位而不是RCC_CSR。2.2 RCC_CSR——判断这次为什么复位的RCC_CSRClock Control Status Register是 STM32 复位原因的案发现场。每种复位发生时硬件会在 CSR 里置一个对应标志位软件上电后读它就知道这次是被谁弄醒的。/* 平台STM32F4HAL 库 */voidcheck_reset_reason(void){/* 注意顺序PINRST 在几乎所有复位时都会被置位必须放最后兜底 先查具体原因 POR/BOR/IWDG/WWDG/SFTRST再查 PINRST */if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST)){printf(上电/掉电复位 POR/PDR\r\n);}elseif(__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST)){printf(欠压复位 BOR\r\n);}elseif(__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)){printf(独立看门狗复位——上次可能死机了\r\n);}elseif(__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST)){printf(窗口看门狗复位\r\n);}elseif(__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST)){printf(软件复位 NVIC_SystemReset()\r\n);}elseif(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST)){printf(外部 NRST 引脚复位\r\n);}/* 读完后必须清标志否则下次复位原因会叠加读错 */__HAL_RCC_CLEAR_RESET_FLAGS();}⚠️ 顺序很重要PINRST 标志在几乎所有复位时都会被置位NRST 引脚在每次复位时都会动作这是 ST 的设计。所以判断必须先查 PORRST/BORRST/IWDGRST/WWDGRST/SFTRST 这些具体原因把 PINRST 留到最后兜底——不然你按 IWDG 复位时可能 PINRST 也是 1逻辑就乱了。经验做法读完后立刻__HAL_RCC_CLEAR_RESET_FLAGS()下次复位原因才干净。2.3 软件复位NVIC_SystemReset()——什么场景用#includestm32f4xx.h/* 设备头文件会间接 include CMSIS 的 core_cm4.h *//* 收到升级指令 / 自检失败 / OTA 完成 */NVIC_SystemReset();/* 这一行执行后内核立刻复位不会返回 */NVIC_SystemReset()本质是写SCB-AIRCR寄存器的SYSRESETREQ位触发一次系统复位。它不清 SRAM——所以OTA_02里 Bootloader 收完固件NVIC_SystemReset()重启再检查 app 合法性这个流程是成立的SRAM 里的升级标志还在。典型场景OTA 写完 Flash 后重启进新固件、自检发现硬件异常主动重启、配置变更需要重新初始化。别滥用——程序 bug 导致死机用软件复位掩盖问题没解决只是被刷过去了。2.4 “复位和上电的区别”——标准答法这是送分题但答得不全还是露怯。完整答法三层触发方式上电复位是 VDD 从 0 升到阈值硬件自动复位是 NRST 引脚被拉低或软件触发可主动。作用范围上电复位清空 SRAM一切从零开始普通复位NRST/IWDG/软件保留 SRAM只复位内核和外设寄存器。判别方式上电后读RCC_CSR的PORRST标志位区分这次是真上电还是复位。⚠️ 加分句“所以很多 Bootloader 用’上电标志 备份寄存器’判断是冷启动还是热复位”——冷启动要重新初始化一切热复位可以保留上次状态。这句话一出面试官就知道你写过 Bootloader。三、启动模式与 Boot 引脚呼应 核心概念_03启动流程的代码视角见嵌入式核心概念/核心概念_03_启动流程详解.md这里讲上电后从哪儿开始取指。3.1 BOOT0 / BOOT1——决定从哪儿启动STM32 上电时CPU 从哪个地址取第一条指令不是固定 0x08000000而是由 BOOT0 / BOOT1 引脚的电平决定F1 系列F4 简化为只有 BOOT0BOOT1BOOT0启动区域里面是什么x0Flash0x08000000你烧的业务代码01System Memory0x1FFF0000ST 出厂的 ISP Bootloader串口/USB 下载就靠它11SRAM0x20000000调试用掉电即失⚠️关键认知BOOT0/BOOT1 在复位那一刻被采样复位后改电平没用——必须重新复位才生效。所以用跳线切启动模式的流程是①改跳线②按一次复位键③开始下载。3.2 System Memory 里的 ISP Bootloader——别和你自己写的 Bootloader 混淆这是新手最容易混淆的点面试官特别爱用这道题筛人System Memory 里那个 Bootloader 是 ST 出厂烧死的你不能改、也读不出源码。它支持的协议串口/USB/I2C/SPI和命令是固定的详见 ST 应用笔记 AN2606。你用 FlyMcu / STM32 Flasher 串口下载走的就是它。而OTA_02里我们写的 Bootloader是你自己的代码烧在 Flash 起始 0x08000000支持你自定义的协议帧能和你的 App 共存。这是两个完全不同的东西。一句话区分┌─────────────────────────────────┬─────────────────────────────────┐ │ System Memory Bootloader │ 你自己写的 Bootloader │ │ (ST 出厂, 0x1FFF0000) │ (你的代码, 0x08000000) │ ├─────────────────────────────────┼─────────────────────────────────┤ │ BOOT01 才启动 │ BOOT00 默认就启动 │ │ 只能串口/USB 下载不能跑业务 │ 能跑业务、能收 OTA、能跳 App │ │ ST 写死改不了 │ 你随便改 │ │ 量产烧录用 │ 量产远程升级用 │ └─────────────────────────────────┴─────────────────────────────────┘⚠️ 这道题答错比如System Memory 里是我写的 Bootloader基本就凉了——面试官立刻知道你没真做过 OTA。System Memory 是 ST 的0x08000000 起才是你的。3.3 中断向量表重定位SCB-VTOR——Bootloader 跳转的灵魂核心概念_03讲过CPU 上电时硬件从 Flash 起始读 MSP 和 Reset_Handler。但当 App 不在 0x08000000比如OTA_02里 App 在 0x08010000中断来了 CPU 默认还去 0x08000000 找向量表——那是 Bootloader 的向量表App 的中断全跑飞。SCB-VTORVector Table Offset Register就是解决这个的告诉 CPU向量表现在搬去这个地址了。/* App 工程的 main() 开头第一行 */SCB-VTORFLASH_BASE0x10000;/* 0x08010000App 向量表所在 */__DSB();/* 数据同步屏障确保新 VTOR 对后续取指可见 */⚠️ VTOR 重定位的地址必须按向量表大小对齐最低若干位为 0。F4 向量表约 0x188 字节所以地址至少 0x200 对齐用 0x08010000 这种 64KB 对齐地址肯定没问题。对齐错了一开中断就 HardFault。CubeMX 工程可以在system_stm32f4xx.c改VECT_TAB_OFFSET宏省得手写——本质一样都是设 VTOR。四、Bootloader 面试要点呼应 OTA_02~04完整的 Bootloader 实现见固件升级与OTA/OTA_STM32自己写Bootloader从0实现串口升级.md安全启动见OTA_04这里讲面试视角。4.1 为什么要 Bootloader——别只答为了升级面试官问为什么要写 Bootloader背书答法是为了升级——太浅。懂了的答法是三段远程升级设备装在野外/机房/客户家里不能拆壳用 JTAG 烧必须能自己收固件、自己刷。分区与回滚升级有可能失败/新固件有 bug所以常做 A/B 双分区——升级时刷备用区启动时校验新固件跑起来失败自动回滚到旧区。OTA_02是单 App 校验失败停留 Bootloader 的简化版A/B 是量产标配。安全启动Bootloader 是信任链的stage-1负责校验 App 签名OTA_04拒绝非法固件。没有 Bootloader 这一层签名校验就无处可放。⚠️ 加分句“ESP32 的 OTA 是乐鑫在 SDK 里给你做好的STM32 没有现成的得自己写——这也是为什么 STM32 的 Bootloader 是嵌入式面试的高频题。”这一句区分了用过现成方案和理解底层面试官立刻高看你一眼。4.2 Bootloader 与 App 的分区与跳转——核心代码必须默写出来分区OTA_02的 STM32F407 例子0x08000000 ┌──────────────────────┐ │ Bootloader (64KB) │ ← 复位入口BOOT00 默认进这 0x08010000 ├──────────────────────┤ │ App (~960KB) │ ← 你的业务代码 │ 向量表在最前面 │ └──────────────────────┘ 0x080FFFFF跳转流程——这道题面试官可能让你白板写必须默得出/* 平台STM32F4CMSIS */typedefvoid(*app_entry_t)(void);voidjump_to_app(uint32_tapp_addr){uint32_tsp*(volatileuint32_t*)app_addr;/* 向量表[0] MSP */uint32_tpc*(volatileuint32_t*)(app_addr4);/* 向量表[1] Reset_Handler */__disable_irq();/* ① 关全局中断 *//* ② 清掉 Bootloader 侧所有 NVIC 使能与挂起 */for(inti0;i8;i){NVIC-ICER[i]0xFFFFFFFF;/* 清使能 */NVIC-ICPR[i]0xFFFFFFFF;/* 清挂起 */}SysTick-CTRL0;/* 关 SysTick否则 App 接管前可能进滴答中断 */SCB-VTORapp_addr;/* ③ 向量表切到 App */__DSB();__ISB();/* 屏障确保新 VTOR 对取指可见 */__set_MSP(sp);/* ④ 设 MSP 为 App 的栈顶 */__enable_irq();/* ⑤ 恢复全局中断App 默认期望 PRIMASK0 */app_entry_tentry(app_entry_t)(pc|0x1);/* Thumb 状态最低位1 */entry();/* ⑥ 跳相当于手动复位进 App */}记忆口诀关中断 → 清 NVIC/SysTick → 改 VTOR带屏障→ 设 MSP → 开中断 → 跳。⚠️ 三个最容易漏的点OTA_02里都踩过①清 NVIC——不清的话 Bootloader 里的挂起中断会在 App 的向量表里找入口跑飞②__DSB();__ISB();屏障——改完 VTOR 立刻跳没屏障的话 CPU 流水线可能还用旧地址③__enable_irq()恢复中断——很多人__disable_irq()后忘了恢复App 的中断全被屏蔽裸机工程会假死。漏任何一条都可能 HardFault 或假死。4.3 版本号防回滚——OTA_04/OTA_05的核心面试必问“签名能防伪造但能不能防降级”——能但要靠版本号 单调计数器。固件头里嵌一个单调递增的版本号如 uint32_t fw_version 7 │ ▼ 设备用 eFuse / 备份寄存器 / Flash 末页存已接受的最高版本 max_seen │ ▼ 启动时检查fw_version max_seen ? 是 → 接受更新 max_seen fw_version 否 → 拒绝防回滚为什么必须防回滚攻击者拿你去年有漏洞的旧固件合法签名刷进设备设备照样认——漏洞被复活。所以签名只证明是你签的不证明是最新的。⚠️ 存最高版本的位置很关键放普通 Flash 可被攻击者改回去写成 0 就能装任何旧版正确做法是放 eFuse / OTP一次性烧写烧死改不了。STM32 没有 eFuse但有OTP 区F4 是 16 字节起可以用来存版本计数器。这条答出来是高级加分。4.4 安全启动签名校验——OTA_04的精华一句带过签名验签的完整流程见OTA_04面试一句话版“构建时用私钥对固件哈希签名设备用烧死在eFuse/OTP里的公钥验签验不过就停在 Bootloader 不跳 App。三个关键点① 公钥必须锁死在 OTP不能放普通 Flash否则攻击者可换公钥恶意固件② 验签失败必须硬拒绝不能只警告③ 签名之外还要防回滚嵌版本号 单调计数器。”4.5 Bootloader 自己怎么升级——鸡生蛋问题这是 Bootloader 面试的最难一问能答出来基本就是高级岗的水平。问题App 能被 Bootloader 升级那 Bootloader 自己想升级怎么办Bootloader 不能自己擦自己擦完跑飞。三种答法方案做法适用A/B BootloaderFlash 起始放两份 Bootloader升级时擦备用那份、写新的、置启动选哪份标志、重启切到新的量产、空间够RAM 跳转法Bootloader 把新 Bootloader 代码先整体读到 SRAM跳到 SRAM 执行SRAM 里的代码擦 Flash 的 Bootloader 区、写新版本、重启空间紧张、SRAM 够大不支持升级出厂烧死后永不变动靠 App 的可升级性兜底大多数学生项目 / 低端产品⚠️ 大多数学生项目答不支持升级Bootloader 出厂烧死就够——别硬答 A/B面试官追问细节你答不上来反而露怯。诚实说我项目里 Bootloader 不升级只升 AppBootloader 出厂烧死靠 RDP 读保护防止被读出——这个答法比硬装懂强 10 倍。五、新手必踩的 N 个坑这一栏把看门狗、复位、Boot、Bootloader 四块里面试官最爱追问、新手最常翻车的坑汇总成一张表。每条都对应前面某篇的详细分析这里给面试一句话版。#坑后果正确做法详见1IWDG 超时算错把 LSI 当精确时钟LSI 精度 17~47 kHz理论 1 s 实际可能 0.5 s 或 1.5 s喂狗间隔算错就反复复位留 2~3 倍余量别在需要精确超时的场景用 IWDG核心概念_05 §2.2 / 低功耗_03 §132低功耗场景随手开 IWDGStop 模式 IWDG 继续计数10 分钟长睡被 30 s 复位一次长周期睡眠改用 RTC 唤醒 软件自检要开 IWDG 就把长睡切成 20 s 短睡分段喂狗低功耗_03 §133Bootloader 跳转前忘关中断旧向量表生效期间被中断触发跑飞 HardFaultjump_to_app第一行__disable_irq()清 NVIC 关 SysTick 再切 VTOROTA_02 §4.24App 没设 VTOR一开中断就 HardFaultCPU 还去 0x08000000 找向量表Appmain()第一行SCB-VTOR APP_ADDR地址须按向量表大小对齐OTA_02 §55App 链接地址没改Bootloader 和 App 重叠互烧互覆盖.ld里 FLASH ORIGIN 改成0x08010000LENGTH 减 0x10000OTA_02 §56BOOT 引脚悬空上电随机电平可能误进 System Memory / SRAM 模式烧不进 FlashBOOT0 必须接下拉或上拉到 VDD 取决于设计别悬空数据手册明确要求RM0090 Boot pins7混淆 System Memory Bootloader 和自己写的 Bootloader面试答错基本凉——面试官判定你没做过 OTASystem Memory ST 出厂 ISPBOOT01 进0x1FFF0000你写的 Bootloader 烧在 0x08000000 的业务代码BOOT00 进本文 §3.28跳转前没校验栈顶App 向量表损坏跳过去直接死循环或跑飞跳前必做app_is_valid栈顶在 SRAM 范围、复位向量在 Flash 范围且 Thumb 位置 1OTA_02 §4.19__disable_irq()后忘__enable_irq()恢复App 中断全被屏蔽裸机工程假死跳转流程末尾恢复__enable_irq()App 默认期望 PRIMASK0OTA_02 §4.210只签名不防回滚攻击者用合法签名的旧漏洞固件刷入签名形同虚设固件嵌单调版本号设备用 OTP/eFuse 存最高已接受版本更低的一律拒OTA_04 §8 坑6 这张表不是用来背的是用来对号入座的。秋招前过一遍每条对照你简历项目问自己我能不能讲出具体场景——能讲出 3 条以上这四块面试基本稳了。六、动手练一练光看不练面试时还是嘴卡。下面这几个练习建议你用开发板真跑一遍别用正在用的项目板故意搞破坏用。练习 1故意跳转前不关中断看 HardFault复用OTA_02的 Bootloader App 工程把jump_to_app里的__disable_irq()和清 NVIC/SysTick那几行注释掉其它不变。voidjump_to_app(uint32_tapp_addr){/* __disable_irq(); ← 故意注释掉 *//* for(...) NVIC-ICER... ← 故意注释掉 *//* SysTick-CTRL 0; ← 故意注释掉 */SCB-VTORapp_addr;__set_MSP(*(uint32_t*)app_addr);/* __enable_irq(); ← 也注释掉 */app_entry_tentry(app_entry_t)(*(uint32_t*)(app_addr4)|0x1);entry();}步骤编译烧录看现象——大概率跳过去几条指令就 HardFault因为 Bootloader 里挂起的 SysTick 中断在 App 的向量表里找入口找到了不对的地址。用调试器在 HardFault_Handler 打断点看压栈的 PC 指向哪里理解为什么没关中断会跑飞。把注释取消恢复正常再跑——对比现象。加分只注释SysTick-CTRL 0一行看 SysTick 中断在 App 接管前触发的具体后果——这条更隐蔽很多新手栽在这。做完这个面试官问跳转前为什么必须关中断你能说我亲手试过不关会 HardFault原因是挂起的中断在新向量表里找错入口——比任何博客都有说服力。练习 2故意不设 VTOR看 App 中断跑飞复用上面的工程这次 Bootloader 跳转写对但把 App 里的SCB-VTOR那行注释掉/* App 的 main() 第一行 */intmain(void){/* SCB-VTOR FLASH_BASE 0x10000; ← 故意注释掉 */HAL_Init();SystemClock_Config();/* ... 后面开了 USART1 接收中断 ... */}步骤烧 Bootloader 烧 App启动后 Bootloader 跳到 App。App 主循环里点个 LED能跑——说明不设 VTOR 主循环也能跑。关键从串口发一个字节触发 USART1 接收中断——立刻 HardFault。因为 CPU 还去 0x08000000Bootloader 的向量表找 USART1 入口跳到 Bootloader 的 USART1_Handler可能就是空的死循环现场错乱。取消注释设回 VTOR再试——中断正常进。这个练习做完App 为什么必须设 VTOR就不再是博客上的话是你亲手验证过的事实。练习 3读 RCC_CSR 看复位原因/* 平台STM32F4 */voidcheck_reset_reason(void);/* 见本文 §2.2 的完整实现 */intmain(void){HAL_Init();uart_init();/* 用于 printf */printf( 启动 \r\n);check_reset_reason();while(1){/* ... */}}步骤烧录后第一次上电拔插 USB看串口输出——应该是上电/掉电复位 POR/PDR。按板子上的 RESET 键不动电源看输出——应该是外部 NRST 引脚复位。故意写一个死循环让 IWDG 复位比如while(1);不喂狗看输出——应该是独立看门狗复位——上次可能死机了。注意每次读完后必须__HAL_RCC_CLEAR_RESET_FLAGS()否则下次会叠加。做完这个面试问怎么判断这次为什么复位你能直接说读 RCC_CSR 的标志位PORRST/PINRST/IWDGRST/SFTRST 分别对应上电/NRST/看门狗/软件复位——又是真数据。练习 4算一下你板子的 IWDG 最大超时拿你手头 STM32 的数据手册查 LSI 频率F4 标称 32 kHz范围 17~47 kHz按公式T_max 4 × 2^(PR2) × (RLR1) / f_LSIPR 取最大 6、RLR 取最大 4095算出理论最大超时和最坏情况超时用 LSI 下限 17 kHz。F407 答案理论约 32.8 s最坏约 17 s。差距接近一倍——这就是为什么留余量不是口号是 LSI 精度逼出来的。算完这个面试问IWDG 超时怎么算、LSI 精度对它有什么影响你张口就能答。小结把四块拧成一条面试答线这一篇不是新知识是收口复习——把看门狗、复位、Boot、Bootloader 四块以前讲过基础的东西重新组织成面试答线。秋招前我用它的方式是每块都对照简历项目想一个标准答法。比如被问看门狗我不只说IWDG 防死机而是我多士炉项目里 IWDG 超时 1 s、主循环喂狗、留 5 倍余量因为继电器死机会火灾——把简历项目和八股绑死。第五节那张坑表当 checklist。每条问自己我踩过没能讲出具体场景吗——能讲出 3 条以上这四块面试基本稳了。动手练习至少做完练习 1 和 2。那两个故意搞破坏的练习做完你面试时说我亲手试过不关中断会 HardFault、“我试过不设 VTOR 一开中断就崩”——这种话一出口面试官就知道你不是背书的。最后送一句我自己最深的体会这四块技术本身不难难的是答得让面试官觉得你做过。同样一句跳转前要关中断背出来和讲出来是两个味儿——区别就在于你有没有亲手试过不关会怎样。前面 OTA 五篇我都写过、踩过这一篇就是把它们拧成一根面试答线希望对你秋招有用。文中的 RM0090 复位/启动章节、AN2606/AN4657 和 ARMv7-M SCB 内容都对照了 ST 和 ARM 官方文档想深挖的按章节号去翻。下一篇面试_03_嵌入式面试全真模拟与简历项目讲法
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表