14_Linux设备树下的platform驱动编写

目录

设备树下的platform驱动简介

运行测试


设备树下的platform驱动简介

platform驱动框架分为总线、设备和驱动,其中总线不需要我们这些驱动程序员去管理,这个是Linux内核提供的,我们在编写驱动的时候只要关注于设备和驱动的具体实现即可。在没有设备树的Linux内核下,我们需要分别编写并注册platform_device和 platform_driver,分别代表设备和驱动。在使用设备树的时候,设备的描述被放到了设备树中,因此platform-device就不需要我们去编写了,我们只需要实现 platform_driver 即可。在编写基于设备树的platform驱动的时候我们需要注意一下几点:

1.在设备树中创建设备节点

毫无疑问,肯定要先在设备树中创建设备节点来描述设备信息,重点是要设置好compatible属性的值,因为platform总线需要通过设备节点的compatible属性值来匹配驱动!这点要切记。比如,我们可以编写如下所示的设备节点来描述我们本章实验要用到的LED这个设备:

14_Linux设备树下的platform驱动编写_第1张图片

 示例中的gpioled节点,注意第4行的compatible属性值为“atkalpha-gpioled”,因此一会在编写platform驱动的时候of_match_table属性表中要有“atkalpha-gpioled”。

2.编写platform驱动的时候要注意兼容属性

在使用设备树的时候platform驱动会通过of_match_table来保存兼容性值,也就是表明此驱动兼容哪些设备。所以, of_match_table将会尤为重要,比如本例程的platform驱动中platform_driver就可以按照如下所示设置:

14_Linux设备树下的platform驱动编写_第2张图片

 第1~4行,of_device_id表,也就是驱动的兼容表,是一个数组,每个数组元素为of_device_id类型。每个数组元素都是一个兼容属性,表示兼容的设备,一个驱动可以跟多个设备匹配。这里我们仅仅匹配了一个设备,那就是中创建的gpioled这个设备。

第2行的compatible值为"atkalpha-gpioled",驱动中的compatible属性和设备中的compatible属性相匹配,因此驱动中对应的probe函数就会执行。注意第3行是一个空元素,在编写of_device_id的时候最后一个元素一定要为空!

第6行,通过MODULE_DEVICE_TABLE声明一下leds_of_match这个设备匹配表。

第11行,设置platform_driver中的of_match_table匹配表为上面创建的leds_of_match,至此我们就设置好了platform驱动的匹配表了。

3.编写platform驱动

基于设备树的platform驱动和无设备树的platform驱动基本一样,都是当驱动和设备匹配成功以后就会执行probe函数。需要在probe函数里面执行字符设备驱动那一套,当注销驱动模块的时候remove函数就会执行,都是大同小异的。

platform驱动程序编写

14_Linux设备树下的platform驱动编写_第3张图片

14_Linux设备树下的platform驱动编写_第4张图片

14_Linux设备树下的platform驱动编写_第5张图片

14_Linux设备树下的platform驱动编写_第6张图片

14_Linux设备树下的platform驱动编写_第7张图片

14_Linux设备树下的platform驱动编写_第8张图片

14_Linux设备树下的platform驱动编写_第9张图片

14_Linux设备树下的platform驱动编写_第10张图片

14_Linux设备树下的platform驱动编写_第11张图片

14_Linux设备树下的platform驱动编写_第12张图片

14_Linux设备树下的platform驱动编写_第13张图片

 第33~112行,传统的字符设备驱动,没什么要说的。

第120-164行, platform驱动的probe函数,当设备树中的设备节点与驱动之间匹配成功以后此函数就会执行,原来在驱动加载函数里面做的工作现在全部放到probe函数里面完成。

第171~180 行,remobe 函数,当卸载 platform驱动的时候此函数就会执行。在此函数里面释放内存、注销字符设备等,也就是将原来驱动卸载函数里面的工作全部都放到remove函数中完成。

第183-186行,匹配表,描述了此驱动都和什么样的设备匹配,第184行添加了一条值为"atkalpha-gpioled"的compatible属性值,当设备树中某个设备节点的compatible属性值也为“atkalpha-gpioled”的时候就会与此驱动匹配。

第189-196行,platform_driver驱动结构体,191行设置这个platform驱动的名字为“ imx6ulled”,因此,当驱动加载成功以后就会在/sys/bus/platform/drivers/目录下存在一个名为“imx6uled”的文件。

第192行设置of_match_table为上面的led_of_match。

第203-206行,驱动模块加载函数,在此函数里面通过platform_driver_register向Linux内核注册led_driver驱动。

第213-216行,驱动模块卸载函数,在此函数里面通过platform_driver_unregister从Linux内核卸载 led_driver 驱动。

运行测试

驱动模块加载完成以后到/sys/bus/platform/drivers/目录下查看驱动是否存在,在leddriver.c中设置led_driver(platform_driver类型)的name字段为"imx6ul-led",因此会在/sys/bus/platform/drivers/目录下存在名为"imx6ul-led”这个文件,结果如图所示:

 同理,在/sys/bus/platform/devices/目录下也存在led的设备文件,也就是设备树中gpioled这个节点,如图所示:

 驱动和模块都存在,当驱动和设备匹配成功以后就会输出如图所示一行语句:

 驱动和设备匹配成功以后就可以测试LED灯驱动了,输入如下命令打开LED灯:

 在输入如下命令关闭LED灯:

 观察一下LED灯能否打开和关闭,如果可以的话就说明驱动工作正常,如果要卸载驱动的话输入如下命令即可:

你可能感兴趣的:(Linux驱动,linux,U-boot,arm开发,设备树,嵌入式硬件)