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. TreeView的绑定与读取

    /// <summary>        /// 绑定TreeView        /// </summary>        public void BindTreeVie ...

  2. Django框架 之 基于Ajax中csrf跨站请求伪造

    Django框架 之 基于Ajax中csrf跨站请求伪造 ajax中csrf跨站请求伪造 方式一 1 2 3 $.ajaxSetup({     data: {csrfmiddlewaretoken: ...

  3. numpy.loadtxt() 出现codecError_____ Excel 做矩阵乘法

    1) 用 numpy读入csv文件是报错 UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal m ...

  4. css总结13:CSS 伪类(Pseudo-classes)

    1 伪类作用:CSS伪类是用来添加一些选择器的特殊效果. 2 常用示例: 2.1anchor伪类:代码:   正常语法: a{color:#FF0000;}/* 文字颜色 */   伪类语法: a:l ...

  5. whereis libjpeg.so.7

    在服务器上调用import ImageFont时报如下错误 ImportError: The _imagingft C module is not installed (服务器为Centos5.5, ...

  6. 干掉MessageBox,自定义弹出框JMessbox (WindowsPhone)

    先上效果图                                               QQ退出效果                                           ...

  7. vitamio遇到的坑,都是不能播放

    在模拟器上可以运行,在真机上不能用,一点就app全退了,不知原因,没办法用as连接到真机上调试,才发现是版本过高的原因,不支持sdk 23,大家的办法都是改成21, targetSdkVersion ...

  8. luoguP4868 Preprefix sum

    https://www.luogu.org/problemnew/show/P4868 线段树上加等差数列,基础区间修改单点查询 等差数列具有可加性,当在同一段区间内时,首项相加公差相加即可 #inc ...

  9. request payload

    最近在调试代码时发现有Request Payload的情况,从网上查一些文件,也都有较多的描述.下面我只是说明一下大家没有注意的地方 关于HTTP请求,都是通过URL及参数向后台发送数据.主要方式有G ...

  10. CodeForces - 233A Perfect Permutation

    A. Perfect Permutation time limit per test: 2 seconds memory limit per test: 256 megabytes input: st ...