所学来自百问网
目录
2.2 platfrom_driver和platfrom_device的注册过程
1.驱动设计的思想:面向对象/分层/分离
1.1 面向对象
面向对象就是指的根据某一类事物的属性,进行抽象。
字符设备驱动程序抽象出一个file_operations结构体;
file_operations:对我们驱动程序经常需要用到的open、read、write这些公共的函数或属性封装成一个结构体,由于不同的硬件有不同的操作方法,故对这部分函数或属性进行抽象,在编写字符设备驱动程序时,只需对该结构体进行实现即可
1.2 分层
上层实现硬件无关的操作,比如注册字符设备驱动:leddrv.c
下层实现硬件相关的操作,比如board_A.c实现单板A的LED操作
如:
1.3 分离
当我们想对分层后的代码进行修改时,比如驱动不同的引脚的led灯,我们就要重新编写初始化和控制代码,这样显然很麻烦;由于每一款芯片的GPIO的操作都是类似的,故我们可以针对该芯片书写一个硬件通用代码
2.总线驱动设备模型
platform_driver结构体负责对硬件的寄存器代码的编写、初始化file_operation、映射寄存器等对硬件设备的初始化操作,即驱动
platform_device结构体负责对硬件功能的实现,即资源
在linux内核中,platform_bus_type
是platform总线的数据结构,它是一个虚拟的总线,总线负责设备和驱动的匹配和绑定,用于将platform_device
和platform_driver
连接起来
2.1 相关函数和结构体
2.1.1 platform_device
platform_device包含了对描述设备所需的各种信息,如设备的名称、ID、资源(如 IO 端口、内存地址、中断号等)以及指向设备特定数据的指针。
部分字段的含义:
struct platform_device {
const char *name; // 设备的名称,用于与驱动程序进行匹配
int id; // 设备的 ID 号,用于区分具有相同名称的不同设备实例。
struct device dev; // 一个 device 结构体,表示设备在内核设备模型中的抽象。
u32 num_resources; // 设备使用的资源数量
struct resource *resource; // 资源描述符数组
char *driver_override; // 一个指向字符数组的指针,用于指定要强制匹配的驱动程序名称
};
2.1.2 platform_driver
platform_driver提供了注册和注销设备驱动程序的接口,负责对硬件驱动程序的书写
部分字段的含义:
struct platform_driver {
int (*probe)(struct platform_device *); //函数指针,指向驱动程序的 probe 函数 用于初始化设备并分配必要的资源
int (*remove)(struct platform_device *); //函数指针,指向驱动程序的 remove 函数 释放之前分配的资源并执行清理操作
struct device_driver driver; //device_driver 结构体,包含了驱动程序的通用信息,如驱动程序的名称、所属模块等
const struct platform_device_id *id_table; //指向 platform_device_id 结构体数组的指针,用于基于设备 ID 的匹配
};
2.1.3 相关函数
-
用于向内核注册一个平台驱动程序
-
int platform_driver_register(struct platform_driver *drv);
-
drv
是一个指向platform_driver
结构体的指针,该结构体包含了驱动程序的信息和函数指针 -
返回值:注册成功,返回 0;如果失败,返回非零错误码
-
-
从内核中注销一个已经注册的平台驱动程序
-
void platform_driver_unregister(struct platform_driver *drv);
-
drv
是一个指向要注销的平台驱动程序结构体的指针
-
-
用于向内核注册一个平台设备
-
struct platform_device *platform_device_register(struct platform_device *pdev);
-
pdev
是一个指向
-