1. Linux2.6内核引入总线、设备、驱动模型来描述各种总线(PCI、USB、I2C、SPI)与外围设备及其驱动之间的关系。

2. 在Linux内核中,总线用bus_type结构来描述,定义于文件:include/linux/Device.h

struct bus_type {
const char *name;
struct bus_attribute *bus_attrs;
struct device_attribute *dev_attrs;
struct driver_attribute *drv_attrs; int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
int (*remove)(struct device *dev);
void (*shutdown)(struct device *dev); int (*suspend)(struct device *dev, pm_message_t state);
int (*suspend_late)(struct device *dev, pm_message_t state);
int (*resume_early)(struct device *dev);
int (*resume)(struct device *dev); struct dev_pm_ops *pm; struct bus_type_private *p;
};

① name:总线名字,如PCI

② bus_attrs:总线属性

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

④ uevent:

⑤ probe:

⑥ remove:

(1) 总线的注册:int us_register(struct bus_type *bus)(若注册成功,新的总线将被添加进系统,可在/sys/bus 下看到相应的目录)

(2) 总线的注销:void bus_unregister(struct bus_type *bus)

3. 在Linux内核中, 驱动由device_driver结构描述

struct device_driver {
const char *name;
struct bus_type *bus; struct module *owner;
const char *mod_name; /* used for built-in modules */ int (*probe) (struct device *dev);
int (*remove) (struct device *dev);
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
struct attribute_group **groups; struct dev_pm_ops *pm; struct driver_private *p;
};

① probe:

② remove:

(1)驱动的注册:int driver_register(struct device_driver *drv)

(2)驱动的注销:void driver_unregister(struct device_driver *drv)

4. 在Linux内核中, 设备由struct device结构描述

struct device {
struct klist klist_children;
struct klist_node knode_parent; /* node in sibling list */
struct klist_node knode_driver;
struct klist_node knode_bus;
struct device *parent; struct kobject kobj;
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
unsigned uevent_suppress:;
const char *init_name; /* initial name of the device */
struct device_type *type; struct semaphore sem; /* semaphore to synchronize calls to
* its driver.
*/ struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
struct dev_pm_info power; #ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
u64 *dma_mask; /* dma mask (if dma'able device) */
u64 coherent_dma_mask;/* Like dma_mask, but for
alloc_coherent mappings as
not all hardware supports
64 bit addresses for consistent
allocations such descriptors. */ struct device_dma_parameters *dma_parms; struct list_head dma_pools; /* dma pools (if dma'ble) */ struct dma_coherent_mem *dma_mem; /* internal for coherent mem
override */
/* arch specific additions */
struct dev_archdata archdata; dev_t devt; /* dev_t, creates the sysfs "dev" */ spinlock_t devres_lock;
struct list_head devres_head; struct klist_node knode_class;
struct class *class;
struct attribute_group **groups; /* optional groups */ void (*release)(struct device *dev);
};

(1)设备的注册:int device_register(struct device *dev)

(2)设备的注销:void device_unregister(struct device *dev)

5. 简单示例

(1)Bus.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h> MODULE_LICENSE("GPL"); int my_match(struct device *dev, struct device_driver *drv)
{
printk("Bus: my_match\n");
return !strncmp(dev->kobj.name, drv->name, strlen(drv->name));
} int my_remove(struct device *dev)
{
printk("Bus: Device %s removed from bus\n", dev->init_name);
} struct bus_type my_bus_type = {
.name = "my_bus",
.match = my_match,
.remove = my_remove,
}; EXPORT_SYMBOL(my_bus_type); int my_bus_init(void)
{
int ret; ret = bus_register(&my_bus_type); return ret;
} void my_bus_exit(void)
{
bus_unregister(&my_bus_type);
} module_init(my_bus_init);
module_exit(my_bus_exit);

(2)Device.c

#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; void my_release(struct device *dev)
{
printk("Device: Device %s's release function\n", dev->init_name);
} struct device my_dev = {
.init_name = "my_dev",
.bus = &my_bus_type,
.release = my_release,
}; int my_device_init(void)
{
int ret;
ret = device_register(&my_dev);
return ret;
} void my_device_exit(void)
{
device_unregister(&my_dev);
} module_init(my_device_init);
module_exit(my_device_exit);

(3)Driver.c

#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; int my_probe(struct device *dev)
{
printk("Driver: driver found the device it can handle!\n");
return ;
} struct device_driver my_driver = {
.name = "my_dev",
.bus = &my_bus_type,
.probe = my_probe,
}; int my_driver_init(void)
{
int ret; ret = driver_register(&my_driver); return ret;
} void my_driver_exit(void)
{
driver_unregister(&my_driver);
} module_init(my_driver_init);
module_exit(my_driver_exit);

Linux总线设备驱动模型的更多相关文章

  1. Linux中总线设备驱动模型及平台设备驱动实例

    本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...

  2. Linux的总线设备驱动模型

    裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同: 而Linux中还需要按照Linux的驱动模型来编写,也就是需要按照"模板"来写,写出来的驱动就比较统一. ...

  3. Linux学习 : 总线-设备-驱动模型

    platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为pl ...

  4. usb驱动开发4之总线设备驱动模型

    在上文说usb_init函数,却给我们留下了很多岔路口.这次就来好好聊聊关于总线设备驱动模型.这节只讲理论,不讲其中的函数方法,关于函数方法使用参考其他资料. 总线.设备.驱动对应内核结构体分别为bu ...

  5. 总线设备驱动模型---platform篇

    总线设备驱动模型----驱动篇 http://blog.chinaunix.net/uid-27664726-id-3334923.html http://blog.chinaunix.net/uid ...

  6. Linux 字符设备驱动模型

    一.使用字符设备驱动程序 1. 编译/安装驱动 在Linux系统中,驱动程序通常采用内核模块的程序结构来进行编码.因此,编译/安装一个驱动程序,其实质就是编译/安装一个内核模块 2. 创建设备文件 通 ...

  7. Linux I2C总线设备驱动模型分析(ov7740)

    1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...

  8. Linux内核驱动学习(四)Platform设备驱动模型

    Linux platform设备驱动模型 文章目录 Linux platform设备驱动模型 前言 框架 设备与驱动的分离 设备(device) 驱动(driver) 匹配(match) 参考 前言 ...

  9. Linux混杂设备驱动

    1. Linux混杂设备驱动模型 ① 在Linux系统中,存在一类字符设备,它们拥有相同的主设备号(10),但次设备号不同,我们称这类设备为混杂设备(miscdevice).所有混杂设备形成一个链表, ...

随机推荐

  1. 在Windows 8上安装SQL Server2012

    SQL Server 2012 的安装方法跟2008差不多,基本上都是点击下一步,不过在安装的时候可能会进度条一直停留在“正在启动操作系统功能”NetFx3””处不动,出现这个问题的原因是在Windo ...

  2. 前端基础 之 Bootstrap框架

    浏览目录 Bootstrap介绍 为什么要使用Bootstrap? Bootstrap环境搭建 布局容器 栅格系统 Bootstrap全局样式 一.Bootstrap介绍 Bootstrap是Twit ...

  3. Part7-时钟初始化_lesson1

    1.概念解析 1.1时钟脉冲信号 1.2时钟脉冲频率 1.3时钟源(提供时钟脉冲信号) a.晶振 b.锁相环PLL 2.时钟体系 2440: 晶振的频率.时钟体系有多少个PLL.这些PLL分别产生了哪 ...

  4. Git教程--廖雪峰

    Git简介 1.Git是目前世界上最先进的分布式版本控制系统(没有之一) 2.集中式和分布式版本控制系统有什么区别呢?      区别在于历史版本维护的位置:Git本地仓库包含代码库还有历史库,在本地 ...

  5. FreeMarker的实例通俗理解

    1.把包lib/freemarker.jar拷贝到项目中 2.  在WEB-INF下新建文件夹templates  在templates下新建test.ftl文件 内容为: <html> ...

  6. easyui SWFUpload

    业务背景:实现一个用药人的增加功能,用药人信息中包含附件.如题所示,主要讨论easyui上传的实现.jsp页面代码(弹出框),一个简单的增加页面 div id=addMedicationDlg cla ...

  7. Unity本地持久化类Playerprefs使用详解

    一.PlayerPrefs是什么? PlayerPrefs是Unity3d提供了一个用于数据本地持久化保存与读取的类.工作原理十分简单,就是以key-value的形式将数据保存在本地,然后在代码中可以 ...

  8. ZeroSSL,支持多域名的在线 Let's Encrypt SSL 证书申请工具

    前言: 微信需要ssl证书,很多网站都有免费一年的证书:免费一年的证书叫做单域名证书,iis没办法配置多个子站点443端口:我有很多客户需要用我的的域名,同一个域名配置多个ssl,或者支持多个子域名: ...

  9. 从头开始学eShopOnContainers——开发环境要求

    一.简介 eShopOnContainers是一个简化版的基于.NET Core和Docker等技术开发的面向微服务架构的参考应用,是一个简化版的在线商城/电子商务应用,其包含基于浏览器的Web应用. ...

  10. WinForm中ListBox的使用

    获取选中数据:listbox.SelectedItem as XXX 重绘每一行item DrawMode设置为DrawMode.OwnerDrawVariable 然后实现DrawItem(obje ...