目录
设备树下的platform驱动简介
platform驱动框架分为总线、设备和驱动,其中总线不需要我们这些驱动程序员去管理,这个是Linux内核提供的,我们在编写驱动的时候只要关注于设备和驱动的具体实现即可。在没有设备树的Linux内核下,我们需要分别编写并注册platform_device和 platform_driver,分别代表设备和驱动。在使用设备树的时候,设备的描述被放到了设备树中,因此platform-device就不需要我们去编写了,我们只需要实现 platform_driver 即可。在编写基于设备树的platform驱动的时候我们需要注意一下几点:
1.在设备树中创建设备节点
毫无疑问,肯定要先在设备树中创建设备节点来描述设备信息,重点是要设置好compatible属性的值,因为platform总线需要通过设备节点的compatible属性值来匹配驱动!这点要切记。比如,我们可以编写如下所示的设备节点来描述我们本章实验要用到的LED这个设备:
示例中的gpioled节点,注意第4行的compatible属性值为“atkalpha-gpioled”,因此一会在编写platform驱动的时候of_match_table属性表中要有“atkalpha-gpioled”。
2.编写platform驱动的时候要注意兼容属性
在使用设备树的时候platform驱动会通过of_match_table来保存兼容性值,也就是表明此驱动兼容哪些设备。所以, of_match_table将会尤为重要,比如本例程的platform驱动中platform_driver就可以按照如下所示设置:
第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驱动程序编写
第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灯能否打开和关闭,如果可以的话就说明驱动工作正常,如果要卸载驱动的话输入如下命令即可: