优必选 Linux BSP 岗:RTOS 调度、中断与设备树
- 轮次
- 技术面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
- RTOS 的任务调度流程是怎样的?
- 多任务调度时,任务怎么存储?(链表)
- 上下文切换机制是怎样的?
- 什么是优先级反转?优先级继承怎么解决?
- 死锁的条件有哪些?如何解决死锁?
- Linux 设备驱动模型是怎样的?
- Linux 内核启动流程是怎样的?怎么知道要访问哪个内存?
- 中断下半部有哪些实现方式?接触过软中断吗?
- 中断函数可以使用互斥锁吗?
- 二叉树的遍历方法有哪些?分别用什么算法实现?
- 设备树有没有自己写过一条完整的总线?
- Linux 外设驱动你用过哪些?
- CAN 总线标准帧和扩展帧有什么区别?CAN FD 和经典 CAN 呢?
- C++ 智能指针有哪些?unique 引用和 shared 引用可以转换吗?
- map 的底层实现原理是什么?
- 引用折叠了解吗?
《参考解析》
RTOS 调度分「就绪队列 + 优先级 + 时间片」。任务控制块(TCB)用链表挂在就绪/阻塞/挂起队列上,调度器每次从最高优先级就绪队列取任务;同优先级按时间片轮转。上下文切换保存当前任务的寄存器组到 TCB、恢复下一个任务的寄存器组,再切栈指针。
优先级反转是「高优先级任务被低优先级任务持有的锁挡住,而中优先级任务又抢占了低优先级任务」。解决办法是优先级继承(持锁的低优先级任务临时提升到等待者的优先级)或优先级天花板。死锁的四个必要条件互斥、占有并等待、不可抢占、循环等待,破坏任意一个即可。
中断里不能用互斥锁,因为中断上下文不能睡眠,而互斥锁在竞争时会阻塞。中断里只能用自旋锁(且要关中断防止死锁)或原子操作;耗时工作放到下半部(软中断、tasklet、工作队列),工作队列可以睡眠。
Linux 启动流程:BootROM → bootloader(U-Boot)→ 内核解压与初始化(建立页表、初始化内存和中断)→ 挂载根文件系统 → 启动 init/systemd → 用户态服务。设备树在启动时被解析,内核据此匹配驱动、获取寄存器地址和中断号。
CAN 标准帧 11 位 ID、扩展帧 29 位 ID;CAN FD 支持更大的数据段(最多 64 字节)和更高的速率,仲裁段仍兼容经典 CAN。BSP 岗常问这些,因为车载和机器人大量使用 CAN。
C++ 智能指针:unique_ptr 独占、shared_ptr 共享(控制块计数)、weak_ptr 观察。unique 可以转 shared(移动构造),shared 不能转 unique(所有权不唯一)。map 底层是红黑树,查找/插入 O(log n),有序;unordered_map 是哈希表,平均 O(1) 但无序。引用折叠是模板推导里 & + & = &、& + && = &、&& + && = &&,完美转发靠它。