平台总线会将name相同的device和driver进行匹配,执行driver中的probe
设备树描述的节点会生成对应的设备树device,我这里理解为设备树也向平台总线注册了device,可以在/sys/devices/platform/目录下看到
driver也可以通过平台总线和设备树中的节点设备进行匹配,执行probe,获取设备树中节点的参数,然后执行各种操作。
相当于之前的device的驱动代码部分由设备树来代替。
思路步骤:
taxue_leds:taxue_leds { compatible = "taxue_leds"; gpios1 = <&gpl2 0 GPIO_ACTIVE_HIGH>; gpios2 = <&gpk1 1 GPIO_ACTIVE_HIGH>; status = "disabled"; }; &taxue_leds { status = "okay"; };
查看板卡上的节点是否存在
cat /sys/devices/platform/taxue_leds/of_node/compatible taxue_leds
#include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/uaccess.h> #include <linux/platform_device.h> #include <linux/ioport.h> #include <linux/of.h> #include <linux/of_gpio.h> #define DEVICE_NAME "taxue_leds" struct device_node *led_node=NULL; //probe函数,进入probe说明匹配到device int drProbe(struct platform_device *dev){ int ret; struct property *pro; unsigned int gpioval[3]; printk("probe here\n"); led_node = of_find_node_by_path("/taxue_leds"); //从设备树路径获取节点 //或者 //led_node = dev->dev.of_node; //probe函数的形参就是匹配的设备指针 if(led_node == NULL){ printk("find node failed\n"); return -1; } pro = of_find_property(led_node, "compatible", NULL); //获取节点中的compatible属性 printk("compatible name = %s\n", pro->name); printk("compatible value = %s\n", (char *)(pro->value)); printk("compatible len = %d\n", pro->length); pro = of_find_property(led_node, "status", NULL); printk("status name = %s\n", pro->name); printk("status value = %s\n", (char *)(pro->value)); printk("status len = %d\n", pro->length); ret = of_property_read_u32_array(led_node, "gpios2", gpioval, 3); //读取gpios2属性,该属性值是<>括起来的,所以数据类型是32位的数组 if(ret == 0){ printk("gpios2 value= %d\t%d\t%d\t\n", gpioval[0], gpioval[1], gpioval[2]); }else{ printk("read gpios2 failed\n"); } return 0; } int drRemove(struct platform_device *dev){ printk("driver remove\n"); return 0; } //match_table static const struct of_device_id of_leds_match[] = { {.compatible = DEVICE_NAME}, {}, }; static struct platform_driver pdrv = { .probe = drProbe, //和设备匹配后会调用probe函数 .remove = drRemove, .driver = { .name = "DEVICE_NAME", //如果使用设备树中的设备,则不根据name匹配 .owner = THIS_MODULE, .of_match_table = of_leds_match, //使用match_table进行匹配 }, }; static int driver_init_led(void){ int ret=0; ret = platform_driver_register(&pdrv); //向平台注册driver if(ret < 0){ printk("platform driver regist failed\n"); return -1; } return 0; } static void driver_exit_led(void){ platform_driver_unregister(&pdrv); printk("platform driver exit!\n"); } module_init(driver_init_led); module_exit(driver_exit_led); MODULE_LICENSE("Dual BSD/GPL"); //遵循BSD和GPL开源许可 MODULE_AUTHOR("TAXUE"); //模块作者
#在板卡上 ls /proc/device-tree/ #目录下有所有的节点信息 cat /sys/devices/platform/xxx/of_node/compatible #xxx表示节点名,这里如果存在,表明节点已经成功注册设备