分析设备树文件

news2025/8/12 18:31:40

1.设备树是干嘛的

硬件资源有很多,想要实现分类管理,方便驱动去控制它,则需要设备树来管理硬件信息。

所以,设备树主要存放了一些设备节点信息,键值对,和属性;节点中也可以包含子节点。

2.设备树节点信息的获取

 有三种方法可以获取设备树信息:

1)通过获取节点的函数---- ----  of_find_node_by_path 顾名思义通过路径获取节点信息

成功返回目标节点的地址,失败返回NULL

 为什么调用大小端转换函数?

因为arm架构是大端存储(低地址存储高位数据)正常的阅读习惯是千百十个,低地址存低位

 2)通过属性相关函数---struct property *of_find_property(节点地址,节点名,获取到的字节数)

 3)通过键名获取数值

int of_property_read_u32_index(np:节点结构体指针 propname:键名 index:索引号 out_value:获取到的值 )

返回值:成功返回0,失败返回错误码

int of_property_read_variable_u32_array()

int of_property_read_string

int of_property_read_variable_u8_array

int of_property_read_u8_array

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
//定义结构体获取设备树节点信息
struct device_node *node;
//compatible
struct device_node *compa;
//定义属性结构体获取设备树节点信息
struct property *pr;
int i,len;
//键名获取数值给到val
unsigned int val;
//获取u32数组
unsigned int array[2];
//获取u8数组
char arry[6];
//获取字符串给到str
const char *str;
int ret;
static int __init mycdev_init(void)
{
//通过路径获取设备节点信息
    node=of_find_node_by_path("/mynode@0x12345678");
    if(node==NULL)
    {
        printk("failed\n");
        return -EFAULT;
    }
    printk("succeed\n");
    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);
    //32位无符号整形需要实现小端转大端再输出
    printk("name=%s,value=%#x,%#x\n",node->properties->name,__be32_to_cpup((int *)node->properties->next->next->value),\
    __be32_to_cpup((int *)node->properties->next->next->value+1));

  //通过compatible获取节点信息
    compa=of_find_compatible_node(NULL,NULL,"hqyj,mynode");
    if(compa==NULL)
    {
        printk("failed\n");
        printk("%d\n",__LINE__);
        return -EFAULT;
    }
    printk("succeed\n");
    printk("name1=%s,value1=%s\n",compa->properties->name,(char *)compa->properties->value);  
//1.根据属性名或节点信息结构体名解析出节点内指定名字的属性信息
    
    pr=of_find_property(node,"astring",&len);
    if(pr==NULL)
    {
        printk("属性解析失败\n");
        printk("%d\n",__LINE__);
        return -EFAULT;
    }
    printk("属性解析成功\n");
    printk("name=%s,value=%s\n",pr->name,(char *)pr->value);
    //解析单字节属性
    pr=of_find_property(node,"binarry",&len);
    if(pr==NULL)
    {
        printk("属性解析失败\n");
        printk("%d\n",__LINE__);
        return -EFAULT;
    }
    //循环遍历单字节属性值
    for(i=0;i<len;i++)
    {
        printk("name=%s value=%#x\n",pr->name,*((char *)pr->value+i));
    }
//2.通过键名获取属性名
    //1)根据索引号index获取u32
    ret=of_property_read_u32_index(node,"unit",1,&val);
    if(ret)
    {
        printk("u32获取失败,ret=%d\n",ret);
        printk("%d\n",__LINE__);
        return -EFAULT;
    }
    printk("value=%#x\n",val);
    //2)获取u32数组,失败返回错误码
    ret=of_property_read_variable_u32_array(node,"unit",array,2,2);
    if(ret<0)
    {
        printk("获取u32数组失败\n");
        printk("%d\n",__LINE__);
        return -EFAULT;
    }
    printk("value:%#x %#x\n",array[0],array[1]);
    //3)获取u8数组1
    ret=of_property_read_variable_u8_array(node,"binarry",arry,6,6);
    if(ret<0)
    {
        printk("获取u8数组失败\n");
        printk("%d\n",__LINE__);
        return -EFAULT;
    }
    printk("binarry=[");
    for(i=0;i<6;i++)
    {
        printk("%#x ",arry[i]);
    }
    printk("]\n");
    //3)获取u8数组2
    ret=of_property_read_u8_array(node,"binarry",arry,6);
    if(ret)
    {
        printk("获取u8数组失败\n");
        printk("%d\n",__LINE__);
        return -EFAULT;
    }
    printk("binarry=[");
    for(i=0;i<6;i++)
    {
        printk("%#x ",arry[i]);
    }
    printk("]\n");
    //属性获取字符串
    ret=of_property_read_string(node,"astring",&str);
    if(ret)
    {
        printk("string not get\n");
        printk("%d\n",__LINE__);
        return -EFAULT;
    }
    printk("astring=%s\n",str);
    return 0;


}

