Linux系统驱动(十)设备树

news2024/9/27 9:30:55

文章目录

  • 一、简介
  • 二、设备树语法
    • (一)设备树的组成
      • 1. 节点的组成
        • (1)节点的别名
        • (2)节点可以被引用
        • (3)同名节点的合并
      • 2. 属性的组成
        • (1)值的字符串表示形式
        • (2)值的无符号32位数的表示形式
        • (3)值的16进制表示的单字节的数的形式
        • (4)混合类型的值的表示形式
        • (5)reg描述属性的用法
      • 3. 设备树语法示例
    • (二)添加一个设备树节点
        • (1)添加自己的设备树节点
        • (2)编译设备树
        • (3)拷贝生成的设备树文件以及镜像文件到tftpboot文件中
        • (4)切换到/proc/device-tree目录下
        • (5)cd进入mynode节点
  • 二、驱动获取设备树的信息
    • (一)设备树节点相关结构体
      • 1. device_node结构体
      • 2. property结构体
    • (二)获取节点的函数接口
      • 1. 接口
      • 2. 代码示例
      • 3. 描述节点名

一、简介

在linux内核启动时才会解析dtb

3.10版本之后才有设备树
设备树帮助文档官网:https://elinux.org/Device_Tree_Usage

二、设备树语法

(一)设备树的组成

设备树由节点属性组成的树状结构,节点可以包含属性和子节点,属性就是键值对

1. 节点的组成

<name>[@<unit-address>]
name :代表节点的类型名,不是设备名,它是有字符串组成的,最多不超过31个字符(超过的字符就不再进行区分了)
<unit-address> :如果节点内描述的有地址,这个对应的就是它的地址

eg:
serial@101f1000{}; //串行设备,地址是101f1000

(1)节点的别名
/{
	node:mynode@0x12345678{};
};

别名node在编译阶段使用,编译后就会被替换

(2)节点可以被引用

引用节点必须放在根节点之外
解析时会将其引用节点和被引用节点合并。
同名的属性,后者的值会将前面的值覆盖掉;
不同的属性,后者会添加到前者中;

/{
	node:mynode@0x12345678{};
};

&node{
};
(3)同名节点的合并

同级路径下同名节点会合并为一个节点,同名的属性,后者的值会将前面的值覆盖掉
在这里插入图片描述

2. 属性的组成

属性是简单的键值对,值可以为空,也可以是字节流

  • 注:所有语句结尾要加分号;
(1)值的字符串表示形式

string-property = "a string";
值用双引号""引起来,多个字符串使用逗号,分隔

(2)值的无符号32位数的表示形式

cell-property = <0xbeee 123 0xabcd1234>
值用尖括号<>引起来,多个值用空格分隔

(3)值的16进制表示的单字节的数的形式

binary-property = [00 01 23 45 67];
值用方括号[]引起来,多个值被空格分隔,使用十六进制的数表示
只能表示单字节的数

注:前面的0不能省略

(4)混合类型的值的表示形式

mixed-property = "a string", [01 23 45 67], <0x12345678>;
多个值使用逗号,分隔

(5)reg描述属性的用法
/ {
    #address-cells = <1>; //修饰子节点一个元素组成中的地址成员个数
    #size-cells = <1>;    //修饰子节点一个元素组成中的长度成员个数

    serial@101f0000 {
        compatible = "arm,pl011";
        reg = <0x101f0000 0x1000 >; //地址,长度
    };
};

/ {
    #address-cells = <1>; //修饰子节点一个元素组成中的地址成员个数
    #size-cells = <0>;    //修饰子节点一个元素组成中的长度成员个数
    serial@101f0000 {
        compatible = "arm,pl011";
        reg = <0x40 >; //地址(比如i2c从机地址就可以这样写)
    };
};

3. 设备树语法示例

/dts-v1/;  //设备树的版本号

