1. Linux 设备驱动模型的核心组件有哪些?
kobject:最基础对象,提供引用计数、sysfs 文件系统导出、对象生命周期管理;
kset:kobject 的集合,按类别管理同类 kobject(如所有设备对象),支持统一事件处理;
bus:总线抽象(如 platform/I2C/spi),是设备与驱动的连接媒介,定义匹配 / 解绑规则;
device:表示硬件设备(物理 / 逻辑),存储设备属性、父 / 子设备关系,关联到具体总线;
driver:驱动抽象,包含 probe(设备匹配后初始化)、remove(设备移除时清理)等核心接口;
class:按功能归类设备(如 led/input),简化用户态访问(/sys/class/)。
2、驱动和设备是如何匹配的?
核心基于总线的匹配函数,分三类场景:
(1).设备树匹配(主流):驱动的of_match_table中compatible属性,与设备树中设备节点的compatible字符串匹配;
(2).平台总线匹配:平台设备(platform_device)的name与平台驱动(platform_driver)的driver.name完全匹配;
(3).ID 匹配:驱动的 id_table(如 I2C 的driver.id_table )与设备的 ID(如 I2C 的 client.addr )匹配;匹配成功后,总线调用驱动的 probe 函数完成设备初始化。
3. 设备树在驱动开发中的作用是什么?
硬件解耦:将硬件参数(寄存器地址、GPIO、中断号、时钟)从驱动代码中剥离,集中在设备树(.dts),无需修改驱动适配不同硬件;
动态配置:运行时通过设备树解析硬件信息,支持多平台复用同一驱动;
标准化:遵循 DTB 规范,统一硬件描述格式,简化驱动移植;
资源管理:驱动通过of_接口(如of_get_address)获取硬件资源,替代传统platform_get_resource。
4. GPIO 子系统架构?
底层:GPIO 控制器硬件驱动(如芯片级 GPIO 控制器),实现寄存器操作(方向 / 电平 / 中断);
核心层(gpiolib):提供统一的 GPIO 抽象接口(gpio_request/gpio_set_value),屏蔽不同控制器的硬件差异;
上层:驱动层调用 gpiolib 接口操作 GPIO,支持设备树解析、中断映射、sysfs 导出。
5. GPIO 子系统实现?(核心逻辑)
GPIO 控制器注册:驱动实现gpio_chip结构体(包含方向 / 电平 / 中断操作接口),通过gpiochip_add_data注册到 gpiolib;
GPIO 编号管理:为每个 GPIO 分配全局编号(静态 /base 或动态),关联到具体控制器;
GPIO 请求 / 释放:驱动通过gpio_request申请 GPIO(防止冲突),gpio_free释放;电平 / 方向操作:通过gpio_direction_input/output设置方向,gpio_get_value/set_value读写电平。
6、GPIO 子系统的主要组件有哪些?
gpio_chip:表示一个 GPIO 控制器,包含控制器的硬件操作接口(如方向设置、电平读写);
gpio_desc:单个 GPIO 引脚的描述符,存储 GPIO 编号、方向、电平、中断属性、所属gpio_chip;
gpiolib:核心库,提供 GPIO 申请、释放、电平操作、中断映射的统一接口;
GPIO 控制器驱动:硬件层实现,对具体芯片的 GPIO 寄存器(如 NXP 高通 GPIO 控制器)操作
7、 如何在驱动中使用 GPIO?
(1) 从设备树获取GPIO编号
of_get_named_gpio();
(2). 申请GPIO
gpio_request()
(3). 设置方向(输出)
gpio_direction_output();
(4) 操作电平
gpio_set_value();
(5). 释放GPIO(驱动卸载时)
gpio_free();
8、GPIO 中断是如何使用的?
中断映射:通过gpio_to_irq将 GPIO 编号转换为中断号;
申请中断:调用request_irq注册中断处理函数,指定触发方式(上升沿 / 下降沿 / 双边沿);
硬件触发:GPIO 引脚电平变化触发控制器中断,内核调用注册的中断处理函数;
中断释放:驱动卸载时调用free_irq释放中断。
9、 Pinctrl 子系统架构?
核心层:提供引脚复用、配置(上拉 / 下拉 / 速率)的统一接口;
硬件层:芯片级 pinctrl 驱动(如 pinctrl-s32k),实现寄存器级引脚配置;
设备树层:描述引脚组(pin group)、复用功能(function)、配置属性;
接口层:驱动通过pinctrl_get/pinctrl_select_state调用配置。
10、 Pinctrl 子系统使用?(核心步骤)
(1)pinctrl 驱动注册:实现pinctrl_desc结构体(包含引脚配置、复用接口),通过pinctrl_register注册;
(2)设备树解析:解析设备节点的pinctrl-0/pinctrl-names属性,获取引脚状态(默认 / 休眠);
(3)引脚配置:驱动通过pinctrl_select_state选择引脚状态,底层驱动修改寄存器配置复用 / 上下拉。
11、Pinctrl 子系统的作用是什么?
引脚复用:配置引脚功能(如同一引脚切换为 GPIO/I2C_SDA/SPI_CLK);
引脚配置:设置引脚的电气特性(上拉 / 下拉 / 驱动强度、速率、开漏 / 推挽);
引脚管理:统一管理系统所有引脚,避免引脚冲突;
状态切换:支持引脚在不同状态(默认 / 休眠 / 唤醒)下的配置切换,适配低功耗场景。
12、 Pinctrl 与 GPIO 子系统的关系是什么?
依赖关系:GPIO 引脚必须先通过 Pinctrl 配置为 “GPIO 功能”,才能被 GPIO 子系统操作;
分工不同:Pinctrl 负责引脚的 “复用 + 电气配置”(硬件属性),GPIO 负责引脚的 “方向 + 电平 + 中断”(功能操作);
流程联动:驱动先通过 Pinctrl 将引脚设为 GPIO 模式,再调用 GPIO 子系统操作电平 / 中断。
kobject:最基础对象,提供引用计数、sysfs 文件系统导出、对象生命周期管理;
kset:kobject 的集合,按类别管理同类 kobject(如所有设备对象),支持统一事件处理;
bus:总线抽象(如 platform/I2C/spi),是设备与驱动的连接媒介,定义匹配 / 解绑规则;
device:表示硬件设备(物理 / 逻辑),存储设备属性、父 / 子设备关系,关联到具体总线;
driver:驱动抽象,包含 probe(设备匹配后初始化)、remove(设备移除时清理)等核心接口;
class:按功能归类设备(如 led/input),简化用户态访问(/sys/class/)。
2、驱动和设备是如何匹配的?
核心基于总线的匹配函数,分三类场景:
(1).设备树匹配(主流):驱动的of_match_table中compatible属性,与设备树中设备节点的compatible字符串匹配;
(2).平台总线匹配:平台设备(platform_device)的name与平台驱动(platform_driver)的driver.name完全匹配;
(3).ID 匹配:驱动的 id_table(如 I2C 的driver.id_table )与设备的 ID(如 I2C 的 client.addr )匹配;匹配成功后,总线调用驱动的 probe 函数完成设备初始化。
3. 设备树在驱动开发中的作用是什么?
硬件解耦:将硬件参数(寄存器地址、GPIO、中断号、时钟)从驱动代码中剥离,集中在设备树(.dts),无需修改驱动适配不同硬件;
动态配置:运行时通过设备树解析硬件信息,支持多平台复用同一驱动;
标准化:遵循 DTB 规范,统一硬件描述格式,简化驱动移植;
资源管理:驱动通过of_接口(如of_get_address)获取硬件资源,替代传统platform_get_resource。
4. GPIO 子系统架构?
底层:GPIO 控制器硬件驱动(如芯片级 GPIO 控制器),实现寄存器操作(方向 / 电平 / 中断);
核心层(gpiolib):提供统一的 GPIO 抽象接口(gpio_request/gpio_set_value),屏蔽不同控制器的硬件差异;
上层:驱动层调用 gpiolib 接口操作 GPIO,支持设备树解析、中断映射、sysfs 导出。
5. GPIO 子系统实现?(核心逻辑)
GPIO 控制器注册:驱动实现gpio_chip结构体(包含方向 / 电平 / 中断操作接口),通过gpiochip_add_data注册到 gpiolib;
GPIO 编号管理:为每个 GPIO 分配全局编号(静态 /base 或动态),关联到具体控制器;
GPIO 请求 / 释放:驱动通过gpio_request申请 GPIO(防止冲突),gpio_free释放;电平 / 方向操作:通过gpio_direction_input/output设置方向,gpio_get_value/set_value读写电平。
6、GPIO 子系统的主要组件有哪些?
gpio_chip:表示一个 GPIO 控制器,包含控制器的硬件操作接口(如方向设置、电平读写);
gpio_desc:单个 GPIO 引脚的描述符,存储 GPIO 编号、方向、电平、中断属性、所属gpio_chip;
gpiolib:核心库,提供 GPIO 申请、释放、电平操作、中断映射的统一接口;
GPIO 控制器驱动:硬件层实现,对具体芯片的 GPIO 寄存器(如 NXP 高通 GPIO 控制器)操作
7、 如何在驱动中使用 GPIO?
(1) 从设备树获取GPIO编号
of_get_named_gpio();
(2). 申请GPIO
gpio_request()
(3). 设置方向(输出)
gpio_direction_output();
(4) 操作电平
gpio_set_value();
(5). 释放GPIO(驱动卸载时)
gpio_free();
8、GPIO 中断是如何使用的?
中断映射:通过gpio_to_irq将 GPIO 编号转换为中断号;
申请中断:调用request_irq注册中断处理函数,指定触发方式(上升沿 / 下降沿 / 双边沿);
硬件触发:GPIO 引脚电平变化触发控制器中断,内核调用注册的中断处理函数;
中断释放:驱动卸载时调用free_irq释放中断。
9、 Pinctrl 子系统架构?
核心层:提供引脚复用、配置(上拉 / 下拉 / 速率)的统一接口;
硬件层:芯片级 pinctrl 驱动(如 pinctrl-s32k),实现寄存器级引脚配置;
设备树层:描述引脚组(pin group)、复用功能(function)、配置属性;
接口层:驱动通过pinctrl_get/pinctrl_select_state调用配置。
10、 Pinctrl 子系统使用?(核心步骤)
(1)pinctrl 驱动注册:实现pinctrl_desc结构体(包含引脚配置、复用接口),通过pinctrl_register注册;
(2)设备树解析:解析设备节点的pinctrl-0/pinctrl-names属性,获取引脚状态(默认 / 休眠);
(3)引脚配置:驱动通过pinctrl_select_state选择引脚状态,底层驱动修改寄存器配置复用 / 上下拉。
11、Pinctrl 子系统的作用是什么?
引脚复用:配置引脚功能(如同一引脚切换为 GPIO/I2C_SDA/SPI_CLK);
引脚配置:设置引脚的电气特性(上拉 / 下拉 / 驱动强度、速率、开漏 / 推挽);
引脚管理:统一管理系统所有引脚,避免引脚冲突;
状态切换:支持引脚在不同状态(默认 / 休眠 / 唤醒)下的配置切换,适配低功耗场景。
12、 Pinctrl 与 GPIO 子系统的关系是什么?
依赖关系:GPIO 引脚必须先通过 Pinctrl 配置为 “GPIO 功能”,才能被 GPIO 子系统操作;
分工不同:Pinctrl 负责引脚的 “复用 + 电气配置”(硬件属性),GPIO 负责引脚的 “方向 + 电平 + 中断”(功能操作);
流程联动:驱动先通过 Pinctrl 将引脚设为 GPIO 模式,再调用 GPIO 子系统操作电平 / 中断。
