Linux Platform Device and Driver
从 Linux 2.6 起引入了一套新的驱动管理和注册机制 :Platform_device 和 Platform_driver 。
Linux 中大部分的设备驱动,都可以使用这套机制 , 设备用 Platform_device 表示,驱动用 Platform_driver 进行注册。
Linux platform driver 机制和传统的 device driver 机制 ( 通过 driver_register 函数进行注册 ) 相比,一个十分明显的优势在于 platform 机制将设备本身的资源注册进内核,由内核统一管理,在驱动程序中使用这些资源时通过 platform device 提供的标准接口进行申请并使用。这样提高了驱动和资源管理的独立性,并且拥有较好的可移植性和安全性 ( 这些标准接口是安全的 ) 。
Platform 机制的本身使用并不复杂,由两部分组成: platform_device 和 platfrom_driver 。
通过 Platform 机制开发发底层驱动的大致流程为 : 定义 platform_device --->注册 platform_device---> 定义 platform_driver --->注册platform_driver 。
首先要确认的就是设备的资源信息,例如设备的地址,中断号等。
在 2.6 内核中 platform 设备用结构体 platform_device 来描述,该结构体定义在 kernel/include/linux/platform_device.h 中,
struct platform_device {
const char * name;
u32 id;
struct device dev;
u32 num_resources;
struct resource * resource;
};
该结构一个重要的元素是 resource ,该元素存入了最为重要的设备资源信息,定义在 kernel/include/linux/ioport.h 中,
struct resource {
const char *name;
unsigned long start, end;
unsigned long flags;
struct resource *parent, *sibling, *child;
};
下面举 s3c2410 平台的 i2c 驱动作为例子来说明:
|
|
这里定义了两组 resource ,它描述了一个 I2C 设备的资源,第 1 组描述了这个 I2C 设备所占用的总线地址范围, IORESOURCE_MEM 表示第 1 组描述的是内存类型的资源信息,第 2 组描述了这个 I2C 设备的中断号, IORESOURCE_IRQ 表示第 2 组描述的是中断资源信息。设备驱动会根据 flags 来获取相应的资源信息。
有了 resource 信息,就可以定义 platform_device 了:
|
|
定义好了 platform_device 结构体后就可以调用函数 platform_add_devices 向系统中添加该设备了,之后可以调用 platform_driver_register() 进行设备注册。要注意的是,这里的 platform_device 设备的注册过程必须在相应设备驱动加载之前被调用,即执行 platform_driver_register 之前 , 原因是因为驱动注册时需要匹配内核中所以已注册的设备名。
s3c2410-i2c 的 platform_device 是在系统启动时,在 cpu.c 里的 s3c_arch_init() 函数里进行注册的,这个函数申明为 arch_initcall(s3c_arch_init);会在系统初始化阶段被调用。
arch_initcall 的优先级高于 module_init 。所以会在 Platform 驱动注册之前调用。 ( 详细参考 include/linux/init.h)
s3c_arch_init 函数如下:
|
|
同时被注册还有很多其他平台的 platform_device ,详细查看 arch/arm/mach-s3c2410/mach-smdk2410.c 里的 smdk2410_devices 结构体。
驱动程序需要实现结构体 struct platform_driver ,参考 drivers/i2c/busses
|
|
在驱动初始化函数中调用函数 platform_driver_register() 注册 platform_driver ,需要注意的是 s3c_device_i2c 结构中 name 元素和s3c2410_i2c_driver 结构中 driver.name 必须是相同的,这样在 platform_driver_register() 注册时会对所有已注册的所有 platform_device 中的 name和当前注册的 platform_driver 的 driver.name 进行比较,只有找到相同的名称的 platfomr_device 才能注册成功,当注册成功时会调用 platform_driver结构元素 probe 函数指针,这里就是 s3c24xx_i2c_probe, 当进入 probe 函数后,需要获取设备的资源信息,常用获取资源的函数主要是:
struct resource * platform_get_resource(struct platform_device *dev, unsigned int type, unsigned int num);
根据参数 type 所指定类型,例如 IORESOURCE_MEM ,来获取指定的资源。
struct int platform_get_irq(struct platform_device *dev, unsigned int num);
获取资源中的中断号。
下面举 s3c24xx_i2c_probe 函数分析 , 看看这些接口是怎么用的。
前面已经讲了, s3c2410_i2c_driver 注册成功后会调用 s3c24xx_i2c_probe 执行,下面看代码:
|
|
小思考:
那什么情况可以使用 platform driver 机制编写驱动呢?
我的理解是只要和内核本身运行依赖性不大的外围设备 ( 换句话说只要不在内核运行所需的一个最小系统之内的设备 ), 相对独立的 , 拥有各自独自的资源(addresses and IRQs) , 都可以用 platform_driver 实现。如: lcd,usb,uart 等,都可以用 platfrom_driver 写,而 timer,irq 等最小系统之内的设备则最好不用 platfrom_driver 机制,实际上内核实现也是这样的。
Linux Platform Device and Driver的更多相关文章
- [platform]linux platform device/driver(三)--Platform Device和Platform_driver注册过程之代码对比
转自:http://blog.csdn.net/thl789/article/details/6723350 Linux 2.6的设备驱动模型中,所有的device都是通过Bus相连.device_r ...
- [platform]Device和Driver注册顺序
1. 设备和驱动注册,无论谁先谁后,都可以通过查询总线进行匹配 设备挂接到总线上时,与总线上的所有驱动进行匹配(用bus_type.match进行匹配),如果匹配成功,则调用bus_type.prob ...
- [platform]linux platform device/driver(二)--Platform Device和Platform_driver注册过程之详细代码
转自:http://www.cnblogs.com/haimeng2010/p/3582403.html 目录: 1.platform_device注册过程 2.platform_driver注册过程 ...
- [platform]linux platform device/driver(一)--Driver是如何找到对应的device
1.platform device是怎么"自动"关联到platform driver上的? 转向linux driver有些时间了,前段时间碰到个问题,在Linux kernel ...
- 驱动开发学习笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇
驱动开发读书笔记. 0.05 linux 2.6 platform device register 平台设备注册 2/2 共2篇 下面这段摘自 linux源码里面的文档 : 内核版本2.6.22Doc ...
- 驱动开发学习笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇
驱动开发读书笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇下面这段摘自 linux源码里面的文档 : Documentatio ...
- linux 内核驱动--Platform Device和Platform_driver注册过程
linux 内核驱动--Platform Device和Platform_driver注册过程 从 Linux 2.6 起引入了一套新的驱动管理和注册机制 :Platform_device 和 Pla ...
- Linux kernel驱动相关抽象概念及其实现 之“bus,device,driver”
bus,device,driver三个很重要的概念贯穿Linux内核驱动架构,特转载一篇博文: (转载自http://blog.csdn.net/gdt_a20/article/details/642 ...
- I.MX6 Linux I2C device& driver hacking
/******************************************************************************************* * I.MX6 ...
随机推荐
- android launcher 之踩到的坑
需求: 1. 用android系统launcher 隐藏主菜单 所有应用显示在桌面 即workspace上: 2.隐藏launcher上方默认的google search: 3.切换一套launche ...
- [extjs5学习笔记]第三十七节 Extjs6预览版都有神马新东西
本文在微信公众号文章地址:微信公众号文章地址 本文地址:http://blog.csdn.net/sushengmiyan/article/details/45190485 [TOC] 在Ext JS ...
- Android自定义View(一、初体验自定义TextView)
转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51454685 本文出自:[openXu的博客] 目录: 继承View重写onDraw方法 自 ...
- activiti源码编译
个小时,大家安装的时候一定要耐心. 最终编译之后的效果部分如下图所示: 因为我这里有些xml文件没有去除验证,所以有红色的警告,不过也不影响使用. 下面看一下下载之后文件的变化如下图所示: 我们导入主 ...
- Compass 更智能的搜索引擎(2)--进阶
经过了Compass 更智能的搜索引擎(1)–入门的学习,想必对于Compass的使用有了更深的认识了吧.下面谈点更加切合实际开发的东西.那就是CRUD. 面向对象的分页 dao层实现 代码释义 优点 ...
- 全文检索 Lucene(4)
经过了前面几篇文章的学习,我们基本上可以适用Lucene来开发我们的站内搜索应用了.但是观察一下目前的主流的搜索引擎,我们会发现查询结果会有高亮的显示效果.所以,今天我们就来学习一下,给Lucene添 ...
- FFmpeg与libx264接口源代码简单分析
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...
- OpenCV实时美颜摄像并生成H264视频流
为什么美颜摄像这么简单的功能,OpenCV这个开源项目网上很少有代码呢?对于在windows平台下,生成h264视频流也比价麻烦,没有现成的api可以使用,需要借助MinGw编译libx264,或者f ...
- 创建银行API
DECLARE lc_output VARCHAR2(3000); lc_msg_dummy VARCHAR2(3000); lc_return_status VARCHAR2(3000); lc_m ...
- 【JavaEE WEB 开发】Tomcat 详解 Servlet 入门
转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/47146817 一. Tomcat 下载安装配置 1. Tomcat 下载 T ...