RK3568平台(设备树api篇)of 操作函数获取设备树节点

本文详细介绍了Linux内核中用于设备树节点查找和操作的一系列OF函数,如of_find_node_by_name、of_find_node_by_path等,并通过一个示例展示了如何在驱动程序中使用这些函数进行设备树节点的探测和操作。
摘要由CSDN通过智能技术生成

一.of函数概述

Linux内核给我们提供了一系列的函数来获取设备树中的节点或者属性信息,这一系列的函数都有一个统一的前缀 ”of“ , 所以在很多资料里面也被叫做OF函数。

Linux 内核使用device_node 结构体来描述一个节点,此结构体定义在文件include/linux/of.h 中,定义如下:

二.查找节点的of函数

of_find_node_by_name 函数,该函数通过节点名字查找指定的节点。

struct device_node *of_find_node_by_name(struct device_node *from, const char *name);

from : 开始查找的节点,如果为NULL 表示从根节点开始查找整个设备树。

name :**要查找的节点名字。

返回值:**找到的节点,如果为NULL 表示查找失败。

of_find_node_by_path,该函数通过路径来查找指定的节点。

struct device_node *of_find_node_by_path(const char *path);

path : 带有全路径的节点名,可以使用节点的别名,比如:“/backlight” 就是backlight 这个节点的

返回值:**找到的节点,如果为NULL 表示查找失败。

of_get_parent 函数,该函数用于获取指定节点的父节点(如果有父节点的话)。

struct device_node *of_get_parent(const struct device_node *node);

node : 要查找父节点的节点。

返回值: 找到的父节点。

 of_get_next_child 函数,该函数用迭代的方式查找子节点。

struct device_node *of_get_next_child(const struct device_node *node,
					     struct device_node *prev);

node : 父节点。

prev:**前一个子节点,也就是从哪个子节点开始迭代的查找下一个子节点。可以设置为NULL,表示从第一个子节点开始。

返回值:**找到的下一个子节点

of_find_compatible_node 该函数根据device_type 和compatible 这两个属性查找指定的节点

struct device_node *of_find_compatible_node(struct device_node *from,
const char *type, const char *compat);

from : 开始查找的节点,如果为NULL 表示从根节点开始查找整个设备树。

type :**要查找的节点对应的type 字符串,也就是device_type 属性值。可以为NULL,表示忽略掉device_type 属性。

compatible : 要查找的节点所对应的compatible 属性列表。
返回值:**找到的节点,如果为NULL 表示查找失败。

of_find_matching_node_and_match该函数通过 of_device_id 匹配表来查找指定的节点。

struct device_node *of_find_matching_node_and_match(
	struct device_node *from,
	const struct of_device_id *matches,
	const struct of_device_id **match);

from : 开始查找的节点,如果为NULL 表示从根节点开始查找整个设备树。

matches : of_device_id 匹配表,也就是在此匹配表里面查找节点。

match : 找到的匹配的of_device_id 。

返回值:**找到的节点,如果为NULL 表示查找失败。

三.of函数获取设备树节点实验

dts:

/{
    topeet{
        #address-cells = <1>;
        #size-cells = <1>;
        compatible = "simple-bus";

        myLed{
            compatible = "my devicetree";
            reg = <0xFDD60000 0x00000004>;
        };
    };
};

驱动程序:

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/of.h>

struct device_node *mydevice_node;      
const struct of_device_id *mynode_match;
struct of_device_id mynode_of_match[] = {
	{.compatible="my devicetree"},
	{},
};

// 平台设备的初始化函数
static int my_platform_probe(struct platform_device *pdev)
{
    printk(KERN_INFO "my_platform_probe: Probing platform device\n");

    // 通过节点名称查找设备树节点
    mydevice_node = of_find_node_by_name(NULL, "myLed");
	printk("mydevice node is %s\n", mydevice_node->name);
    
	// 通过节点路径查找设备树节点
    mydevice_node = of_find_node_by_path("/topeet/myLed");
    printk("mydevice node is %s\n", mydevice_node->name);
        
    // 获取父节点
    mydevice_node = of_get_parent(mydevice_node);
    printk("myled's parent node is %s\n", mydevice_node->name);
            
    // 获取子节点
    mydevice_node = of_get_next_child(mydevice_node, NULL);
    printk("myled's sibling node is %s\n", mydevice_node->name);

	// 使用compatible值查找节点
	mydevice_node=of_find_compatible_node(NULL ,NULL, "my devicetree");
	printk("mydevice node is %s\n" , mydevice_node->name);
	
	//根据给定的of_device_id匹配表在设备树中查找匹配的节点
	mydevice_node=of_find_matching_node_and_match(NULL , mynode_of_match, &mynode_match);
	printk("mydevice node is %s\n" ,mydevice_node->name);
	return 0;
}

// 平台设备的移除函数
static int my_platform_remove(struct platform_device *pdev)
{
    printk(KERN_INFO "my_platform_remove: Removing platform device\n");

    // 清理设备特定的操作
    // ...

    return 0;
}


const struct of_device_id of_match_table_id[]  = {
	{.compatible="my devicetree"},
};

// 定义平台驱动结构体
static struct platform_driver my_platform_driver = {
    .probe = my_platform_probe,
    .remove = my_platform_remove,
    .driver = {
        .name = "my_platform_device",
        .owner = THIS_MODULE,
		.of_match_table =  of_match_table_id,
    },
};

// 模块初始化函数
static int __init my_platform_driver_init(void)
{
    int ret;

    // 注册平台驱动
    ret = platform_driver_register(&my_platform_driver);
    if (ret) {
        printk(KERN_ERR "Failed to register platform driver\n");
        return ret;
    }

    printk(KERN_INFO "my_platform_driver: Platform driver initialized\n");

    return 0;
}

// 模块退出函数
static void __exit my_platform_driver_exit(void)
{
    // 注销平台驱动
    platform_driver_unregister(&my_platform_driver);
    printk(KERN_INFO "my_platform_driver: Platform driver exited\n");
}

module_init(my_platform_driver_init);
module_exit(my_platform_driver_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("topeet");

  • 22
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式_笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值