传音 BSP 驱动一面面经:摄像头驱动与 V4L2 深挖
- 轮次
- 一面
- 时间
- 2026-10
- 来源
- 牛客网
《面试题目》
岗位:C++ 开发工程师(驱动,高通方向),base 重庆。本场当晚通过,次日安排二面。
- 自我介绍,核对岗位。
- 介绍一下你的实习项目,尤其是影像相关的部分。
- 重点讲一下分离屏端的性能优化,以及分合体优化。
- 你们如何确保分离屏端和主机端的操作以及状态的一致?
- 你在影石做的主要都是偏上层的开发吗?
- 讲一下你在应用层如何处理多线程同步和竞态问题。
- 除了基本的互斥锁之外,还有哪些互斥机制?你是否了解无锁机制?
- 你做过 MCU 开发,了解哪些通讯协议及其作用,简单讲一讲各自的特性。
- 你本科是土木,硕士是人工智能,怎么跑来搞嵌入式和驱动开发了?
- 我看你人工智能相关的履历似乎不多?
- 你驱动做得比较多,讲一下 V4L2 吧:要添加一个设备,应该做哪些工作?
- 比如我现在有两个 CMOS,你应该如何调试?
- 你是不是写过摄像头驱动?
- 如果摄像头不出图,你该如何检测?
- 不应该先看设备是否成功挂载吗?
- 你有使用过 MIPI 的 sensor 吗?
- 你是否了解 3A?
- 如果现在摄像头过曝了,你应该调节哪些参数?
- 不应该先调光圈吗?曝光三要素是光圈、ISO、曝光时长。
- 你是否了解 CMOS 的成像原理或者参数含义?
- EV 是什么?
- 你了解哪些图像格式,详细讲讲。
- 为什么 YUV 要在 UV 通道减少数据量?
- 你是否了解安卓?
- 你平时如何使用 AI?
- 你嵌入式获奖经验怎么就只写到了 2021 年?
- 是否听说过 HAL 层,是否能接受来做 HAL?
反问:什么时候出面试结果?(答:一两周内)
《参考解析》
-
V4L2 添加一个设备(第 11 题):按「总线和设备匹配 → 分配与注册 → 字符设备与 fops → buffer 队列 → 控制接口」这条链路讲。摄像头 sensor 挂在 I2C 上,通常以 I2C 设备加平台设备的形式注册,驱动里用
i2c_device_id/of_device_id声明能匹配的型号。probe 里依次做几件事:申请 GPIO 与 regulator、按手册上电并解复位、通过 I2C 写寄存器列表做初始化;接着注册v4l2_device作为 V4L2 子系统的根,注册v4l2_subdev(sensor 侧)或video_device(输出节点侧);实现file_operations的open/ioctl/mmap/poll;用 vb2 队列管理帧缓冲,实现queue_setup、buf_prepare、start_streaming/stop_streaming这些回调;最后调video_register_device暴露/dev/videoX。补一句 media controller 框架下还要建 entity 与 pad 链接,把 sensor → CSI → ISP 的流水线连起来,这才算讲完整。 -
两个 CMOS 怎么调试(第 12 题):默认情况下两路会各自注册成独立的
/dev/videoX,所以第一步永远是分开验证——单独上电、单独读 sensor ID 寄存器确认 I2C 通、单独取流确认能出图,先排除「某一颗本身没工作」。真正难的是共享资源:MIPI CSI 的通道数有限,不少平台需要分时复用,靠多路复用开关或 virtual channel 区分;两路 sensor 若共用同一路主时钟或 reset GPIO,初始化时序会互相打断,要明确谁先谁后、谁负责拉复位。调试手段是v4l2-ctl列格式与取流、media-ctl -p打印拓扑确认 entity 连接和格式协商是否符合预期,再用示波器看 MIPI 时钟与同步信号。 -
摄像头不出图怎么查(第 14、15 题):先把「不出图」和「花屏」分开,两类问题的排查路径完全不同。不出图要从链路底层往上走:设备有没有被枚举到(
dmesg看 probe 是否成功、/dev/video*有没有节点、media 拓扑是否正确)→ I2C 能不能读写(读 sensor ID 寄存器)→ 时钟、供电、复位时序是否满足手册要求 → 同步信号有没有在动(示波器看 VSYNC / HSYNC 或 MIPI 的时钟 lane)→ 数据有没有进到 CSI / ISP(看中断计数、vb2 的 buffer 是否被填满、DQBUF 是否超时)。如果确认 sensor 已经在连续出图、而应用还是拿不到帧,问题就落在 vb2 / CSI / ISP 这几层,不在 sensor 本身。花屏则要查同步信号与数据搬运之间的联动、帧数据类型与 stride 是否匹配、lane 数与字节序配置是否正确。这也解释了面试官那句追问:确认「不出图」时设备其实已经挂载了,没挂载是另一类问题,要从 I2C 控制通路查起。 -
无锁机制(第 7 题):互斥锁之外,内核里常用的同步原语还有自旋锁(不可睡眠的短临界区)、读写锁(读多写少)、可重入锁、信号量(允许 N 个持有者)、完成量(等待某个事件发生)。无锁方向重点讲两个:RCU 的读侧完全不加锁,靠发布-订阅语义加宽限期延迟释放,适合读极多、写极少的场景,代价在写侧要等宽限期、内存回收滞后;顺序锁 seqlock 让读者前后各读一次版本号,两次不一致就重读,写侧只递增版本号,适合时间戳这类写极少而读极多的数据。要补一句边界:无锁不等于无条件更快,读侧省下的开销是用写侧复杂度、内存放大和实现难度换来的,选型要看读写比。
-
3A 与过曝(第 17、18、19 题):3A 指 AE 自动曝光、AF 自动对焦、AWB 自动白平衡,三者在 ISP 里都是闭环控制——统计模块给出直方图或分区亮度,算法算出目标值,再回写 sensor 的曝光与增益寄存器、VCM 位置、白平衡增益。过曝先分清是整体偏亮还是高光溢出:整体偏亮就降曝光时长或降增益,优先降增益是因为拉长曝光在动态场景里更容易糊;只有高光区域溢出,则要看动态范围够不够、是否需要 HDR 或色调映射。面试官追问「为什么不先调光圈」,答案是手机 CMOS 模组绝大多数是固定光圈,没有可调的机械光圈,所以手机上曝光三要素里真正可控的只有曝光时长和增益(ISO),这一点和单反的操作顺序不一样。
-
EV(第 21 题):EV 是曝光值,标准定义是
EV = log2(N² / t),把光圈值与快门时间合成一个数,用来比较不同组合的总进光量是否等价。手机语境里 EV 更多被当成曝光补偿在用,一个 EV 就是一档、进光量翻倍或减半。动态范围越高的 sensor 能保留的可用档位越多,所以高动态范围的 sensor 曝光补偿的可调区间也更大——把这两层分开说,就不会把「曝光值」和「曝光补偿」混成一个概念。 -
YUV 采样(第 23 题):YUV 把亮度与色度分离,而人眼对亮度细节的分辨能力远高于色度:视网膜里负责色觉的锥细胞数量少、分布密度也低,色度的空间分辨率损失肉眼几乎察觉不到。所以 4:2:2 / 4:2:0 只在色度平面做下采样、亮度保持全采样,却能省掉三分之一到一半的带宽与存储。工程上 NV12 是摄像头与编解码链路里最常见的格式,因为它在内存里 Y 与 UV 各是一段连续区域,便于 DMA 传输与硬件对齐。
-
分离屏端与主机端的状态一致(第 4 题):这类双端系统的一致性不能靠共享内存加锁,得靠「单一数据源 + 版本号」的模型:主机端持有权威状态,分离屏端只持有一份带序号的快照,所有写操作都回到主机端串行化,屏端按序号应用增量并丢弃过期的响应。断连重连时屏端上报本地序号,主机端决定是补发增量还是全量重建。用序号而不是时间戳,是因为两台设备的时钟本来就不一致。