第4章:平台设备与设备树驱动面试
建议复习路径:设备树语法 → of_match_table结构 → platform_driver注册流程 → probe中of API调用 → 实际项目踩坑点。以下通过3个高频问答和1个真实项目模板,系统梳理面试常考内容。
---面试问答卡片
考察点:驱动框架整体理解、设备树匹配流程、probe触发时机
回答框架:① 先说明platform总线将设备和驱动分离,通过name/of_match_table匹配;② 设备树节点会被内核解析为platform_device并注册到平台总线;③ 驱动注册时遍历总线,匹配成功则调用probe。
可能追问:● 如果设备树有多个匹配项,驱动如何处理?● probe失败后资源如何释放?● platform_device如何手动注册?
考察点:设备树节点编写、of_match_table宏、MODULE_DEVICE_TABLE
回答框架:① 设备树节点定义compatible、reg、interrupts等;② 驱动中定义of_device_id数组并指定compatible字符串;③ 使用MODULE_DEVICE_TABLE(of, xxx_of_match)导出;④ probe中即可通过device_of_node获取节点。
i2c0: i2c@ff000000 { compatible = "vendor,i2c-ctrl"; reg = <0xff000000 0x1000>; interrupts = ; }; 驱动中static const struct of_device_id i2c_of_match[] = { { .compatible = "vendor,i2c-ctrl" }, {} }; MODULE_DEVICE_TABLE(of, i2c_of_match); 注册platform_driver时赋值.of_match_table。
可能追问:● 如果多个驱动声明相同的compatible字符串,会发生什么?● of_match_table可以同时兼容多个不同版本吗?
考察点:of_address_to_resource、of_iomap、of_irq_get、of_property_read_xxx等实际使用
回答框架:① 先通过of_node = pdev->dev.of_node拿到节点;② 使用of_address_to_resource或platform_get_resource获取物理地址;③ 调用of_iomap映射;④ 用of_irq_get获取中断号;⑤ 自定义属性用of_property_read_u32/of_property_read_string。
可能追问:● of_iomap和devm_ioremap_resource的区别?● 设备树属性节点包含多个值如何解析?● 如何读取64位地址?
项目案例:智能音箱语音信号预处理加速器驱动
| 项目名称 | 智能音箱语音信号预处理加速器驱动(基于Xilinx Zynq FPGA) |
| 业务背景 | 为智能音箱提供硬件FFT/滤波加速,降低CPU负载,实现低延迟语音唤醒。 |
| 规模指标 | 驱动代码约1500行,支持10路音频通道、4组DMA,延迟低于10ms,驱动已在量产版本中使用。 |
| 技术栈 | Linux 4.14, Platform驱动, 设备树(FPGA IP核描述), DMAC, 中断, 用户态ioctl接口 |
| 核心难点 | 1. 多个IP核共用同一地址空间,需通过设备树reserved-memory管理;2. 中断与DMA协同,需处理竞态;3. 驱动与前级I2S驱动数据交互。 |
| 面试高频追问 | ● 设备树中如何描述多个IP核的地址空间?● 你的驱动如何处理DMA中断与CPU访问的同步?● 为什么选择platform驱动而不是直接字符设备?● 调试驱动时你用了哪些工具? |
| 可迁移回答话术 | “我们使用设备树的ranges属性映射多个IP核到CPU地址空间,驱动通过of API解析后统一管理。中断处理采用workqueue推迟耗时操作,DMA使用dmaengine框架。选platform驱动是因为芯片没有真实总线,且可以通过设备树描述多实例。” |
interrupt-names配合platform_get_irq_byname获取有语义的中断;使用of_property_read_bool检查设备树节点是否存在可选属性;提出将驱动拆分为核心层和实例层(如使用of_match_ptr宏)的设计模式。