云鲸智能嵌入式软件开发二面面经(项目拷打)
- 轮次
- 二面
- 时间
- 2026-09
- 来源
- 牛客网
《面试题目》
- 介绍一下你这个 STM32H747 车载中控双核项目,CM7 和 CM4 各自负责什么?
- 为什么把 CAN 放在 CM4,而不是直接在 CM7 收?
- OpenAMP/RPMsg 这条链路你怎么保证不被 UI 饿死?
- HSEM 在你们双核启动里具体起什么作用?
- 你的 FreeRTOS 任务是怎么划分的?OTA 时为什么有的任务要挂起、有的不能挂?
- 双槽 OTA 的镜像、校验和生效流程是怎么做的?
- 如果 CAN 报文丢失或延迟,你会怎么定位是总线问题还是核间通信问题?
《参考解析》
-
双核职责划分:CM7 做主核,负责时钟与外存初始化、LVGL 仪表 UI、以太网与 LwIP、HTTP OTA、DoIP 诊断网关以及 OpenAMP Master;CM4 做从核,负责 FDCAN 实际总线收发,通过 OpenAMP 把 CAN 帧转给 CM7,并维护本地 CAN 心跳。这样拆的目的是把实时总线侧和 UI/网络侧隔离——LVGL 刷屏、FatFS 读卡、LwIP 协议栈都会造成负载抖动,放在同一个核上会拖垮 CAN 的响应时效。核间通过 HSEM 唤醒、D3 共享状态字和 RPMsg 通道协同。
-
为什么 CAN 放在 CM4:判据是「实时性要求最高的任务应该独占一个核」。CM7 上同时跑着 LVGL、SD 读图和 LwIP,CPU 占用抖动大,CAN 的轮询和响应会被延迟;CM4 只做 FDCAN 收发与转发,职责单一、时序可控。代价是多了一跳核间通信,所以 OpenAMP 相关任务的优先级必须高于普通 UI 任务。
-
防饿死的几个手段:把 CM7 的 ipcTask 优先级设为 High、高于 LVGL 的 Normal,避免 PNG 解码和刷屏长时间占 CPU;ipcTask 里周期性 poll,防止 VRING 缓冲区耗尽后对端发不过来;OTA 协作挂起时只停 UI 和杂务任务,不挂 ipcTask,保证核间通道仍然活着;启动顺序上先完成 Master 初始化与 HSEM release,再等 CM4 endpoint ready。运行期用 rx/tx/fail 计数和周期日志观察是否堆积或发送失败。
-
HSEM 的作用:HSEM 是硬件信号量,在这里当双核启动的握手信号用。CM4 启动后先进入低功耗/等待状态,CM7 在 OpenAMP Master 初始化完成后通过 clear/take/release HSEM 发出 handoff 信号把 CM4 唤醒;真正的槽位基址和启动参数通过 D3 SRAM 的 handoff 结构传递,不只靠信号量本身。这样能保证 CM7 先把时钟、共享内存和选槽信息准备好,再让 CM4 跑业务。顺序反了容易出现 endpoint 未就绪、CAN 未初始化或共享区读到脏数据。
-
OTA 期间哪些任务能挂:CM7 主要有 lvgl_task、ipcTask、netTask、canTask、defaultTask,外加 LwIP/HTTP/DoIP 相关线程。OTA 时挂起 LVGL 和杂务任务,降低 Flash 擦写期间的 CPU 与总线争用;ipcTask 和看门狗相关路径不挂,避免核间失联、CM4 失联或系统复位。Flash 擦写路径另有 IWDG 直写喂狗,防止长时间擦写触发复位。netTask 则延后启动 LwIP,避开 Boot 与 CM4 handoff 窗口,减少启动竞态。
-
双槽 OTA 的镜像与生效:片内 Flash 分 A/B 双槽,升级时写入空闲槽、不覆盖当前运行槽;EEPROM 记录 active/pending 槽位、镜像长度和 CRC 等元数据。HTTP 收包写完后校验(长度 + CRC,有签名的话再验签),校验通过才把 pending 置上并复位;Bootloader 起来后检查 pending 槽是否有效,有效则切换 active、启动新镜像,新镜像首次启动确认自身健康后再把 pending 清掉。这样即使升级中途掉电,当前运行的槽仍然是完整的,可以回滚。
-
CAN 丢包/延迟的定位思路:先看错误计数器和总线状态——TEC/REC 是否在涨、有没有进 BusOff、总线负载率多高,这些能区分「总线本身有问题(终端电阻、线束、波特率不匹配、节点发送过快)」还是「收发正常但上层没处理」。如果 CAN 控制器侧干净、而 CM7 侧消费延迟,就看核间通道:RPMsg 的 rx/tx/fail 计数、VRING 是否耗尽、ipcTask 有没有被抢占,以及 CM7 的 canTask 队列是否堆积。共享状态字里同时放着总线错误计数和 IPC 计数,就是为了让这种判断能一眼做完。