Linux总线设备驱动模型
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总线设备驱动模型的更多相关文章
- Linux中总线设备驱动模型及平台设备驱动实例
本文将简要地介绍Linux总线设备驱动模型及其实现方式,并不会过多地涉及其在内核中的具体实现,最后,本文将会以平台总线为例介绍设备和驱动程序的实现过程. 目录: 一.总线设备驱动模型总体介绍及其实现方 ...
- Linux的总线设备驱动模型
裸机编写驱动比较自由,按照手册实现其功能即可,每个人写出来都有很大不同: 而Linux中还需要按照Linux的驱动模型来编写,也就是需要按照"模板"来写,写出来的驱动就比较统一. ...
- Linux学习 : 总线-设备-驱动模型
platform总线是一种虚拟的总线,相应的设备则为platform_device,而驱动则为platform_driver.Linux 2.6的设备驱动模型中,把I2C.RTC.LCD等都归纳为pl ...
- usb驱动开发4之总线设备驱动模型
在上文说usb_init函数,却给我们留下了很多岔路口.这次就来好好聊聊关于总线设备驱动模型.这节只讲理论,不讲其中的函数方法,关于函数方法使用参考其他资料. 总线.设备.驱动对应内核结构体分别为bu ...
- 总线设备驱动模型---platform篇
总线设备驱动模型----驱动篇 http://blog.chinaunix.net/uid-27664726-id-3334923.html http://blog.chinaunix.net/uid ...
- Linux 字符设备驱动模型
一.使用字符设备驱动程序 1. 编译/安装驱动 在Linux系统中,驱动程序通常采用内核模块的程序结构来进行编码.因此,编译/安装一个驱动程序,其实质就是编译/安装一个内核模块 2. 创建设备文件 通 ...
- Linux I2C总线设备驱动模型分析(ov7740)
1. 框架1.1 硬件协议简介1.2 驱动框架1.3 bus-drv-dev模型及写程序a. 设备的4种构建方法a.1 定义一个i2c_board_info, 里面有:名字, 设备地址 然后i2c_r ...
- Linux内核驱动学习(四)Platform设备驱动模型
Linux platform设备驱动模型 文章目录 Linux platform设备驱动模型 前言 框架 设备与驱动的分离 设备(device) 驱动(driver) 匹配(match) 参考 前言 ...
- Linux混杂设备驱动
1. Linux混杂设备驱动模型 ① 在Linux系统中,存在一类字符设备,它们拥有相同的主设备号(10),但次设备号不同,我们称这类设备为混杂设备(miscdevice).所有混杂设备形成一个链表, ...
随机推荐
- 《架构师杂志》评述:Scott Guthrie
发布日期: 2007-03-29 | 更新日期: 2007-03-29 Scott Guthrie 是 Microsoft 开发事业部的总经理.他领导着负责构建 CLR(公共语言运行库).ASP. ...
- ASP.NET伪静态配置
一.下载URLRewriter.dll 二.在项目中添加URLRewrite的引用 三.配置webconfig 1.在<configuration>节点中添加: <configSec ...
- unity中播放视频
unity中播放视频步骤如下: 1.将要播放的视频拖入projec.(注意:unity一般支持的视频格式有mov, .mpg, .mpeg, .mp4,.avi, .asf格式 ) 2.在场景中添加 ...
- Unity5.5.2 CD旋转 顺时针逆时针
UGUI 下 Sprite_CD 在Inspector下 Image(Script) 下 Clock wise 勾选 决定 CD是顺时针还是逆时针 默认是顺时针 勾选则为逆时针
- Android学习笔记 TextSwitcher文本切换组件的使用
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- 八、Node.js-http模块
JS代码如下: /* 如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi,来处理客户端的请求相应. 不过对 N ...
- MongoDB 副本集配置,开启账号认证
MongoDB 自带功能强大的主从,配置也很简单,从零开始花了30分钟搞定 3台以上机器IP: 192.168.1.24, 192.168.1.25, 192.168.1.26, 192.168.1. ...
- django 实现电子支付功能
思路:调用第三方支付 API 接口实现支付功能.本来想用支付宝来实现第三方网站的支付功能的,但是在实际操作中发现支付宝没有 Python 接口,网上虽然有他人二次封装的的 Python 接口,但是对我 ...
- django自定义rbac权限组件(二级菜单)
一.目录结构 二.表结构设计 model.py from django.db import models # Create your models here. class Menu(models.Mo ...
- Httprequest 添加Cookie
string postData = "Inputs={\"BarCode\":\"" + barCode + "\"}" ...