static void __exit mycdev_exit(void)
{

}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

 打印信息:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/33415.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安全架构中的前端安全防护研究

国家互联网应急中心发布的被篡改网站数据让很多人触目惊心&#xff0c;近年来各种Web网站攻击事件频频发生&#xff0c;网站SQL注入&#xff0c;网页被篡改、信息失窃、甚至被利用成传播木马的载体Web安全形势日益严峻&#xff0c;越来越受到人们的关注。 Gartner 对安全架构的…

创建计划协议、维护创建计划、收货

创建计划协议事务码&#xff1a;ME31L创建计划协议 &#xff08;ME32L 修改计划协议 ME33L查询计划协议 ME2L查询采购订单&#xff09; 输入&#xff1a;供应商、协议类型、协议日期、采购组织、采购组、工厂、存储地点等信息后回车。 然后输入有效截至日期&#xff0c; 再点击…

计算机毕业设计java+springboot宠物商城系统

一、项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot Maven mybatis Vue 等等组成&#xff0c;B…

【JVM】垃圾回收:垃圾收集器

一、语境中的并行与并发 并行 并行描述的时多条垃圾收集器线程之间的关系&#xff0c;说明同一时间有多条这样的线程在协同工作&#xff0c;通常默认此时用户线程是处于等待状态。 并发 并发描述的是垃圾收集器线程与用户线程之间的关系&#xff0c;说明同一时间垃圾收集器线程…

简单实现一个虚拟形象系统

前言 上周启动居家开会的时候&#xff0c;看到有人通过「虚拟形象」功能&#xff0c;给自己带上了口罩、眼镜之类&#xff0c;于是想到了是不是也可以搞一个简单的虚拟形象系统。 大致想来&#xff0c;分为以下几个部分&#xff1a; 卷积神经网络(CNN) 下面讲解一下三层CN…

视频格式转换器哪个好用?万兴优转-好用的视频格式转换器

视频格式转换器是用于转换视频格式的软件&#xff0c;是指用于视频转换、音频转换、CD轨抓取、音视频混合转换、音视频剪切、连接转换、视频水印叠加、滚动字幕、个性化文字、图片叠加、视频相框叠加的音视频转换工具。 也就是说&#xff0c;视频有非常多的格式如AVI、VCD、SVC…

【JavaWeb从零到一】会话技术CookieSessionJSP

&#x1f680;【JavaWeb从零到一】系列文章目录 &#x1f6a9;【JavaWeb从零到一】前置知识 &#x1f6a9;【JavaWeb从零到一】Mysql基础总结 &#x1f6a9;【JavaWeb从零到一】JDBC详解 &#x1f6a9;【JavaWeb从零到一】JDBC连接池&JDBCTemplate Cookie&Session&…

王学岗音视频开发(二)—————OpenGLES开发实践

矩阵以及矩阵运算 上图就是m x a 的矩阵 1x30x22x1 :为左侧第一行乘以右侧第一列。 1x10x12x0 :为左侧第一行乘以右侧第二列。 -1x33x21x1:为左侧第二行乘以右侧第一列。 -1x13x11x0:为左侧第二行乘以右侧第二列。 矩阵的行列式 伴随矩阵 A*表示伴随矩阵 OpenGL 教程----屏…

Grails SpringBoot国际化不生效

问题描述&#xff1a; grails项目使用了国际化&#xff0c;按照官方文档的说法&#xff1a; 会根据用户浏览器访问时使用的Accept-Language头自动选择合适的语言。 但无论浏览器了配置什么语言甚至配置了Tomcat启动参数 -Duser.languagexxx -Duser.regionxxx页面显示依旧是英…

