通常在Linux中,把SOC系统中集成的独立外设单元(如:I2C、IIS、RTC、看门狗等)都被当作平台设备来处理。在Linux中用platform_device结构体来描述一个平台设备,在2.6.32内核中定义在:include/linux/platform_device.h中,如下:
在Linux中是用这个结构体来定义一些平台设备的。
在arch/arm/plat-s3c24xx/devs.c中就定义了很多平台设备。
平台设备驱动是指具体的某种平台设备的驱动,比如RTC平台设备驱动。在Linux中,系统还为平台设备定义了平台驱动结构体platform_driver,就好比系统为字符设备定义了file_operations一样,但不要把平台设备跟字符设备、块设备、网络设备搞成了并列的概念,因平台设备也可以是字符设备等其他设备。注意:在被定义为平台设备的字符设备的驱动中,除了要实现字符设备驱动中file_operations的open、release、read、write等接口函数外,还要实现平台设备驱动中platform_driver的probe、remove、suspend、resume等接口函数。
以S3c2440开发板为例,在linux-2.6.30.4/arch/arm/plat-s3c24xx/common-smdk.c中定义了如下设备:
staticstruct platform_device __initdata *smdk_devs[] = { //
平台设备列表
1
,也就是说我们要使用一个新的平台设备要先在上面定义,然后加到这个列表中,最后到驱动层去实现该设备的驱动
&s3c_device_nand,
&s3c_device_sdi,
&smdk_led4,
&smdk_led5,
&smdk_led6,
&smdk_led7,
};
在linux-2.6.30.4/arch/arm/mach-s3c2440/mach-smdk2440.c中定义了如下设备:
static struct platform_device*smdk2440_devices[] __initdata = { //
平台设备列表
2
&s3c_device_usb,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_rtc,
&s3c_device_dm9000,
&s3c_device_uda134x,
};
这些设备在smdk2440_machine_init函数中,通过platform_add_device函数注册进内核。
linux-2.6.30.4/arch/arm/mach-s3c2440/mach-smdk2440.c
static void __initsmdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));
//
将上面列表中的平台设备添加到系统总线中
smdk_machine_init();
linux-2.6.30.4/arch/arm/plat-s3c24xx/common-smdk.c
void __init smdk_machine_init(void)
{
……
s3c_device_nand.dev.platform_data =&smdk_nand_info;
platform_add_devices(smdk_devs,ARRAY_SIZE(smdk_devs));
//
将上面列表中的平台设备添加到系统总线中
s3c_pm_init();
以实时时钟RTC 驱动为例
linux/arch/arm/plat-s3c24xx/devs.c中:
struct platform_device s3c_device_rtc = {
.name = "s3c2410-rtc",
.id = -1,
.num_resources =ARRAY_SIZE(s3c_rtc_resource),
.resource = s3c_rtc_resource,
};
drivers/rtc/rtc-s3c.c中:
static struct platform_driver s3c2410_rtc_driver = {
.probe = s3c_rtc_probe,// RTC探测函数, 探测就意味着在系统总线中去检测设备的存在,然后获取设备有用的相关资源信息,以便我们使用这些信息
.remove = __devexit_p(s3c_rtc_remove),// RTC移除函数
.suspend = s3c_rtc_suspend,// RTC挂起函数
.resume = s3c_rtc_resume,// RTC恢复函数
.driver = {
.name = "s3c2410-rtc",
.owner = THIS_MODULE,
},
};
在linux/arch/arm/plat-s3c24xx/devs.c中
static struct resource s3c_rtc_resource[] = {//定义了RTC平台设备使用的资源,这些资源在驱动中都会用到
[0]= { //IO端口资源范围
.start= S3C24XX_PA_RTC,
.end = S3C24XX_PA_RTC+ 0xff,
.flags= IORESOURCE_MEM,
},
[1]= {//RTC报警中断资源
.start= IRQ_RTC,
.end = IRQ_RTC,
.flags= IORESOURCE_IRQ,
},
[2]= { //TICK节拍时间中断资源
.start= IRQ_TICK,
.end = IRQ_TICK,
.flags= IORESOURCE_IRQ
}
};
static int __init s3c_rtc_init(void)
{
/*将RTC注册成平台设备驱动*/
return platform_driver_register(&s3c2410_rtc_driver);
}
static void __exit s3c_rtc_exit(void)
{
/*注销RTC平台设备驱动*/
platform_driver_unregister(&s3c2410_rtc_driver);
}
module_init(s3c_rtc_init);
module_exit(s3c_rtc_exit);
RTC设备类的操作,是对RTC硬件的各种寄存器进行操作,rtc_class_ops是RTC设备类在RTC驱动核心部分中定义的对RTC设备类进行操作的结构体,类似字符设备在驱动中的file_operations对字符设备进行操作的意思。对RTC的操作主要有打开、关闭、设置或获取时间、设置或获取报警、设置节拍时间计数值等等,该结构体内接口函数的实现都在下面
static const struct rtc_class_ops s3c_rtcops = {
.open = s3c_rtc_open,
.release = s3c_rtc_release,
.irq_set_freq = s3c_rtc_setfreq, /*在第②步中已实现*/
.irq_set_state = s3c_rtc_setpie,
.read_time = s3c_rtc_gettime,
.set_time = s3c_rtc_settime,
.read_alarm = s3c_rtc_getalarm,
.set_alarm = s3c_rtc_setalarm,
};
机理:内核启动后,首先够造链表将描述设备的platform_device结构组织起来,得到一个设备的列表;当加载到某个驱动程序的platform_driver结构时(start_kernelàrest_init()àinit àdo_basic_setup(); //初始化设备驱动程序),使用一些匹配函数来检查驱动程序是否支持这些设备,常用的检查方法很简单:比较驱动程序和设备的名称。
当注册成功时会调用platform_driver结构元素probe函数指针,这里就是s3c_rtc_probe。驱动的初始化等都是在prob函数中完成的。
分享到:
相关推荐
linux 字符设备驱动 字符设备是指在I/O传输过程中以字符为单位进行传输的设备,例如键盘,打印机等。请注意,以字符为单位并不一定意味着是以字节为单位,因为有的编码规则规定,1个字符占16比特,合2个字节。 在...
Linux设备驱动程序学习总结: *字符设备驱动程序 *调试技术 *并发和竞态 *Linux中的循环缓冲区 *内核的数据类型 *分配内存 *与硬件通信 *时间、延迟及延缓操作 *中断处理 *Linux设备模型
从描述I2C协议开始,到I2C设备驱动架构,特定EEPROM设备AT24c08的datasheet,最后详细描述驱动里的各个函数以及相对应的调试过程!
linux设备驱动归纳总结,简易直接明了的入门教程
十分适合linux驱动初学者,为今后Android驱动开发打下坚实的基础 (一):内核的相关基础概念 (二):模块的相关基础概念 (三):1_字符型设备之设备申请 (三):2_字符型设备的操作open、close、read、write ...
linux设备驱动归纳总结(三):3.设备驱动面向对象思想和lseek的实现 相关代码
linux设备驱动归纳总结(三):2.字符型设备的操作open、close、read、write 文章相关代码
给出实现蓝牙设备驱动的重要数据结构和流程,并总结Linux 下开发蓝牙USB 设备驱动的一般方法和关键技术。 关键词:Linux 系统;蓝牙协议栈;设备驱动 USB Device Driver for Linux Bluetooth Stack LIANG Jun-xue...
文件系统驱动和设备驱动是容易混淆的概念,本PDF将对文件系统过滤驱动和设备驱动的异同点做简要总结和分析,详细剖析两者的异同点,超高清PDF
《Linux 设备驱动程序》第三版是一本面向Linux驱动开发的经典教程,内容非常全面,非常适合没有接触过Linux驱动开发的新手。本人通过阅读本书,对其内容进行了梳理总结,分为两大部分:1.驱动代码分析 2.知识点总结...
linux设备驱动程序,自己学习总结的笔记,比较简略,哈哈
linux 字符设备驱动简单总结,包括各个函数的介绍,分享的他认的,然后整理了下
关于LCD显示屏的驱动的详细架构描述和驱动分析
linux设备驱动归纳总结(三):4.ioctl的实现 文章相关代码
Linux设备驱动异步通知个人总结 ,纯属个人笔记
个人总结的设备-总线-驱动的流程图,以gpio为例
介绍了DSP/BIOS嵌入式实时操作系统上外设模块化驱动程序的开发规范,然后具体讲述了TMS32(~6711 DSK平台 上音频设备驱动程序的开发过程,最后总结了外围设备驱动的一般开发方法。
在linux操作系统下,实现加载一个通过对原linux内核改写的U盘驱动,并且通过加载自己修改、编写的U盘驱动程序模块,实现对U盘的识别,以及对U盘的读写操作。 这里主要是对linux本身已有的U盘驱动进行阅读,通过对...
头文件及内核函数说明总结-linux设备驱动程序