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).所有混杂设备形成一个链表, ...
随机推荐
- 第一次C语言作业:博客随笔
1)你觉得大学和高中有什么差别?具体学习上哪? 大学自主学习较多,锻炼自己独立的品质.在学习上,增加了课程的深度和难度,由更多的活动. 2)我希望大学的师生关系是?阅读上述博客后对师生关系有何感想? ...
- 《架构师杂志》评述:Scott Guthrie
发布日期: 2007-03-29 | 更新日期: 2007-03-29 Scott Guthrie 是 Microsoft 开发事业部的总经理.他领导着负责构建 CLR(公共语言运行库).ASP. ...
- Vivado生成edf文件
https://china.xilinx.com/support/answers/54074.html 综合完成后会跳出个框框,选择open synthesis write_edif module. ...
- (转)QueryBuilder : 打造优雅的Linq To SQL动态查询
原文地址:http://www.cnblogs.com/coolcode/archive/2009/09/28/IQueryBuilder.html 首先我们来看看日常比较典型的一种查询Form 这个 ...
- DELPHI XE5 UP2 运行IOS 遇到 Wrapper init failed: (null)问题的解决办法
一.问题表现: 在MAC OSX(10.9.2)上安装了比较新的XCODE5.1 和COMMAND LINE TOOLS 在DELPHI XE5 UP2上放了一个按钮,输出到MAC OSX上,出现: ...
- .NET和C#的版本历史
维基百科页面:https://en.wikipedia.org/wiki/.NET_Framework_version_history Versionnumber CLRversion Release ...
- Android学习笔记 ImageSwitcher图片切换组件的使用
activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu ...
- 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计
类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...
- js 封装常用方法
1. 获取数据类型 function getType(params) { , -) } 2. 深拷贝 function deepCopy(params) { var obj; if (typeof p ...
- hbase0.92 数据修复
现有集群环境:8台region server.1台master server 早晨重启某一region server后,该server的region全部下线未恢复. 重启前 hbase(main):0 ...