/ {  //  /{};这是设备树的根节点
    node1 {  // node1是根节点的子节点
        a-string-property = "A string"; //属性
        a-string-list-property = "first string", "second string";
        a-byte-data-property = [01 23 34 56];
        child-node1 { //child-node1是node1的子节点
            first-child-property; //空属性,只起到标识作用
            second-child-property = <1>;
            a-string-property = "Hello, world";
        };
        child-node2 { //child-node2是node1的子节点
        };
    };
    node2 {  // node2是根节点的子节点
        an-empty-property; //空属性,只起到标识作用
        a-cell-property = <1 2 3 4>; /* each number (cell) is a uint32 */
        child-node1 { //child-node1是node2的子节点
        };
    };
};
  • 相同路径的同名节点会合并到一起

(二)添加一个设备树节点

(1)添加自己的设备树节点

linux-5.10.61/arch/arm/boot/dts/stm32mp157a-fsmp1a.dtb

//在根节点下,添加如下信息,此处的代码仅为体现语法,并无实际意义
mynode@0x12345678{
	a-string = "hello drivers";
	a-uint = <0x11223344 0xaabbccdd>;
	a-uchar = [00 0c 29 b2 d3 0c];
	a-mixdata = "ethar",<0x12345678>,[11 22 33];
};
(2)编译设备树

切换到家目录下,执行make dtbs
在这里插入图片描述

(3)拷贝生成的设备树文件以及镜像文件到tftpboot文件中

重启开发板,使其重新解析设备树文件

(4)切换到/proc/device-tree目录下

在这里插入图片描述
自己的节点是添加在根目录下的,因此在此目录下可以直接找到

(5)cd进入mynode节点

在这里插入图片描述
可以看到自己的节点中的节点信息

二、驱动获取设备树的信息

(一)设备树节点相关结构体

1. device_node结构体

设备树的每个节点内核解析后都会创建出来一个device_node的结构体,用来描述节点

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. property结构体

在同一个节点中,每个属性都通过一个property描述,所有的property构成一条单链表

struct property {
        char *name; //键
        int length;    //值的长度,单位字节
        void *value; //值
        struct property *next; //指向下一个属性的指针
    }

(二)获取节点的函数接口

1. 接口

#include <linux/of.h>

struct device_node *of_find_node_by_path(const char *path)
功能:通过节点的路径获取节点(节点名必须是全名?)
参数:
 @path:节点的路径  "/mynode@0x12345678"
返回值:成功返回节点的首地址,失败返回NULL

struct device_node *of_find_node_by_name(struct device_node *from,const char *name)
功能:通过节点名获取节点
参数:
 @from:写成NULL代表从根节点开始解析,如果填已知节点,会从已知节点开始解析
 @name:节点名 "mynode"
返回值:成功返回节点的首地址,失败返回NULL

2. 代码示例

#include <linux/module.h>
#include <linux/init.h>
#include <linux/of.h> //设备树文件相关头文件

//设备文件的节点信息 
//mynode@0x12345678{
// 	a-string = "hello drivers";
// 	a-uint = <0x11223344 0xaabbccdd>;
// 	a-uchar = [00 0c 29 b2 d3 0c];
// 	a-mixdata = "ethar",<0x12345678>,[11 22 33];
// };

static int __init mynode_init(void){
    struct device_node *mynode;
    mynode = of_find_node_by_path("/mynode@0x12345678");
    if(NULL == mynode){
        pr_err("of_find_node_by_path error");
        return -ENODATA;
    }
    printk("nodename=%s{\n%s=%s\n%s=%#x,%#x\n}\n",mynode->name,\
    mynode->properties->name,(char *)mynode->properties->value,\
    mynode->properties->next->name,*(unsigned int *)mynode->properties->next->value,\
    *(((unsigned int *)mynode->properties->next->value) + 1));
    return 0;
}
static void __exit mynode_exit(void){

}

module_init(mynode_init);
module_exit(mynode_exit);
MODULE_LICENSE("GPL");
  • 注:在设备树中unsigned int数据存储的时候采用的是大端

