第五十讲 自定义总线(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)相关推荐

  1. 《突破C#编程实例五十讲》源文件下载(2)

    上接<<突破C#编程实例五十讲>源文件下载(1)> 有兴趣的朋友下载看看吧,一共有9个压缩包分3篇文章,下载要注意哦,不然解压要出错哦! 转载于:https://blog.51 ...

  2. 058_《突破Delphi7.0编程实例五十讲》

    <突破Delphi7.0编程实例五十讲> Delphi 教程 系列书籍 (058) <突破Delphi7.0编程实例五十讲> 网友(邦)整理 EMail: shuaihj@16 ...

  3. Android Studio 第五十一期 - 自定义RecycleView Gallery

    代码已经整理好,效果如下图:(支持Verical Horizontal 支持自定义放大位置 支持滚动速度) 图片1: 图片2: 地址: https://github.com/geeklx/MyAppl ...

  4. Android Studio 第五十期 - 自定义TabLayout

    代码已经整理好,效果如下图: code1: <com.ui.widget.UnAnimTabLayoutandroid:id="@+id/tab"android:layout ...

  5. Java SE 第四十八,九,五十讲 Map深入详解及遍历Map的两种实现手段 Map.Entry详解与作业要求,作业讲解...

    1.Map接口:Map的实现类:HashMap类 Map没有add()方法,但是有put()方法. put()将指定的值关联到map中的特定key. 2.HashMap类: 3.vice versa: ...

  6. 高等数学学习笔记——第五十讲——可降阶的高阶微分方程

    1. 问题引入--悬链线问题.从地面垂直向上发射火箭问题需要解二阶微分方程 2. 可降阶的高阶微分方程 3. 另外两种类型的高阶微分方程 4. 微分方程应用实例--悬链线问题的条件量化及建模 5. 悬 ...

  7. 第五十讲:神州路由器IPv6隧道的配置

    目前IPv6隧道技术有ISATAP隧道.6to4隧道.IPv6 over MPL隧道等. 任务一:配置ISATAP隧道 实验拓扑图如下所示 配置要求:两台路由器ROUTERA和ROUTERB通过IPv ...

  8. 线性代数学习笔记——第五十讲——最大无关组的性质和等价叙述

    1. 最大无关组及秩的概念回顾 2. 判断部分无关组恰为最大无关组的方法 3. 最大无关组示例 4. 最大无关组的应用示例 5. 矩阵乘积的秩小于等于每个矩阵的秩的最小值

  9. 第五十二讲 DTS(设备树)

    第五十二讲 DTS(设备树) 一.简介 随着硬件设备的种类逐年递增,板级platform平台设备文件越来越多.在过去的Linux中,arch/arm/plat-xxx和arch/arm/mach-xx ...

最新文章

  1. reporting Server組件不全引起的致命錯誤
  2. C语言函数集(十八)
  3. Linux core dump的详细介绍及使用
  4. 【设计原则和建议】 构造和析构对象
  5. According to TLD or attribute directive in tag file, attribute value does not accept any expressions
  6. oracle12数据库安装步骤,ORACLE RAC 12C(12.2.0.1)数据库软件安装步骤
  7. jQuery的概念、用法、常见面试题详解
  8. 【API进阶之路】用API打造一条自动化内容生产流水线
  9. UI帮手|小样机大作用
  10. centos7登陆mysql_Centos7安装Myql8.0并授权登录
  11. 三星oneui主屏幕费电_这或许是单手握持手感最佳的手机 三星Galaxy S20上手体验...
  12. linux怎么查看系统可用串口,linux串口驱动详解 如何查看linux下串口是否可用?串口名称等?...
  13. php eclipse 插件安装,phpeclipse插件下载-phpeclipse插件官方版 v1.2.3 官方最新版 - 安下载...
  14. iOS ApplePay paymentData 加解密 (待续)
  15. 浏览器看视频,加速脚本
  16. 查看 gmail 办法_如何在Gmail对话主题上查看新电子邮件
  17. [VB.NET]雪花飘的屏保
  18. sqldbx mysql 乱码_sqlDbx连接mysql 及乱码
  19. 谷歌浏览器webGL实验
  20. HTML+CSS实现网易云音乐首页的主播电台页面

热门文章

  1. 用树莓派计算模块搭建的工业单板计算机(转)
  2. hdu2389(HK算法)
  3. Python百度指数可视化分析实战案例1
  4. Vasya and Good Sequences (Codeforces Round #512) 后缀和
  5. 14-HTML-CSS案例
  6. 百度定位SDK 申请密钥步骤
  7. 在notepad++中安装jslint插件
  8. python飞机大战
  9. java stack (null -1)_关于单链表实现的一个stack的问题
  10. c语言五子棋源代码vc6,五子棋源码实验报告及人机对战说明.docx