总线设备驱动模型

来源:互联网 发布:qq游戏端口是多少 编辑:程序博客网 时间:2024/04/30 16:04

1.总线设备模型概述
2.总线
3.驱动
4.设备
1.总线设备模型概述
随着技术的不断进步,系统的拓扑结构也越来越复杂,对热插拔,跨平台移植性的要求也越来越高,2.4内核已经难以满足这些需求。为适应这种形势的需要,从Linux2.6内核开始提供了全新的设备模型。总线设备驱动对热插拔要求越来越高。
在linux系统中,有很多总线,例如USB总线挂载很多USB设备驱动程序(鼠标,USB网卡),往USB总线上插入一个USB网卡设备,USB总线感知到一个新的设备上到总线上并且是USB的,总线会把总线上的每一个驱动与USB网卡设备匹配,匹配成功后usb总线将控制权交给USB网卡驱动程序,USB驱动程序开始处理USB网卡设备。设备从总线拔掉,USB总线感知USB网卡设备拔掉,USB总线将找到相应的USB网卡驱动程序将处理设备拔掉这个事件。
网卡从USB换成miniPCI,需要修改的特别少,增强了驱动程序的可移植性。
当往总线上插入一个设备,总线有义务将设备与驱动进行匹配,有match函数完成是否可以匹配。匹配成功调用probe函数
以下将从创建总线、创建驱动,创建设备3个方面进行总线设备挂载到总线上的流程进行介绍。
2.总线
2.1描述结构
在Linux 内核中, 总线由bus_type 结构表示,定义在

#include<linux/device.h>struct bus_type {const char *name; /*总线名称*/int (*match) (struct device *dev, struct device_driver *drv); /*驱动与设备的匹配函数*/}int (*match)(struct device * dev, struct device_driver * drv)

当一个新设备或者新驱动被添加到这个总线时,该函数被调用。用于判断指定的驱动程序是否能处理指定的设备。若可以,则返回非零。
2.2总线注册
总线的注册使用如下函数
bus_register(struct bus_type *bus)
若成功,新的总线将被添加进系统,并可在
/sys/bus 下看到相应的目录。
2.3总线注销
总线的注销使用:
void bus_unregister(struct bus_type *bus)

bus.c#include<linux/init.h>#include<linux/module.h>#include<linux/kernel.h>#include<linux/device.h>MODULE_LICENSE("GPL");int my_match(struct device *dev, struct device_driver *drv){     return !strncmp(dev->kobj.name,drv->name,strlen(drv->name));}struct bus_type my_bus_type = {    .name = "my_bus",    .match = my_match,};EXPORT_SYMBOL(my_bus_type);//将变量输出,供外部使用int my_bus_init(){    int ret;    ret=bus_register(&my_bus_type);    return ret;}void my_bus_exit(){    bus_unregister(&my_bus_type);}module_init(my_bus_init);module_exit(my_bus_exit);

insmod bus.ko加载驱动、向系统注册总线
lsmod
查看总线课通过cd /sys/bus,ls即可查看linux支持的总线
3.驱动
3.1描述结构
在Linux内核中, 驱动由device_driver结构表示。
struct device_driver {
{
const char name; /驱动名称*/
struct bus_type bus; /驱动程序所在的总线*/
int (*probe) (struct device *dev);
………
}
3.2驱动注册
驱动的注册使用如下函数
int driver_register(struct device_driver *drv)

3.3驱动注销
驱动的注销使用:
void driver_unregister(struct device_driver *drv)

driver.c#include<linux/module.h>#include<linux/init.h>#include<linux/device.h>#include<linux/kernel.h>extern struct bus_type my_bus_type;//变量来自于外部MODULE_LICENSE("GPL");int my_probe(struct device *dev){    printk("the bus's driver find the device it can handle\n ");    //实际的硬件设备初始化}struct device_driver my_driver = {    .name = "my_dev",//驱动名称    .bus = &my_bus_type,//所挂载的总线    .probe = my_probe,//匹配调用函数};int my_driver_init(){    int ret;    ret =driver_register(&my_driver);    return ret;}void my_driver_exit(){    driver_unregister(&my_driver);}module_init(my_driver_init);module_exit(my_driver_exit);

insmod driver.ko
cd /sys/bus/
ls即可看到my-bus总线
cd drivers/
ls
即可查看重新注册的驱动my_dev
4.设备
4.1设备描述结构
在Linux内核中, 设备由struct device结构表示。
struct device {
{
const char init_name; /设备的名字*/
struct bus_type bus; /设备所在的总线*/
………
}
4.2设备注册
设备的注册使用如下函数
int device_register(struct device *dev)
4.3设备注销
设备的注销使用:
void device_unregister(struct device *dev)

device.v#include<linux/init.h>#include<linux/module.h>#include<linux/kernel.h>#include<linux/device.h>MODULE_LICENSE("GPL");extern struct bus_type my_bus_type;struct device my_device = {    .init_name = "my_dev",    .bus = &my_bus_type,};int my_device_init(){    int ret;    ret = device_register(&my_device);    return ret;}void my_device_exit(){        dvice_unregister(&my_device);}module_init(my_device_init);module_exit(my_device_exit);

insmod bus.ko
insmod driver.c
insmod device.c
#
the bus’s driver find the device it can handle
总结:
1.总线上已经挂载设备驱动程序,当向总线添加设备,总线匹配成功,调用驱动1的probe函数
2.总线上已经挂载多个设备,后加载一个驱动程序,将驱动与每个设备匹配,匹配成功,调用驱动probe函数

0 0