1、设备树节点信息结构体
#include<linux/of.h>
struct device_node {
const char *name; //设备树节点名 mynode
const char *full_name;//完整的设备树节点名 mynode@0x12345678
struct property *properties;//属性链表头节点
struct device_node *parent;//父节点地址
struct device_node *child;//子节点地址
struct device_node *sibling;//兄弟节点地址
};
2、设备树节点属性结构体
struct property {
char *name;//键名
int length;//值的长度
void *value;//值
struct property *next;//下一个属性结构体首地址
};
3、解析设备树节点信息相关API
1.struct device_node *of_find_node_by_name(struct device_node *from,
const char *name);
功能:根据设备树节点的名字解析设备树节点
参数:
from:当前节点父节点首地址(不知道就填NULL,默认从设备树根节点开始解析)
name:设备树节点名字 mynode
返回值:成功获取到解析的设备树节点信息结构体首地址,失败返回NULL
2.struct device_node *of_find_node_by_path(const char *path)
功能:根据设备树节点路径解析设备树节点
参数:
path:设备树节点路径 /mynode0x12345678
返回值:成功获取到解析的设备树节点信息结构体首地址,失败返回NULL
3.struct device_node *of_find_compatible_node(struct device_node *from,
const char *type, const char *compat);
功能:根据设备树节点中compatibe键来解析设备树节点
参数:
from:填NULL,默认从根节点开始解析
type:NULL
compat:填写要解析的设备树节点中compatible的值
返回值:成功获取到解析的设备树节点信息结构体首地址,失败返回NULL
实例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/of.h>
struct device_node *node;
static int __init mycdev_init(void)
{
//根据设备树节点路径解析设备树节点
node = of_find_node_by_path("/mynode@0x12345678");
if(node == NULL)
{
printk("查找失败...\n");
return -1;
}
printk("name=%s, value=%s\n", node->properties->name, (char *)(node->properties->value));
printk("name=%s, value=%s\n", node->properties->next->name, (char *)(node->properties->next->value));
printk("name=%s, value=%x, value=%x\n", node->properties->next->name,
__be32_to_cpup((uint32_t *)(node->properties->next->next->value)),
__be32_to_cpup((uint32_t *)(node->properties->next->next->value+4)));
return 0;
}
static void __exit mycdev_exit(void)
{
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
4、解析设备树节点属性相关API
struct property *of_find_property(const struct device_node *np,
const char *name,
int *lenp)
功能:基于解析后的设备树节点信息结构体解析指定属性键值对
参数:
np:设备树节点信息结构体指针
name:指定的键名
lenp:获取到的字节个数
返回值:成功返回属性结构体首地址,失败返回NULL
实例
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/of.h>
struct device_node *node;
struct property *pr;
unsigned int val;
int len;
static int __init mycdev_init(void)
{
int i;
//根据设备树节点路径解析设备树节点
node = of_find_node_by_path("/mynode@0x12345678");
if(node == NULL)
{
printk("of_find_node_by_path failded...\n");
return -1;
}
//解析指定键名的属性
pr = of_find_property(node, "binarry", &len);
for(i=0;i<len;i++)
{
printk("name=%s, value=%x\n", pr->name, *(uint8_t *)(pr->value+i));
}
return 0;
}
static void __exit mycdev_exit(void)
{
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
5、根据设备树节点信息结构体和键名解析各类型的值
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/of.h>
struct device_node *node;
struct property *pr;
unsigned int val;
unsigned char c_val;
const char *buf;
static int __init mycdev_init(void)
{
//根据设备树节点路径解析设备树节点
node = of_find_node_by_path("/mynode@0x12345678");
if(node == NULL)
{
printk("of_find_node_by_path failded...\n");
return -1;
}
//根据设备树节点信息结构体和键名解析uint类型的值(索引号)
if(of_property_read_u32_index(node, "uint", 0, &val))
{
printk("of_property_read_u32_index failed...\n");
return -1;
}
printk("%x\n", val);
//根据设备树节点信息结构体和键名解析uint类型的值(数组)
if(of_property_read_u32_array(node, "uint", &val, 1))
{
printk("of_property_read_u32_array failed...\n");
return -1;
}
printk("%x\n", val);
//根据设备树节点信息结构体和键名解析u8类型的值(数组)
if(of_property_read_u8_array(node, "binarry", &c_val, 1))
{
printk("of_property_read_u8_array failed...\n");
return -1;
}
printk("%x\n", c_val);
//根据设备树节点信息结构体和键名解析字符串的值
if(of_property_read_string(node, "astring", &buf))
{
printk("of_property_read_string failed...\n");
return -1;
}
printk("%s\n", buf);
return 0;
}
static void __exit mycdev_exit(void)
{
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");