[附源码]java毕业设计一点到家小区微帮服务系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

QPushButton按钮用法

QPushButton 简介 QPushButton是一个很常用的一个按钮控件&#xff0c;主要用于创建一个可按压的按键。它显示了一 个文本和一个图标。另外&#xff0c;你也可以在创建时&#xff0c;指定一个快捷键。 基本用法 1. 创建 QPushButton主要有两种创建方法&#xff0c;一种是直…

SQLite实现的学生管理系统

SQLite数据库 案例资源所在地址&#xff1a; https://download.csdn.net/download/weixin_41957626/87150608?spm1001.2014.3001.5503 1.简介 1.1引入 1.前面学习的文件存储和SharedPreference存储的方式只能存储一些小型的数据但是对于复杂关系以及复杂数据结构的数据仅仅靠…

交互与前端16 Tabulator 表格实践4

说明 继续给表格来加一些小功能。 内容 1 分页 在表格初始化的地方加两行配置,表格就实现了分页 pagination:true, //enable.paginationSize:20, // this option can take any positive integer value2 超链接 这个需求的来源是,一些微服务需要注释,所以我写了很多文档…

科研教育「双目视觉技术」首选!维视MV-VS220双目立体视觉系统开发平台

NO.1产品背景 在最近大热的自动驾驶赛道&#xff0c;大疆采用新的技术路线——双目立体视觉。具体来说&#xff0c;它就是模拟人的视觉系统&#xff0c;通过两个临近摄像头所拍摄到的画面的视差&#xff0c;来还原出三维立体结构。不需要对海量数据进行标注和训练&#xff0c;可…

Echarts 散点象限图(二)动态绘制

之前发布过一篇文章Echarts散点象限图,基于死数据来绘制的,但实际开放场景中,需要请求数据,而且可能会动态更改数据,这时候需要如何处理,有什么要注意的地方,这篇文章详细说明一下。 主要需要处理的地方就是四个象限的markArea,需要根据中心的位置来画,你可以想象成…

36 - 经典问题解析三(赋值 string)

---- 整理自狄泰软件唐佐林老师课程 1. 关于赋值的疑问 什么时候需要重载赋值操作符&#xff1f;编译器是否提供默认的赋值操作&#xff1f; 编译器为每个类 默认重载了赋值操作符默认的赋值操作符 仅完成 浅拷贝当需要进行 深拷贝 时 必须重载赋值操作符赋值操作符与拷贝构造…

Elasticsearch系列【1】概述

有道无术&#xff0c;术尚可求&#xff0c;有术无道&#xff0c;止于术。 文章目录Elastic公司Elastic StackElasticsearch结构化/非结构化数据全文搜索ES 发展史ES 特点ES 应用场景ES 应用案例Beats 系列LogstashKibanaElastic公司 Elastic是一家以搜索引擎闻名世界的软件公司…

pythoin爬虫2之利用cookie进行登录

python爬虫2之利用cookie进行登录利用requests模拟post方法cookies的获取session综合实例拓展&#xff1a;实现时间间隔&#xff08;第一次抓取后间隔...秒进行下一次抓取&#xff09;利用requests模拟post方法 requests.post(url,data,hearders) url即要解析的网址data即是向服…

【学习笔记18】JavaScript对象的基本认识

一、什么是对象 &#xff08;一&#xff09;概念 &#x1f603; 就是一个数据的集合(复杂数据)&#x1f601; 对象属于复杂数据类型(引用数据类型) &#xff08;二&#xff09;知识点的补充 JS 的数据类型 1. 基本数据 2. 复杂数据&#xff08;引用数据类型&#xff09; 引用数…

图像处理技术:数字图像分割 ------ 图像分割、边界分割(边缘检测)、区域分割

一、图像分割概述 • 定义 是指根据灰度、彩色、空间纹理、几何形状等特征把图像划分 成若干个互不相交的区域&#xff0c;使得这些特征在同一区域内表现出一致 性或相似性&#xff0c;而在不同区域间表现出明显的不同 分割出来的区域应该同时满足&#xff1a; (1&#xff09…