ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

设备树-平台总线

2021-10-11 22:04:15  阅读:167  来源: 互联网

标签:node led 总线 平台 driver platform printk 设备


设备树设备和平台设备的关系

平台总线会将name相同的device和driver进行匹配,执行driver中的probe

设备树描述的节点会生成对应的设备树device,我这里理解为设备树也向平台总线注册了device,可以在/sys/devices/platform/目录下看到

driver也可以通过平台总线和设备树中的节点设备进行匹配,执行probe,获取设备树中节点的参数,然后执行各种操作。

相当于之前的device的驱动代码部分由设备树来代替。

以设备树-平台总线方式注册驱动、获取设备树参数

思路步骤:

  • 设备树中添加需要的节点,烧录进板卡
  • 在设备中确认相关节点存在,确认compatible属性(在板卡命令行可以查看)
  • 编写driver驱动代码
  • 初始化platform_driver结构体:注意driver结构体成员中的of_match_table属性,因为依靠这个名字来和compatible匹配
  • 编写platform_driver结构体中的probe函数
  • 注册平台driver:使用platform_driver_register函数
  • 在probe函数里使用of相关函数获取节点的参数

设备树中添加的节点:

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

driver代码

#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表示节点名,这里如果存在,表明节点已经成功注册设备

标签:node,led,总线,平台,driver,platform,printk,设备
来源: https://www.cnblogs.com/TaXueWuYun/p/15395165.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有