平台总线开发笔记:https://blog.csdn.net/weixin_39148042/article/details/82495343
高级驱动--平台总线:
Linux设备驱动模型的由来:
1,实现入口函数 xxx_init()和卸载函数 xxx_exit()
2,申请设备号 register_chrdev (与内核相关)
3,利用udev/mdev机制创建设备文件(节点) class_create, device_create (与内核相关)
4,硬件部分初始化
io资源映射 ioremap,内核提供gpio库函数 (与硬件相关)
注册中断(与硬件相关)
5,构建 file_operation结构 (与内核相关)
6,实现操作硬件方法 xxx_open,xxx_read,xxxx_write
设备驱动模型:总线、device、driver
device对象:设备对象,描述设备信息,包括地址,中断号,甚至其他自定义的数据
driver对象:描述设备驱动的方法(代码逻辑)
bus:平台总线,平台总线会建立两个链表,一个与device相关的链表,另一个与driver相关的链表,我们写的所有的device和driver都会添加(注册)到bus中的相应链表中,device和driver中都有一个名字,找出device和driver名字相同的匹配在一起,形成一个完整的设备驱动,然后调用driver中的probe函数(方法),如果需要移除设备,调用driver中的remove函数(方法),这就是bus的功能。
Sysfs文件系统:告诉我们内核驱动的一些信息
下图是拓扑图,表示设备之间的一种关系,可以通过总线查看一个设备,也可以通过Devices查看一个设备,还可以通过一个类来查看一个设备。
/sys目录下存放的有Buses、Devices、Classes
Buses:所有总线,下图usb是其中的一个总线
Devices:所有设备的集合
Classes:将所有设备进行分类,比如:输入设备等
总线设备都可以在Buses、Devices和Classes中找到。
/sys:
block:用于管理块设备,系统中的每一个块设备会在该目录下对应一个子目录。
bus:用于管理总线,每注册一条总线,在该目录下有一个对应的子目录。
其中,每个总线子目录下会有两个子目录:devices和drivers。
devices包含系统中所有属于该总线的的设备。
class:将系统中的设备按功能分类。
dev:该目录包含已注册的设备号(设备节点)的视图,包括char和block
kernel:内核中的相关参数。
module:内核中的模块信息。
fireware:内核中的固件信息。
fs:描述内核中的文件系统。
配对函数(match)、探测函数(probe)和卸载函数:
1,int (*match)(struct device *dev, struct device_driver *drv);--总线bus
当总线上添加了新设备或者新驱动函数的时候,内核会调用一次或者多次这个函数。
如果现在添加了一个新的驱动(driver),内核就会调用所属总线(bus)的match函数,
配对总线上所有的设备(device),如果驱动能够对应处理其中一个设备,函数返回1,
告诉内核配对成功。一般的,match函数是判断设备的结构体成员device->bus_id
和驱动函数的结构体成员device_driver->name是否一致,如果一致,
那就表明配对成功。
2,int (*probe)(struct device *dev);---- 驱动driver
当配对(match)成功后,内核就会调用指定驱动中的probe函数来查询设备能否被该
驱动操作,如果可以,驱动就会对该设备进行相应的操作,如初始化。所以说,真正
的驱动函数入口是在probe函数中。
3, int (*remove) (struct device *dev); ---驱动driver
当设备从总线中移除时,内核会调用驱动函数中的remove函数调用,进行一些设备
卸载相应的操作
总线模型编程:
平台总线模型:
平台总线编程接口:
Pdev注册和注销
int platform_device_register(struct platform_device * pdev)
void platform_device_unregister(struct platform_device * pdev)
获取资源数据
int platform_get_irq(struct platform_device * dev,unsigned int num)
struct resource * platform_get_resource_byname(struct platform_device * dev, unsigned int type,const char * name)