总线设备驱动模型

本文介绍了Linux 2.6内核中的总线模型,包括总线、设备和驱动三部分的结构体定义及其注册与注销过程。通过代码示例展示了如何实现自定义总线、驱动和设备。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

总线模型

随着技术的不断进步,系统的拓扑结构也越来越复杂,对热插拔,跨平台移植性的要求也越来越高,2.4内核已经难以满足这些需求。为适应这种形势的需要,从Linux 2.6内核开始提供了全新的设备模型。

总线设备驱动模型包括 总线设备驱动 三个组成部分。

总线

描述结构体:
在 Linux 内核中, 总线由 bus_type 结构表示,定义在 同文件

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

匹配函数:

int (*match)(struct device * dev, struct device_driver * drv)

当一个新设备或者新驱动被添加到这个总线时,该函数被调用。用于判断指定的驱动程序是否能处理指定的设备。若可以,则返回非零

总线注册与注销:
总线的 注册 使用如下函数:

bus_register(struct bus_type *bus)

若成功,新的总线将被添加进系统,并可在 * /sys/bus/ * 下看到相应的目录。

总线的 注销 使用:

void bus_unregister(struct bus_type *bus)

驱动

在 Linux内核中, 驱动由 device_driver 结构 表示:

struct device_driver {
{
    const char *name; /*驱动名称*/
    struct bus_type *bus; /*驱动程序所在的总线*/
    int (*probe) (struct device *dev);
    //………
}

驱动的注册使用如下函数:

int driver_register(struct device_driver *drv)

驱动的注销使用:

void driver_unregister(struct device_driver *drv)

设备

在 Linux内核中, 设备由struct device 结构 表示。

struct device {
{
    const char *init_name; /*设备的名字*/
    struct bus_type *bus; /*设备所在的总线*/
    //………
}

设备的 注册 使用如下函数:

int device_register(struct device *dev)

设备的 注销 使用:

void device_unregister(struct device *dev)

代码举例:

总线:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>//需要包含该头文件

MODULE_LICENSE("GPL");//需要声明遵循GPL协议

int my_match(struct device *dev, struct device_driver *drv)
//设备与驱动的匹配函数,设备插入时,总线将挂载的设备与每一个驱动分别匹配
{
    return !strncmp(dev->kobj.name,drv->name,strlen(drv->name));
    //注意:dev的名字在 kobj.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);

//在 /sys/bus/ 文件夹下可以看到添加的总线结构
//在该文件夹下对应的总线结构文件夹下,是该总线上加载的设备和相关驱动

驱动:

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");

extern struct bus_type my_bus_type;//总线结构,注意加 extern

int my_probe(struct device *dev)
{
    printk("driver found the device it can handle!\n");
    return 0;
}

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);

设备:

#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");

extern struct bus_type my_bus_type;//总线结构,注意加 extern

struct device my_dev = {  //设备结构体
     .init_name = "my_dev",
     .bus = &my_bus_type,   
};

int my_device_init()//入口
{
    int ret;
     ret = device_register(&my_dev);//注册设备
     return ret;
}

void my_device_exit()
{
    device_unregister(&my_dev);//主销设备
}

module_init(my_device_init);
module_exit(my_device_exit);

注意:在使用insmod命令加载了总线程序之后,驱动和设备的程序加载无论先后都可以正常工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值