在设备驱动程序中经常看到相关的字段和平台,分布在多个角落的驱动程序中,其中一个更为重要的机制在2.6内核中,了解其原理后,对驱动程序的分析很有帮助,下面简单介绍一下:



在Linux2.6内核设备模型,我们在乎的总线,设备和三个实体。总线绑定设备和驱动程序。当系统注册一个设备时,它会找到与其匹配的驱动程序,相反,当系统为每个驱动程序注册时,就会找到匹配设备,匹配是由总线完成的。



一个真正的Linux设备驱动程序通常需要挂在总线上,本身依赖于PCI、USB、I2C、SPI等设备,这是没有问题的,但在嵌入式系统中,嵌入式系统,集成外设控制器独立挂在内存空间之外,它是没有连接到总线的基础上。这样的背景下,发明了一种称为Linux虚拟总线平台总线。



集成在SOC系统中的集成外围设备(I2C、LCD、SPI、RTC等)被视为平台设备,它们本身就是字符类型的设备。



从Linux2.6内核,一套新的驾驶员管理和注册机制,介绍了platform_device和platform_driver,。在Linux大多数的设备驱动程序可以使用这个机制,该装置是在platform_device表示,和司机登记platform_driver。



platform_device结构包括 / / H platform_device Linux。



结构platform_device



{



常量名称*



U32 ID;



结构设备开发;



U32 num_resources; / /各种二手设备的资源数量



结构资源*;资源的使用



}



platform_driver结构包括 / / H platform_device Linux。



结构platform_driver



{



Int(探头)(结构platform_device *);



Int(*删除)(结构platform_device *);



void(*关机)(结构platform_device *);



Int(*暂停)(结构platform_device *,pm_message_t状态);



Int(* suspend_late)(结构platform_device *,pm_message_t状态);



Int(* resume_early)(结构platform_device *);



Int(*简历)(结构platform_device *);



结构pm_ext_ops下午;



device_driver驱动结构;



};



系统定义了平台总线platform_bus_type bus_type实例,并决定了其成员的功能匹配和驱动匹配设备()。



匹配platform_device和platform_driver主要看是否这两个字段的名称是相同的。(名称必须匹配相同)



使用platform_device_register()函数来登记一个平台装置。



一般来说,platform_device是平台的BSP文件定义,平台和设备注册到系统通过platform_add_devices()函数



登记和注销platform_driver:



platform_driver_register()



platform_driver_unregister()



以S3C2440 LCD驱动器为例:



在BSP文件中:



结构platform_device s3c_device_lcd = { {



名称



id = 1,



num_resources = array_size(s3c_lcd_resource),



s3c_lcd_resource资源=,



。



dma_mask = s3c_device_lcd_dmamask,



coherent_dma_mask = 0xfffffffful。



}



};



为了完成LCD设备注册,放进smdk2440_devices数组定义在 / / /弓臂mach-s3c2440 / mach-smdk2440 C:



静态结构platform_device * smdk2440_devices __initdata = { { { }



…



…



s3c_device_lcd,



};



通过platform_add_devices(smdk2440_devices,array_size(smdk2440_devices));注册









在相应的驱动程序文件:( / / / s3c2410fb司机视频。C)



静态结构platform_driver s3c2410fb_driver = { {



。探头= s3c2410fb_probe /驱动器检测



。删除= __devexit_p(s3c2410fb_remove), / /删除驱动



s3c2410fb_suspend暂停=,



s3c2410fb_resume简历=,



驱动程序{ {



名称



业主= this_module,



},



};



静态变量__devinit s3c2410_fb_init(void)



{



返回platform_driver_register(s3c2410fb_driver);



}



静态__exit s3c2410fb_cleanup(void)



{



platform_driver_unregister(s3c2410fb_driver);



}



当注册成功时,您将在以下两个目录中看到设备节点:



系统/平台/设备/



系统/平台/



平台设备资源与数据:



资源结构:



结构资源



{



resource_size_t开始;



resource_size_t结束;



常量char *名称;



无符号长标志;



结构资源*父,*兄弟,*子;



};



我们通常关心开始、结束和标志的3个字段,它们表示开始值、结束值和资源、标志的类型。



它可以ioresource_io,ioresource_mem,ioresource_irq,ioresource_dma等等。



如lcd资源:



静态结构资源s3c_lcd_resource { } = { {



{ 0 } { {



。开始= s3c24xx_pa_lcd, / /的液晶显示器(LCD控制器的IO资源开始登记地址)



s3c24xx_pa_lcd + s3c24xx_sz_lcd。= 1 / /结束地址



ioresource_mem旗帜=,



},



{ 1 } { {



。开始= irq_lcd, / /液晶中断号



irq_lcd结束=,



ioresource_irq旗帜=,



}



};



在platform_get_resource驱动等功能获得设备资源()或()platform_get_irq



结构资源* platform_get_resource(struct platform_device *,unsigned int unsigned int);



国际platform_get_irq(struct platform_device * dev,unsigned int num);



获得的内存或IO资源可以使用之前需要ioremap



进入IRQ资源需要request_irq



除了BSP的设备资源定义外,还可以附加一些数据,因为设备硬件描述除了中断、内存、DMA通道外,还可能有一些配置信息,配置信息也依赖于主板,不适合直接放置在。



备用驱动器本身,因此,平台还提供了platform_data支持。



platform_data可以自定义,如DM9000的驱动程序,来描述一些与platform_data属性:



静态结构dm9000_plat_data s3c_dm9000_platdata = { {



dm9000_platf_16bitonly旗帜=,



};



静态结构platform_device s3c_device_dm9000 = { {



名称=DM9000



id = 0,



num_resources = array_size(s3c_dm9000_resource),



s3c_dm9000_resource资源=,



。



platform_data = s3c_dm9000_platdata,



}



};



在相应的驱动器中使用:



结构dm9000_plat_data *数据= pdev -> dev.platform_data;



访问platform_data



找到一个与平台相关的驱动程序,从BSP文件中分析其结构,分析其底层硬件操作,使之很快熟悉平台的工作原理。