3. 描述节点名

compatible="厂商,设备名";
一般放在节点开头,可以通过compatible属性来获取节点

struct device_node *of_find_compatible_node(
      struct device_node *from,
      const char *type,
      const char *compat)
功能:通过compatilbe获取节点
参数:
 @from:填写NULL,代表从根节点开始解析
 @type:写成NULL
 @compat:"厂商,设备名"
返回值:成功返回节点的首地址,失败返回NULL

在这里插入图片描述

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

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

相关文章

基于STM32开发的停车场管理系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 初始化代码控制代码应用场景 商业停车场管理住宅区停车场管理常见问题及解决方案 常见问题解决方案结论 1. 引言 停车场管理系统通过监测车辆进出情况、空余车位数量以及收费情况&#xff0…

7.2 算法设计与分析-分治法和回溯法

分治法 相对简单&#xff0c;考的概率比较低 分治法&#xff1a;对于一个规模为的问题&#xff0c;若该问题可以容易地解决则直接解决&#xff1b;否则将其分解为k个规模较小的子问题&#xff0c;这些子问题互相独立且与原问题形式相同&#xff0c;递归地解决这些子问题&…

Proxmox Install 8

Proxmox 前言 Proxmox Virtual Environment(简称PVE)是一个开源的服务器虚拟化解决方案,它基于QEMU/KVM和LXC技术。Proxmox VE提供了一个易于使用的Web界面和命令行工具,允许用户轻松地创建和管理虚拟机(VMs)和容器。 Proxmox download Proxmox 官网下载Proxmox 百度网…

Midjourney入门-提示词基础撰写与公式

​ 前言 在前几篇教程里我们已经可以初步使用Midjourney进行出图了。 包括也了解了Midjourney的指令与参数。 但如果你想用Midjourney去生成各种各样高质量的图片&#xff0c; 并且生成的图片是你想要的画面内容&#xff0c;也就是更好控制生成图片的画面内容与风格&#xf…

电脑小白需要知道这些

电脑小白需要知道这些 解决问题 对于刚买到电脑&#xff0c;不懂电脑的新手需要学什么和知道什么&#xff0c;有什么是误区 需要知道 1.Wiodws 10\Windows11不在需要安装杀毒软件 甚至于电脑自带防火墙都可以关闭&#xff08;有时候打开了防火墙反而导致一些奇奇怪怪的问题…

【书生大模型实战营】基础岛-浦语提示词工程实践

【书生大模型实战营】基础岛-浦语提示词工程实践 活动地址&#xff1a;地址 任务 背景问题&#xff1a;近期相关研究发现&#xff0c;LLM在对比浮点数字时表现不佳&#xff0c;经验证&#xff0c;internlm2-chat-1.8b (internlm2-chat-7b)也存在这一问题&#xff0c;例如认为…

生成式AI,在中国工业找到新“活法”

生成式AI&#xff0c;正在经历一场关于落地前景的论战。 在德国中北部城市希尔德斯海姆&#xff0c;世界工业巨头博世已经把生成式AI技术用在了生产线上。他们以AI仿真绘制的方式合成出超过15000张关于产品缺陷的图片&#xff0c;然后将其应用于电机定子生产线的质检。借助生成…

指针基础知识(笔记)

文章目录 1. 概念理解2. 空指针和野指针3. 计算4. 小结5. size_t6. 案例一: 指针查找并返回指定元素索引7. 指针访问多维数组(涉及 int (*ptr)[3]解析)8. 指针数组9. 函数的值传递与地址引用传递① 函数的值传递(pass by value)② 地址传递(pass by reference) 10. 案例二&…

初学Vue

1.v-text 2.v-html 可以解析标签 3.v-pre 4.class绑定 1.字符串绑定 效果 2.对象绑定 效果 3.数组 还可以用data数据带class加上去 4.三元表达式 5.style绑定 1.字符串 2.对象绑定 3.数组绑定 6.计算属性 调用函数 函数如下 面试&#xff1a;计算属性特点 只要值 没有改变…

