第五十讲 自定义总线(xbus)
第五十讲 自定义总线(xbus)
文章目录
- 第五十讲 自定义总线(xbus)
- 一、概述
- 二、重要函数
- 1、buses_init
- 2、bus_register
- 3、device_register
- 4、driver_register
- 三、xbus实验
- 1、代码
- 2、实验步骤
一、概述
前面的几个驱动代码软件和硬件都是夹杂在一起的,这样就会使得驱动的复用性比较低。Bus是链接处理器和其他设备之间的通道。内核规定,系统中的每个设备都要连接在一个Bus上,这个Bus可以是一个内部Bus、虚拟Bus或者Platform Bus。前面的驱动通过引入驱动总线,将硬件相关与软件相关的代码进行分离,将结构体device关联硬件相关代码,将driver_devices关联软件代码,通过设置match匹配规则,使用bus_type对设备进行统一管理。
二、重要函数
1、buses_init
这个函数实在linux启动的时候就自动执行的,主要是建立Linux设备模型总线部分的顶级节点。buses_init函数建立了/sys/bus这个顶级容器节点,该节点是Linux内核中所有总线类型的父节点。
2、bus_register
原型:int bus_register(struct bus_type *bus)
作用:(添加一个新的总线类型)
在/sys/bus下建立xbus目录项,并创建属性文件
在/sys/bus/xbus下建立devices目录项,并创建属性文件
在/sys/bus/xbus下建立drivers目录项,并创建属性文件
初始化 priv->klist_devices链表头
初始化priv->klist_drivers链表头
3、device_register
原型:int device_register(struct device *dev)
作用:(添加设备,关联硬件相关代码)
在/sys/bus/xbus/devices下建立yyy目录项
加入bus-> priv->devices_kset链表
加入bus-> priv->klist_devices链表
遍历bus-> priv->klist_drivers,执行bus->match()寻找合适的drv
dev关联driv,执行drv->probe()
4、driver_register
原型:int driver_register(struct device_driver *drv)
作用:(添加驱动,关联软件相关代码)
在/sys/bus/xbus/drivers下建立zzz目录项
加入bus-> priv->drivers_kset链表
加入bus-> priv->klist_drivers链表
遍历bus-> priv->klist_klist_devices链表,执行bus->match()寻找合适的dev
dev关联dev,执行drv->probe()
三、xbus实验
1、代码
xbus.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h>/*
*本文件主要是添加一个新的总线类型
*/
/*
*match 规则
*/
int match(struct device *dev, struct device_driver *drv)
{if(strncmp(dev_name(dev), drv->name, strlen(drv->name))){printk(KERN_ERR"xBus match failed!\r\n");return 0;}printk(KERN_ERR"xBus match successed!\r\n");return 1;
}
/*初始化设备*/
static struct bus_type xBus =
{.name = "xBus",.match = match,
};
static int __init xBusInit(void)
{printk(KERN_ERR"Enter xBus init functions\r\n");if(bus_register(&xBus)){printk(KERN_ERR"Enter xBus init failed!\r\n");return -1;}return 0;
}
static void __exit xBusExit(void)
{printk(KERN_ERR"Exit xBus init functions\r\n");return ;
}/*声明外部调用*/
EXPORT_SYMBOL (xBus);
/*声明函数*/
module_init(xBusInit);
module_exit(xBusExit);/**/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yeyu");
MODULE_DESCRIPTION("xBus module!");
MODULE_ALIAS("xBus_module");
xdev.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>extern struct bus_type xBus;
/**/
void xDevRelease(struct device *dev)
{printk("%s-%s\n", __FILE__, __func__);
}
/*
*本文件主要是添加一个新的设备(硬件相关)
*/
static struct device dev =
{.init_name = "xbus_test",.bus = &xBus,.release = xDevRelease,
};
/*初始化设备*/
static int __init xDevInit(void)
{printk(KERN_ERR"Init xDev init functions\r\n");if(device_register(&dev)){printk(KERN_ERR"Init xDev init failed!\r\n");return -1;}return 0;
}static void __exit xDevExit(void)
{printk(KERN_ERR"Exit xDev init functions\r\n");return ;
}/*声明函数*/
module_init(xDevInit);
module_exit(xDevExit);/**/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yeyu");
MODULE_DESCRIPTION("xDev module!");
MODULE_ALIAS("xDev_module");
xdrv.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/module.h>extern struct bus_type xBus;int xDrvProbe(struct device *dev)
{printk(KERN_ERR"Match success!\r\n");return 0;
}
int xDrvRemove(struct device *dev)
{printk(KERN_ERR"Close xbus_test derver!\r\n");return 0;
}
/*
*本文件主要是添加一个新的设备(硬件相关)
*/
static struct device_driver xDrv =
{.name = "xbus_test",.bus = &xBus,//当驱动和设备匹配成功之后,便会执行驱动的probe函数.probe = xDrvProbe,//当注销驱动时,需要关闭物理设备的某些功能等.remove = xDrvRemove,
};
/*初始化设备*/
static int __init xDrvInit(void)
{printk(KERN_ERR"Init xDrv init functions\r\n");if(driver_register(&xDrv)){printk(KERN_ERR"Init xDrv init failed!\r\n");return -1;}printk(KERN_ERR"Init xDrv functions success!\r\n");return 0;
}static void __exit xDrvExit(void)
{printk(KERN_ERR"Exit xDrv init functions\r\n");return ;
}/*声明函数*/
module_init(xDrvInit);
module_exit(xDrvExit);/**/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Yeyu");
MODULE_DESCRIPTION("xDrv module!");
MODULE_ALIAS("xDrv_module");
Makefile
KERNEL_DIR=../../ebf_linux_kernel/build_image/build/ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-
export ARCH CROSS_COMPILEobj-m := xbus.o xdev.o xdrv.oall:$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) modules.PHONE:clean copyclean:$(MAKE) -C $(KERNEL_DIR) M=$(CURDIR) clean copy:sudo cp *.ko /home/dragon/nfsshare
2、实验步骤
编译代码
make
将ko文件复制到共享文件夹
make copy
打开开发板
登陆开发板
连接到远程文件夹(nfs)
sudo mount -t nfs 192.168.3.41:/home/dragon/nfsshare /mnt
加载模块(注意顺序)
命令
sudo insmod /mnt/xbus.ko
现象
xbus: loading out-of-tree module taints kernel. Enter xBus init functions
命令
sudo insmod /mnt/xdev.ko
现象
Init xDev init functions
命令
sudo insmod /mnt/xdrv.ko
现象
[ 94.381356] Init xDrv init functions [ 94.391380] xBus match successed! [ 94.398011] Match success! [ 94.409179] Init xDrv functions success!
第五十讲 自定义总线(xbus)相关推荐
- 《突破C#编程实例五十讲》源文件下载(2)
上接<<突破C#编程实例五十讲>源文件下载(1)> 有兴趣的朋友下载看看吧,一共有9个压缩包分3篇文章,下载要注意哦,不然解压要出错哦! 转载于:https://blog.51 ...
- 058_《突破Delphi7.0编程实例五十讲》
<突破Delphi7.0编程实例五十讲> Delphi 教程 系列书籍 (058) <突破Delphi7.0编程实例五十讲> 网友(邦)整理 EMail: shuaihj@16 ...
- Android Studio 第五十一期 - 自定义RecycleView Gallery
代码已经整理好,效果如下图:(支持Verical Horizontal 支持自定义放大位置 支持滚动速度) 图片1: 图片2: 地址: https://github.com/geeklx/MyAppl ...
- Android Studio 第五十期 - 自定义TabLayout
代码已经整理好,效果如下图: code1: <com.ui.widget.UnAnimTabLayoutandroid:id="@+id/tab"android:layout ...
- Java SE 第四十八,九,五十讲 Map深入详解及遍历Map的两种实现手段 Map.Entry详解与作业要求,作业讲解...
1.Map接口:Map的实现类:HashMap类 Map没有add()方法,但是有put()方法. put()将指定的值关联到map中的特定key. 2.HashMap类: 3.vice versa: ...
- 高等数学学习笔记——第五十讲——可降阶的高阶微分方程
1. 问题引入--悬链线问题.从地面垂直向上发射火箭问题需要解二阶微分方程 2. 可降阶的高阶微分方程 3. 另外两种类型的高阶微分方程 4. 微分方程应用实例--悬链线问题的条件量化及建模 5. 悬 ...
- 第五十讲:神州路由器IPv6隧道的配置
目前IPv6隧道技术有ISATAP隧道.6to4隧道.IPv6 over MPL隧道等. 任务一:配置ISATAP隧道 实验拓扑图如下所示 配置要求:两台路由器ROUTERA和ROUTERB通过IPv ...
- 线性代数学习笔记——第五十讲——最大无关组的性质和等价叙述
1. 最大无关组及秩的概念回顾 2. 判断部分无关组恰为最大无关组的方法 3. 最大无关组示例 4. 最大无关组的应用示例 5. 矩阵乘积的秩小于等于每个矩阵的秩的最小值
- 第五十二讲 DTS(设备树)
第五十二讲 DTS(设备树) 一.简介 随着硬件设备的种类逐年递增,板级platform平台设备文件越来越多.在过去的Linux中,arch/arm/plat-xxx和arch/arm/mach-xx ...
最新文章
- reporting Server組件不全引起的致命錯誤
- C语言函数集(十八)
- Linux core dump的详细介绍及使用
- 【设计原则和建议】 构造和析构对象
- According to TLD or attribute directive in tag file, attribute value does not accept any expressions
- oracle12数据库安装步骤,ORACLE RAC 12C(12.2.0.1)数据库软件安装步骤
- jQuery的概念、用法、常见面试题详解
- 【API进阶之路】用API打造一条自动化内容生产流水线
- UI帮手|小样机大作用
- centos7登陆mysql_Centos7安装Myql8.0并授权登录
- 三星oneui主屏幕费电_这或许是单手握持手感最佳的手机 三星Galaxy S20上手体验...
- linux怎么查看系统可用串口,linux串口驱动详解 如何查看linux下串口是否可用?串口名称等?...
- php eclipse 插件安装,phpeclipse插件下载-phpeclipse插件官方版 v1.2.3 官方最新版 - 安下载...
- iOS ApplePay paymentData 加解密 (待续)
- 浏览器看视频,加速脚本
- 查看 gmail 办法_如何在Gmail对话主题上查看新电子邮件
- [VB.NET]雪花飘的屏保
- sqldbx mysql 乱码_sqlDbx连接mysql 及乱码
- 谷歌浏览器webGL实验
- HTML+CSS实现网易云音乐首页的主播电台页面
热门文章
- 用树莓派计算模块搭建的工业单板计算机(转)
- hdu2389(HK算法)
- Python百度指数可视化分析实战案例1
- Vasya and Good Sequences (Codeforces Round #512) 后缀和
- 14-HTML-CSS案例
- 百度定位SDK 申请密钥步骤
- 在notepad++中安装jslint插件
- python飞机大战
- java stack (null -1)_关于单链表实现的一个stack的问题
- c语言五子棋源代码vc6,五子棋源码实验报告及人机对战说明.docx