第4章 驱动开发基础与设备树

设备树(Device Tree)是嵌入式Linux硬件描述的语言,platform驱动是内核与设备树交互的桥梁,字符设备驱动则是BSP工程师最常编写的驱动类型。面试中,这三个核心点往往被组合考察——从设备树节点定义,到驱动匹配,再到字符设备注册与调试,形成一条完整的技术链路。

设备树节点定义 内核解析设备树 of_match_table匹配 probe被调用 初始化硬件资源 驱动未匹配? 检查compatible 确认内核解析状态 检查dtc编译语法 检查reg/地址 验证status属性

📌 面试问答卡片

问题:请描述设备树中一个I2C设备节点的完整结构。

🎯 面试官考察点

  • 是否理解设备树节点语法(@地址、compatible、reg)
  • 是否知道I2C设备地址如何表示
  • 是否熟悉status属性用途

📐 回答框架

  1. 节点命名:device@address
  2. compatible = "厂商,芯片型号";
  3. reg = <地址>; (I2C为7位地址)
  4. 可选status = "okay" / "disabled"

💬 简短示例回答

“例如:&i2c1 { touch@1a { compatible = "goodix,gt911"; reg = <0x1a>; status = "okay"; }; }; 其中reg是设备I2C地址,compatible用于驱动匹配,status控制节点是否生效。”

❓ 可能追问

如何添加两个同型号设备?如何表达中断引脚?

⚠️ 避坑提醒

reg中的地址必须为整数,不可用字符串;不要忽略status="disabled"导致驱动不加载。

问题:platform驱动如何与设备树中的节点匹配?

🎯 面试官考察点

  • 是否理解of_match_table机制
  • 是否知道MODULE_DEVICE_TABLE的作用
  • 是否了解驱动与设备树的绑定关系

📐 回答框架

  1. 驱动定义struct of_device_id数组,填compatible
  2. 内核扫描设备树中已注册节点的compatible
  3. 匹配成功则调用probe
  4. 导出MODULE_DEVICE_TABLE以便模块加载

💬 简短示例回答

“驱动中声明 static const struct of_device_id my_of_match[] = { { .compatible = "vendor,device" }, {} }; 并使用 MODULE_DEVICE_TABLE(of, my_of_match);。设备树节点中compatible属性与之一致,内核即可自动匹配并调用probe。”

❓ 可能追问

多个驱动匹配同一compatible会怎样?of_match_table支持模糊匹配吗?

⚠️ 避坑提醒

忘记导出MODULE_DEVICE_TABLE,模块加载时将无法自动匹配;内核会按编译顺序选择第一个匹配的驱动。

问题:字符设备驱动的probe函数中需要完成哪些初始化工作?

🎯 面试官考察点

  • 是否熟悉字符设备注册流程(设备号、cdev、class)
  • 是否知道file_operations结构体的实现要求
  • 是否理解设备节点自动创建机制

📐 回答框架

  1. 动态分配设备号:alloc_chrdev_region
  2. 初始化cdev结构:cdev_init
  3. 添加cdev到内核:cdev_add
  4. 创建设备类/节点:class_create + device_create

💬 简短示例回答

“先调用alloc_chrdev_region(&devno,0,1,"mydev")获取设备号,然后cdev_init(&cdev,&fops)和cdev_add(&cdev,devno,1),最后通过class_create(THIS_MODULE,"myclass")和device_create(class,NULL,devno,NULL,"mydev")自动创建设备节点。”

❓ 可能追问

如何避免设备号冲突?如果系统没有udev/mdev,节点怎么创建?

⚠️ 避坑提醒

使用静态注册(MKDEV)容易冲突,推荐动态分配;cdev_add失败后需手动释放设备号。

📁 项目案例模板:基于设备树的I2C触摸屏驱动调试

项目名称基于设备树的I2C触摸屏驱动调试(Goodix GT911)
业务背景某款工业平板使用Goodix GT911电容触摸屏,需在Linux 5.4内核上适配驱动并支持多点触控,中断响应要求<10ms。
规模指标单板调试,触摸点数5个,中断频率约80Hz
技术栈Linux 5.4、设备树、I2C subsystem、input子系统、中断处理
核心难点①设备树中断配置错误导致中断无法触发;②I2C时序不匹配导致通信失败;③多点触控协议上报时序。

🔥 面试高频追问

  • 如何验证设备树中的中断配置是否正确?
  • I2C通信失败时,你的排查步骤是什么?
  • 如何确认驱动确实收到了中断并上报了input事件?

💡 可迁移回答话术

“调试中断时先cat /proc/interrupts确认中断号计数是否变化,再检查设备树中interrupts属性值是否与GPIO控制器的中断号匹配。I2C通信验证用i2cget -f -y 读取寄存器,对比预期值。如果读回全0xFF则多半是地址或硬件连接问题。”