如何实现Linux设备驱动模型
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
文库资料©2017 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
如何实现Linux 设备驱动模型
设备驱动模型,对系统的所有设备和驱动进行了抽象,形成了复杂的设备树型结构,采用面向对象的方法,抽象出了device 设备、driver 驱动、bus 总线和class 类等概念,所有已经注册的设备和驱动都挂在总线上,总线来完成设备和驱动之间的匹配。总线、设备、驱动以及类之间的关系错综复杂,在Linux 内核中通过kobject 、kset 和subsys 来进行管理,驱动编写可以忽略这些管理机制的具体实现。
设备驱动模型的内部结构还在不停的发生改变,如device 、driver 、bus 等数据结构在不同版本都有差异,但是基于设备驱动模型编程的结构基本还是统一的。
Linux 设备驱动模型是Linux 驱动编程的高级内容,这一节只对device 、driver 等这些基本概念作介绍,便于阅读和理解内核中的代码。实际上,具体驱动也不会孤立的使用这些概念,这些概念都融合在更高层的驱动子系统中。对于大多数读者可以忽略这一节内容。 1.1.1 设备
在Linux 设备驱动模型中,底层用device 结构来描述所管理的设备。device 结构在文件
程序清单错误!文档中没有指定样式的文字。.1 device 数据结构定义
struct device {
struct device *parent; /* 父设备
*/ struct device_private *p; /* 设备的私有数据 */ struct kobject
kobj; /* 设备的kobject 对象 */ const char *init_name; /*设备的初始名字 */ struct device_type *type;
/* 设备类型
*/ struct mutex mutex; /*同步驱动的互斥信号量 */ struct bus_type *bus; /*设备所在的总线类型 */ struct device_driver *driver; /*管理该设备的驱动程序
*/ void
*platform_data;
/*平台相关的数据 */ struct dev_pm_info
power;
/* 电源管理
*/
#ifdef CONFIG_NUMA int numa_node; /*设备接近的非一致性存储结构
*/ #endif
u64 *dma_mask; /* DMA 掩码
*/ u64 coherent_dma_mask; /*设备一致性的DMA 掩码
*/
struct device_dma_parameters *dma_parms; /* DMA 参数
*/ struct list_head
dma_pools; /* DMA 缓冲池
*/ struct dma_coherent_mem
*dma_mem; /* DMA 一致性内存 */ /*体系结构相关的附加项*/ struct dev_archdata archdata;
/* 体系结构相关的数据
*/ #ifdef CONFIG_OF
文库资料©2017 Guangzhou ZHIYUAN Electronics Stock Co., Ltd.
注册和注销device 的函数分别是device_register()和device_unregister(),函数原型如下:
int __must_check device_register(struct device *dev); void device_unregister(struct device *dev);
大多数不会在驱动中单独使用device 结构,而是将device 结构嵌入到更高层的描述结构中。例如,内核中用spi_device 来描述SPI 设备,spi_device 结构在
程序清单错误!文档中没有指定样式的文字。.2 spi_device 数据结构
struct spi_device {
struct device dev;
/* device 数据结构
*/
struct spi_master *master; u32 max_speed_hz; u8 chip_select; u8 mode; u8 bits_per_word; int irq;
void *controller_state; void *controller_data; char modalias[SPI_NAME_SIZE];
};
系统提供了device_create()函数用于在sysfs/classs 中创建dev 文件,以供用户空间使用。device_create()函数定义如下:
struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);
说明:
● cls 是指向将要被注册的class 结构; ● parent 是设备的父指针; ● devt 是设备的设备编号;
● drvdata 是被添加到设备回调的数据; ● fmt 是设备的名字。