【Week-G7】Semi-Supervised GAN 实践,使用MNIST数据集

文章目录 一、基础知识二、代码实现2.1 导入所需模块 & 设置网络初始参数2.2 初始化权重2.3 定义算法模型2.4 配置模型2.5 训练模型2.6 训练结果 &#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导…

使用 Claude3.5 只需 2 分钟快速构建仪表盘

这是用 claude 生成的图表&#xff0c;只花了 2 分钟 目录 Claude何时使用Artifacts&#xff1f;我如何使用Artifacts&#xff1f;我的例子让claude导出本地部署结尾 关键还可以分享 这是分享之后的链接&#xff1a; https://claude.site/artifacts/1cf37377-1d00-4ab2-b8dd-a…

PMP考试一定要考到3A吗?怎么备考?

PMP&#xff08;Project Management Professional&#xff09;认证是全球公认的项目管理专业人士资格认证&#xff0c;它代表着项目管理领域的高水平标准。 在备考PMP考试时&#xff0c;有些赛宝关心是否需要考到3A&#xff08;即三个领域均为Above Target&#xff0c;超出目标…

【中项】系统集成项目管理工程师-第10章 项目整合管理-10.7结束项目或阶段

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

[Python学习日记-3] 编程前选择一个好用的编程工具

[Python学习日记-3] 编程前选择一个好用的编程工具 简介 PyCharm IDE的安装 PyCharm IDE安装后的一些常规使用 简介 在踏上 Python 编程的精彩旅程之前&#xff0c;选择一款得心应手的编程工具无疑是至关重要的一步。这就如同战士在出征前精心挑选趁手的武器&#xff0c;它将…

Unity补完计划 之 音效

本文仅作笔记学习和分享&#xff0c;不用做任何商业用途 本文包括但不限于unity官方手册&#xff0c;unity唐老狮等教程知识&#xff0c;如有不足还请斧正 首先&#xff0c;音频这块组件较少&#xff0c;但是内容很重要&#xff0c;因为对于任何一款非特殊面向人群的游戏来说&a…

SQLiteStudio 连接sqlite3数据库(真机数据库可视化调试)

SQLiteStudio安装 官网链接&#xff1a;https://sqlitestudio.pl/ 下载后&#xff0c;直接按部就班&#xff0c;打开即可使用 用户手册&#xff08;工具如何使用直接看这份就可以了&#xff09;&#xff1a;https://github.com/pawelsalawa/sqlitestudio/wiki/User_Manual 其…

GoFly快速开发框架代码市场使用说明

说明 我们框架坚持开源的项目绝不能存在收费项目&#xff0c;所以我们gofly快速开发开源版没有内置代码仓插件&#xff0c;因此需要使用代码市场中的代码包需要再企业版中使用&#xff0c;代码市场插件如下&#xff1a; 图1、社区-代码市场​​​​ 他和企业版管理后台的代码仓…

Component和Loader

文章目录 文章内容效果图代码 文章内容 效果图 代码 import QtQuick 2.15 import QtQuick.Window 2.15 import FluentUI import QtQuick.Controls 2.5Window {visible: truewidth: 320height: 240// 自定义组件:需要手动加载Component{id:comRectangle{id:rectwidth: 80heigh…

关闭Windows安全中心

打开Windows安全中心的病毒和威胁防护。 打开该选项的管理设置。 关闭实时保护。

【RTOS面试题】RTOS和Linux的区别

实时操作系统&#xff08;RTOS, Real-Time Operating System&#xff09;与Linux操作系统&#xff08;一种典型的普通操作系统&#xff0c;General-Purpose Operating System, GPOS&#xff09;之间存在一些显著的区别。这两种操作系统各有侧重&#xff0c;适用于不同的应用场景…