linux_bus驱动

作者: stringlife | 来源:发表于2018-08-08 17:03 被阅读0次

由于没有经过完整测试代码中可能会有不足之出,如有网友发现还请斧正
这是一个学习文档,所有代码仅供学习使用,请勿在生产环境中使用
代码在ubuntu 12.04,ubuntu 16.04,ubuntu 18.04下经过测试
[邮箱] :(liulf_pc@126.com)
[CSDN] :https://blog.csdn.net/qqstring
[仓库地址] :https://gitee.com/stringliulf/char_driver.git
[简书]:https://www.jianshu.com/u/752603033847

linux 总线(bus)驱动可以很好了理解linux的驱动模型
我有以下理解:

  • 在bus驱动模型中分成bus,device,driver三个部分
  • driver是真正的驱动,负责做事,在硬件驱动中负责操作硬件
  • device是资源的提供者,负责给driver提供必要的资源
  • bus是纽带,负责将driver与device联系起来

测试方法:

insmod bus.ko
insmod device.ko
insmod driver.ko

匹配过程描述:

  1. 首先将bus注册到内核,告诉内核有一个testbus总线
  2. 将device 注册到内核(实际上注册到了testbus总线的设备列表),即将一个device设备挂在testbus下
  3. 将driver 注册到内核,(实际上注册到了testbus总线的driver列表),即将一个driver驱动挂在testbus下
  4. 在注册device过程中会触发bus的match函数,如果总线上有与该device的匹配的驱动,则会调用该驱动的probe函数
  5. 同样在注册driver过程中也会触发match函数,如果总线有与该driver匹配的设备,则会调用该驱动的probe函数

bus代码

bus只需要完成match的工作就可以

代码中使用设备名进行匹配,实际的驱动中会比这个要复杂点,比如usb可以使用 id进行匹配,match函数返回1表示匹配成功,返回0表示失败

struct bus_type testbus = {
    .name = "testbus",
    .match = testbus_match,
};
EXPORT_SYMBOL(testbus);

int testbus_match(struct device *dev, struct device_driver *drv)
{
    if(strncmp(drv->name, dev->kobj.name, strlen(drv->name)) == 0) {
        printk(KERN_INFO "match success %s\n",drv->name);
        return 1;
    }else {
        printk(KERN_INFO "not match %s\n",drv->name);
        return 0;
    }
}
 
static int testbus_init(void)
{
    int ret;
    ret = bus_register(&testbus);
    return ret;
}
 
static void testbus_exit(void)
{
    bus_unregister(&testbus);
    printk(KERN_ALERT "unregiste %s %s\n",__func__,testbus.name);
}
 
module_init(testbus_init);
module_exit(testbus_exit);
MODULE_LICENSE("GPL");

driver代码

extern struct bus_type testbus;
struct device_driver* mydrv = NULL ;
 
int mydrv_probe(struct device *dev)
{
    printk(KERN_INFO "%s\n",__func__);
    return 0;
}
 
int mydrv_remove(struct device *dev)
{
    printk(KERN_INFO "%s\n",__func__);
    return 0;
}

static int mydrv_init(void)
{
    int ret = 0;

    mydrv = kzalloc(sizeof(*mydrv), GFP_KERNEL);
    mydrv->name = "testdevice";
    mydrv->bus = &testbus;
    mydrv->probe = mydrv_probe;
    mydrv->remove = mydrv_remove;

    ret = driver_register(mydrv);

    return ret;
}
 
static void mydrv_exit(void)
{
    printk(KERN_ALERT "%s\n",__func__);
    driver_unregister(mydrv);
    kfree(mydrv);
}
 
module_init(mydrv_init);
module_exit(mydrv_exit);
MODULE_LICENSE("GPL");

device代码

extern struct bus_type testbus;
struct device* mydev;

static void mydev_release(struct device *dev)
{
    printk(KERN_INFO "%s\n",__func__);
}
 
static int mydev_init(void)
{
    int ret = 0;
    mydev = kzalloc(sizeof(*mydev), GFP_KERNEL);
    mydev->init_name = "testdevice";
    mydev->bus  = &testbus;
    mydev->release = mydev_release;

    ret = device_register(mydev);

    return ret;
}
 
static void mydev_exit(void)
{
    printk(KERN_INFO "%s\n",__func__);
    device_unregister(mydev);
    kfree(mydev);
}
 
module_init(mydev_init);
module_exit(mydev_exit);
MODULE_LICENSE("GPL");


[邮箱] :(liulf_pc@126.com)
[CSDN] :https://blog.csdn.net/qqstring
[仓库地址] :https://gitee.com/stringliulf/char_driver.git

相关文章

  • linux_bus驱动

    由于没有经过完整测试代码中可能会有不足之出,如有网友发现还请斧正这是一个学习文档,所有代码仅供学习使用,请勿在生产...

  • Windows 安装完新系统应该

    驱动360驱动大师_360安全中心、全面检测、驱动检测、驱动下载、驱动管理、驱动安装、驱动升级、驱动备份、驱动还原...

  • 创业成功靠什么

    创业成功的九大驱动力:技术驱动、创新驱动、产品驱动、商业模式驱动、品牌驱动、IP驱动、运营驱动、融资驱动、格局(战...

  • Linux驱动模块编译

    Linux 对大多数的驱动作了分类:块设备驱动、网络驱动、I 2 C 驱动、USB 驱动、SPI 驱动、音频驱动等...

  • 《小群效应》读书笔记

    一、社群效应背后的六大驱动力: 荣誉驱动,利益驱动,关系驱动,事件驱动,地域驱动,兴趣驱动 群的初步形成往往基于除...

  • 冲床机械手所用的4种驱动机构主要有哪些?

    冲床机械手所用的驱动机构主要有4种:液压驱动、气压驱动、电气驱动和机械驱动。其中以液压驱动、气压驱动用得最多。下面...

  • 明远运营读书会5-9打卡

    读《小群效应》 1)激发人的六大驱动力,分别为利益驱动,荣誉驱动,关系驱动,地狱驱动,兴趣驱动和事件驱动。 2)人...

  • 小研05:关于等保2.0市场空间测算的思考

    网络安全行业主要的驱动因素包括合规驱动、事件驱动、技术驱动、业务驱动,其中合规驱动和事件驱动在当前阶段影响最大。预...

  • 品牌从0到1有5套模型

    ——产品驱动、运营驱动、品牌驱动、内容驱动和红人驱动。 产品驱动:品牌产品基因特别强,凭借品质高、功能性强的单品盈...

  • 文化公式

    内行驱动<(权势驱动+利益驱动)=文化荒漠

网友评论

    本文标题:linux_bus驱动

    本文链接:https://www.haomeiwen.com/subject/hluxbftx.html