驱动开发学习笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇
驱动开发读书笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇
下面这段摘自 linux源码里面的文档 :
Documentation/driver-model/platform.txt
Device Enumeration
82 ~~~~~~~~~~~~~~~~~~
83 As a rule, platform specific (and often board-specific) setup code will
84 register platform devices: int platform_device_register(struct platform_device *pdev); int platform_add_devices(struct platform_device **pdevs, int ndev); 90 The general rule is to register only those devices that actually exist,
91 but in some cases extra devices might be registered. For example, a kernel
92 might be configured to work with an external network adapter that might not
93 be populated on all boards, or likewise to work with an integrated controller
94 that some boards might not hook up to any peripherals. 96 In some cases, boot firmware will export tables describing the devices
97 that are populated on a given board. Without such tables, often the
98 only way for system setup code to set up the correct devices is to build
99 a kernel for a specific target board. Such board-specific kernels are
100 common with embedded and custom systems development. 102 In many cases, the memory and IRQ resources associated with the platform
103 device are not enough to let the device's driver work. Board setup code
104 will often provide additional information using the device's platform_data
105 field to hold additional information. 107 Embedded systems frequently need one or more clocks for platform devices,
108 which are normally kept off until they're actively needed (to save power).
109 System setup also associates those clocks with the device, so that that
110 calls to clk_get(&pdev->dev, clock_name) return them as needed. 113 Legacy Drivers: Device Probing
114 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
115 Some drivers are not fully converted to the driver model, because they take
116 on a non-driver role: the driver registers its platform device, rather than
117 leaving that for system infrastructure. Such drivers can't be hotplugged
118 or coldplugged, since those mechanisms require device creation to be in a
119 different system component than the driver. 121 The only "good" reason for this is to handle older system designs which, like
122 original IBM PCs, rely on error-prone "probe-the-hardware" models for hardware
123 configuration. Newer systems have largely abandoned that model, in favor of
124 bus-level support for dynamic configuration (PCI, USB), or device tables
125 provided by the boot firmware (e.g. PNPACPI on x86). There are too many
126 conflicting options about what might be where, and even educated guesses by
127 an operating system will be wrong often enough to make trouble. 129 This style of driver is discouraged. If you're updating such a driver,
130 please try to move the device enumeration to a more appropriate location,
131 outside the driver. This will usually be cleanup, since such drivers
132 tend to already have "normal" modes, such as ones using device nodes that
133 were created by PNP or by platform device setup. 135 None the less, there are some APIs to support such legacy drivers. Avoid
136 using these calls except with such hotplug-deficient drivers. struct platform_device *platform_device_alloc(
const char *name, int id); 141 You can use platform_device_alloc() to dynamically allocate a device, which
142 you will then initialize with resources and platform_device_register().
143 A better solution is usually: struct platform_device *platform_device_register_simple(
const char *name, int id,
struct resource *res, unsigned int nres); 149 You can use platform_device_register_simple() as a one-step call to allocate
150 and register a device.
上文讲了两种platform设备注册方式,一种是
platform specific (and often board-specific) setup code
平台特定的,在/arch/arm/plat-s3c24xx/devs.c中找到相关数据结构和代码
第一步:定义资源结构体
static struct resource s3c_lcd_resource[] = {
[0] = {
.start = S3C24XX_PA_LCD,
.end = S3C24XX_PA_LCD + S3C24XX_SZ_LCD - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = IRQ_LCD,
.end = IRQ_LCD,
.flags = IORESOURCE_IRQ,
} };
第二步:定义platform_device (主要的有 设备名称 设备id(区分相同设备名) 资源个数 资源定义 内嵌设备)
struct platform_device s3c_device_lcd = {
.name = "s3c2410-lcd",
.id = -1,
.num_resources = ARRAY_SIZE(s3c_lcd_resource),
.resource = s3c_lcd_resource,
.dev = {
.dma_mask = &s3c_device_lcd_dmamask,
.coherent_dma_mask = 0xffffffffUL
}
};
第三步:添加到platform_device指针数组 smdk2440_devices (arch/arm/mach-s3c2440/mach-smdk2440.c)
static struct platform_device *smdk2440_devices[] __initdata = {
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c,
&s3c_device_iis,
};
第四步:添加到platform_device指针数组 (arch/arm/mach-s3c2440/mach-smdk2440.c)
static void __init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
platform_add_devices会将platform_device 注册到内核
第五步:有没有发现上面有个 s3c24xx_fb_set_platdata 函数?他是干什么的呢?
platform.txt 写道:
In many cases, the memory and IRQ resources associated with the platform
device are not enough to let the device's driver work. Board setup code
will often provide additional information using the device's platform_data
field to hold additional information.
因为 resource 结构是定义好的,所以不方便添加更多的信息 platform提供了平台数据platform_data的支持. 下面为函数原型:(感觉就是个不美观的补丁。。。)
void __init s3c24xx_fb_set_platdata(struct s3c2410fb_mach_info *pd)
{
struct s3c2410fb_mach_info *npd; npd = kmalloc(sizeof(*npd), GFP_KERNEL);
if (npd) {
memcpy(npd, pd, sizeof(*npd));
s3c_device_lcd.dev.platform_data = npd;
} else {
printk(KERN_ERR "no memory for LCD platform data\n");
}
}
第六步:第四步的代码还有个smdk_machine_init();
是进行gpio的设置,还有注册led设备 小结:第一种方法 定义资源 定义平台data 设置platdata(与platform_device 关联) 然后使用 platform_add_devices函数进行注册
注意 platform_add_devices 和platform_device_add区别很大,platform_add_devices(struct platform_device ** devs,int num) 里面根据传入的指针,
计算出需要注册的platform_device的数量(注意,这个number不是platform_device.id)然后使用迭代来调用platform_device_register(struct platform_device *)
进行注册.
所以核心的函数调用就是 platform_device_register这个函数,多个设备时调用platform_add_devices 有兴趣的朋友可以看一下platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));里面ARRAY_SIZE 计算数组元素个数 的实现方法
这个宏在<linux/kernel.h>里面
注意的是:上面代码都是编译进内核,而不是内核模块 小小的感想:
写了字符设备驱动之后,学习这个platform 设备驱动,十分好奇说是设备驱动,但是没有提供应用接口 open write的方法,百思不得其解;后来来回翻了几本书籍,发现platform似乎
就没有也不是为了提供这些接口而设计的,你可以在driver初始化或者proe探测函数里面 注册字符/混合/类设备 ,达到为应用提供write open的目的,而字符设备与platform 设备驱动的
联系似乎只是 提供注册和销毁的关系,设备驱动真是复杂,希望早日攻克。 下次介绍 第二种注册方式 参考资料:
linux源码 2.6.22
《linux驱动入门》----主编 魏清 副主编 梁庚 徐志国
23:56:02
2016-10-05
驱动开发学习笔记. 0.04 linux 2.6 platform device register 平台设备注册 1/2 共2篇的更多相关文章
- 驱动开发学习笔记. 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.07 Uboot链接地址 加载地址 和 链接脚本地址
驱动开发学习笔记. 0.07 Uboot链接地址 加载地址 和 链接脚本地址 最近重新看了乾龙_Heron的<ARM 上电启动及 Uboot 代码分析>(下简称<代码分析>) ...
- 驱动开发学习笔记. 0.02 基于EASYARM-IMX283 烧写uboot和linux系统
驱动开发读书笔记. 0.02 基于EASYARM-IMX283 怎么烧写自己裁剪的linux内核?(非所有arm9通用) 手上有一块tq2440,但是不知道什么原因,没有办法烧boot进norflas ...
- 驱动开发学习笔记. 0.06 嵌入式linux视频开发之预备知识
驱动开发读书笔记. 0.06 嵌入式linux视频开发之预备知识 由于毕业设计选择了嵌入式linux视频开发相关的项目,于是找了相关的资料,下面是一下预备知识 UVC : UVC,全称为:USB v ...
- 驱动开发学习笔记. 0.01 配置arm-linux-gcc 交叉编译器
驱动开发读书笔记. 0.01 配置arm-linux-gcc 交叉编译器 什么是gcc: 就像windows上的VS 工具,用来编译代码,具体请自己搜索相关资料 怎么用PC机的gcc 和 arm-li ...
- Linux驱动开发学习笔记(1):LINUX驱动版本的hello world
1.关于目录 /lib/modules/2.6.9-42.ELsmp/build/ 这个是内核源码所在的目录 一般使用这样的命令进入这个目录:cd /lib/modules/$(una ...
- 安卓开发学习笔记(七):仿写腾讯QQ登录注册界面
这段代码的关键主要是在我们的相对布局以及线性布局上面,我们首先在总体布局里设置为线性布局,然后再在里面设置为相对布局,这是一个十分常见的XML布局模式. 废话不多说,直接上代码:一.activity. ...
- Hasen的linux设备驱动开发学习之旅--时钟
/** * Author:hasen * 參考 :<linux设备驱动开发具体解释> * 简单介绍:android小菜鸟的linux * 设备驱动开发学习之旅 * 主题:时钟 * Date ...
- Kinect开发学习笔记之(一)Kinect介绍和应用
Kinect开发学习笔记之(一)Kinect介绍和应用 zouxy09@qq.com http://blog.csdn.net/zouxy09 一.Kinect简单介绍 Kinectfor Xbox ...
随机推荐
- (原)android4.2以后获取应用程序和缓存大小的方法(源码有改变)
以前获取应用的大小是用 PackageManager mPackageManager= getPackageManager(); try {Method getPackageSizeInfoMetho ...
- AUTOIT解决域控普通用户以管理员身份安装软件方法
windows域管理,本是很好的管理方式,方便的软件分发,权限控制等功能.不过由于我处软件分发总有那么一些电脑没有成功安装,或是新装的电脑安装软件时漏了安装一些软件,而这些软件需要管理员权限安装的,用 ...
- 虚拟机中CentOS 7下PHP环境配置
为了简单起见,虚拟机网卡设置为桥接模式 1.yum install httpd php 2.yum install mariadb 3.启动mariadb systemctl start maria ...
- GCD、dispatch函数介绍
iOS多线程的方法有3种: NSThread NSOperation GCD(Grand Central Dispatch) 其中,由苹果所倡导的为多核的并行运算提出的解决方案:GCD能够访问线程池, ...
- Bootstrap文件上传插件File Input的使用
基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用 Bootstrap文件上传插件File Input是一个不错的文件上传控件, ...
- 官方提供的屏蔽百度转码Baidu Transcoder的方法no-transform
首先,百度在官方的声明中说:[喝小酒的网摘]http://blog.hehehehehe.cn/a/17112.htm百度仅作为中立的转码工具及相关技术的提供方.在转码过程中,百度对第三方网站内容不做 ...
- cucumber:环境安装
1.安装RubyInstallerhttp://rubyinstaller.org/downloads/注意:安装目录结构不要太深安装完成后在命令行运行: ruby –v 可以查看是否安装成功2.安装 ...
- jQuery 学习笔记(函数调用机制)
最近在学前端框架amazeui,之前用其中的CSS样式搭建了一个伪360网页,学会了点布局的东西,但是始终觉得有点无聊.所以这几天就开始研究jquery代码了. 对于我这样一个初学者来说,有很多东西都 ...
- Docker学习过程中遇到的问题及解决方法
1.重新安装Docker后,运行不起来 [root@zyt-test-14-53 ~]# docker infoCannot connect to the Docker daemon. Is the ...
- Struts2框架之-Struts2的标签
Struts2包含哪些标签? 解答: A: <s:a href=”"></s:a>—–超链接,类似于html里的<a></a> <s:a ...