驱动总线

在Linux系统中,除了硬件总线,还有一种软件虚拟出来的总线 – 驱动总线bus
这种驱动总线的作用:软件与硬件代码分离,提高程序的复用性

驱动总线分三个部分: 三者都是在/include/linux/device.h中定义

  • device - 关联硬件代码
struct device
  • device_driver - 关联软件代码
struct device_driver
  • bus_type - 管理总线,设置匹配规则,devicedevice_driver通过匹配规则进行匹配,匹配成功struct device_driver中的probe()函数就会被执行
  struct bus_type

总线初始化

int __init buses_init(void)
{bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);if (!bus_kset)return -ENOMEM;system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);if (!system_kset)return -ENOMEM;return 0;
}

内核启动该函数会被执行进而初始化驱动总线
总线初始化后会在会创建总线对应的/sys/bus/ 目录


总线注册/卸载

1、注册新的总线:

int bus_register(struct bus_type *bus);

2、卸载总线:

void bus_unregister(struct bus_type *bus)

设备注册/卸载

1、设备注册:添加设备,关联硬件相关代码

int device_register(struct device *dev)

2、设备卸载:

void device_unregister(struct device *dev)

驱动注册/卸载

**1、驱动注册:**添加驱动,关联软件相关代码

int driver_register(struct device_driver *drv)

2、驱动卸载:

void driver_unregister(struct device_driver *drv)

注册新总线实验

1、总线注册

#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>//设置的device和driver的匹配规则  : 设置通过名字匹配
int xbus_match(struct device *dev, struct device_driver *drv)
{if (strcmp(dev_name(dev), drv->name) == 0)   /* 匹配成功 */{printk("xbus device & driver match success\r\n");      return 1;        }return 0;
}static struct bus_type xbus = {.name = "xbus",                                 //注册名为xbus的总线.match = xbus_match,
};EXPORT_SYMBOL(xbus);                               //导出xbus全局符号static int __init  xbus_init(void)
{int ret = bus_register(&xbus);                //注册xbus总线printk("register xbus\r\n");return ret;
}static void __exit xbus_exit(void)
{bus_unregister(&xbus);                        //卸载xbus总线printk("unregsiter xbus\r\n");
}module_init(xbus_init);
module_exit(xbus_exit);MODULE_LICENSE("GPL");

2、注册设备

#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>extern struct bus_type xbus;                         // 注册的xbus总线//device被卸载时被执行
static void xbus_device_release(struct device *dev)
{printk("xbus device relase\r\n");printk("%s %s\r\n", __FILE__, __func__);
}static struct device xbus_dev = {.init_name = "xbusdev",                   .bus = &xbus,                                  //device关联注册的xbus总线.release = xbus_device_release,
};static int __init xbus_device_init(void)
{int ret = device_register(&xbus_dev);         //注册devicereturn ret;
}static void __exit xbus_device_exit(void)
{device_unregister(&xbus_dev);                //卸载deviceprintk("xbus_device exit\r\n");
}module_init(xbus_device_init);
module_exit(xbus_device_exit);MODULE_LICENSE("GPL");

3、注册驱动

#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>extern struct bus_type xbus;                         // 注册的xbus总线//device和driver匹配成功该函数就会被执行
static int xdrv_probe(struct device *dev)
{printk(KERN_INFO"%s-%s\n", __FILE__, __func__);return 0;
}//驱动被卸载时执行
static int xdrv_remove(struct device *dev)
{printk(KERN_INFO"%s-%s\n", __FILE__, __func__);return 0;
}static struct device_driver xbus_drv = {.name = "xbusdev",.bus = &xbus,.probe = xdrv_probe,.remove = xdrv_remove,
};static int __init xbus_drv_init(void)
{printk(KERN_INFO"xbus driver init\n");driver_register(&xbus_drv);return 0;
}static void __exit xbus_drv_exit(void)
{printk(KERN_INFO"xbus driver exit\n");driver_unregister(&xbus_drv);
}module_init(xbus_drv_init);
module_exit(xbus_drv_exit);MODULE_AUTHOR("Ares");
MODULE_LICENSE("GPL");

注册的总线xbus是通过名字匹配,device的名字设置为.init_name = "xbusdev",所以driver的名字(.name = "xbusdev")设置成和device一样

4、编译模块

KERNEL_DIR=/home/ares/ebf-buster-linux/ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export  ARCH  CROSS_COMPILEobj-m += xbus.o xbus_device.o xbus_driver.o
all:$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules.PHONE:cleanclean:$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean

5、加载模块

1、总线模块  sudo insmod xbus.ko
2、device   sudo insmod xbus_device.ko
3、driver   sudo insmod xbus_driver.ko

查看打印的调试信息内核消息:

[39477.494030] xbus driver init
[39477.494092] xbus device & driver match success      //device 和 driver匹配成功
[39477.494172] /home/ares/drivers_learning/xbus/xbus_driver.c-xdrv_probe  //device和driver匹配成功执行xdrv_probe函数

查看/sys/bus/目录:

 ls /sys/bus/

有了一个和注册的xbus总线对应的文件夹:

查看/sys/bus/xbus/目录下的内容:

devices目录 - 表示里面是挂载该总线的设备
drivers目录 - 表示里面是挂载在该总线的驱动

查看/sys/bus/xbus/devices和drivers目录下的内容:

两个目录的内容是一致,就是自己注册的xbusdev

6、卸载模块

1、sudo rmmod xbus_device.ko
2、sudo rmmod xbus_driver.ko
3、sudo rmmod xbus.ko         //由于xbus_device.ko和xbus_driver.ko依赖于xbus.ko,所以不能先卸载xbus.ko

查看打印的调试信息:

[40574.523079] /home/ares/drivers_learning/xbus/xbus_device.c xbus_device_release
[40574.523090] xbus_device exit
[40586.124660] xbus driver exit
[40592.489635] unregsiter xbus

Linux驱动学习笔记 -- 驱动总线实验相关推荐

  1. 【嵌入式环境下linux内核及驱动学习笔记-(16)linux总线、设备、驱动模型之input框架】

    目录 1.Linux内核输入子系统概念导入 1.1 输入设备工作机制 1.2 运行框架 1.3 分层思想 2.驱动开发步骤 2.1 在init()或probe()函数中 2.2 在exit()或rem ...

  2. 【嵌入式环境下linux内核及驱动学习笔记-(15-1)例程】

    目录 1.在APP直接调用标准文件IO操作I2C(针对学习笔记-15的15.3节) 1.1 mail.c 1.2 mpu6050.h 1.3 mpu6050.c 1.4 Makefile 2.以外称i ...

  3. Linux驱动学习笔记

    驱动学习笔记 1.字符设备驱动 Linux 驱动有两种运行方式 第一种就是将驱动编译进 Linux 内核中,这样当 Linux 内核启 动的时候就会自动运行驱动程序. 第二种就是将驱动编译成模块(Li ...

  4. Linux 驱动学习笔记 - beep(九)

    Linux 驱动学习笔记 - beep(九) 本系列均为正点原子 Linux 驱动的学习笔记, 以便加深笔者记忆.如读者想进一步学习,可以到正点原子官网中下载资料进行学习. 添加 pinctrl 节点 ...

  5. 转载:mongoDB java驱动学习笔记

    http://www.blogjava.net/watchzerg/archive/2012/09/22/388346.html mongoDB java驱动学习笔记 指定新mongo实例: Mong ...

  6. linux系统管理学习笔记之三----软件的安装

    linux系统管理学习笔记之三----软件的安装 2009-12-29 19:10:02 标签:linux 系统管理 [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 ...

  7. linux系统管理学习笔记之一-------linux解压缩命令

    linux系统管理学习笔记之一-------linux解压缩命令 2009-12-29 11:52:55 标签:linux tar [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接 ...

  8. 操作系统进程学习(Linux 内核学习笔记)

    操作系统进程学习(Linux 内核学习笔记) 进程优先级 并非所有进程都具有相同的重要性.除了大多数我们所熟悉的进程优先级之外,进程还有不同的关键度类别,以满足不同需求.首先进程比较粗糙的划分,进程可 ...

  9. linux系统管理学习笔记之八---进程与作业的管理

    linux系统管理学习笔记之八---进程与作业的管理 2010-01-05 13:00:42 标签:linux 进程 [推送到技术圈] 版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 ...

最新文章

  1. 第十七课.有向图模型与条件独立性
  2. 取存储过程output的取
  3. python编写赛车游戏单机版_使用Keras和DDPG玩赛车游戏(自动驾驶)
  4. 深入理解C代码中的注释
  5. mysql 数据库编程_MySQL数据库编程(C++语言)
  6. python绘图设置标题出现乱码_解决python2 绘图title,xlabel,ylabel出现中文乱码的问题...
  7. Python平衡点问题
  8. MySQL大批量数据插入
  9. python数据挖掘笔记】二十.KNN最近邻分类算法分析详解及平衡秤TXT数据集读取
  10. Vue项目使用AES做加密
  11. java中 获取classpath路径
  12. 科普:淘宝网的反爬虫变迁史
  13. YAML语法详细总结
  14. Java笔记——08.面向对象(中级)
  15. Android Banner图片轮播
  16. 法拉克机器人自动怎么调_FANUC机器人:参考位置功能介绍与设定方法
  17. Foxmail提示错误421 too many connections【企业邮箱申请】
  18. 如何取得UnityHub内旧版本Unity下载链接
  19. C++ - CString 用法
  20. 我的世界mysql插件_MySQL Inventory Bridge — 跨服背包[1.7-1.15]【Bukkit】

热门文章

  1. 用MS Windows 字体美化 Ubuntu(6.06)
  2. 你是把「热点」营销了,却没有营销到品牌
  3. 为高性价比代言的HKC神盾MG25H电竞显示器
  4. 高职副教授职称评定条件
  5. linux挂载ntfs移动硬盘
  6. URL进行实例化时 参数带有中文问题
  7. uniapp项目添加阿里图标库字体图标(图标在手机、浏览器均可查看)
  8. 基础会计学习笔记12
  9. 清华大学计算机学院曹伦郗,四川文理第一名填报北大 来看看高分“学霸”们最后选了啥专业...
  10. 在linux返回目录并查看,Linux命令(十四) 查看工作目录文件 ls