4.15号驱动

设备树

1. 设备树介绍

1.1 引入

在linux内核3.10版本之前,arm公司将驱动相关的硬件信息(地址、中断号、i2c从机地址)都存放在arch/arm目录

由于每一个设备都会对应一个文件,进行描述硬件的信息,这个目录下会存放大量的垃圾代码,有些驱动不存在,硬件的信息依然存在这个目录下,会导致这个目录没有层次结构

arm公司效仿PowerPC架构,进行整改

1.2 什么是设备树

在linux内核3.10版本之后,内核中引入了设备树,设备树用来存放硬件相关的信息

它本质上就是一个结构体,这个管理方式会让层次目录更为清晰

这个设备树在内核启动时,会被内核进行解析

驱动工程师需要将所有的硬件相关信息,编写到设备树中

编程时从设备树中获取相关地址信息就可以

1.3 设备树相关文件

设备树目录:linux@ubuntu:~$ cd linux-5.10.61/arch/arm/boot/dts/

设备树源文件:stm32mp157a-fsmp1a.dts

设备树头文件:stm32mp15xx-fsmp1x.dtsi

编写设备树命令:make dtbs

设备树镜像文件:stm32mp157a-fsmp1a.dtb

1.4 设备树语法

设备树由节点和子节点组成

节点中包含属性、键值对信息

1.5 属性/键值对格式(重点)

用双引号标识字符串属性:

string-property = "a string";

用尖括号标识无符号32位整数列表:

cell-property = ;

用中括号分隔二进制列表:

binary-property = [01 23 45 67];

可以使用逗号分隔混合键值对:

mixed-property = "a string", [01 23 45 67], ;

用逗号分隔串属性字符串列表:

string-list = "red fish", "blue fish";

1.6 节点格式(重点)

节点格式:<name>[@<unit-address>]

<name>是一个简单的 ASCII 字符串,长度最多为 31 个字符

节点是根据它所代表的设备类型来命名

@:分隔符

unit-address:地址

2. 添加设备树

2.1 添加步骤

设备树目录:linux@ubuntu:~$ cd linux-5.10.61/arch/arm/boot/dts/

打开设备树源文件:vi stm32mp157a-fsmp1a.dts

添加如下节点信息

编译设备树,并且进行拷贝

3. 设备树结构体

在linux内核解析设备树成功之后,每一个节点会通过device_node结构体进行描述

属性是通过struct property结构体进行描述

在同一个节点中,属性构成链表

3.1 节点结构体

struct device_node { //mynode@0x12345678
    const char *name; //节点的名字mynode
    const char *full_name; //节点全名字mynode@0x12345678
    struct property *properties; //属性结构体
    struct  device_node *parent;  //父节点
    struct  device_node *child;   //子节点
};

3.2 属性结构体

struct property {
    char    *name; //属性对应的名字,键值对对应的键的名称
    int length; //值的长度
    void    *value; //属性对应的内容,键值对对应的值的内容
    struct property *next; //指向同一个节点,下一个属性信息
    //在同一个节点中,属性构成链表
};    

4. 设备树API接口

4.1 获取节点API接口

#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  
    
struct device_node *of_find_compatible_node(struct device_node *from,
    const char *type, const char *compat);    
函数功能:通过产商固定含义的键,获取节点相关的信息
参数:
    from:NULL,表示从根节点出发
    type:NUL
   compat:固定产商的名称("hqyj,fsmp1a")
返回值:
    成功返回节点结构体指针
    失败返回NULL  

4.2 获取属性API接口

struct property *of_find_property(const struct device_node *np,
                     const char *name,
                     int *lenp);
函数功能:根据设备节点的名称,获取属性相关的信息
参数:
    np:节点名称
    name:属性对应的名称
    lenp:值的长度
返回值:
    成功返回属性结构体指针首地址
    失败返回NULL
    
int of_property_read_string(const struct device_node *np,
                   const char *propname,
                   const char **out_string);
函数功能:通过键值对键的名称,获取字符串属性
参数:
    np:节点名称
    propname:字符串属性名称
    out_string:字符串属性输出内容
返回值:
    成功返回0
    失败返回错误码
    
int of_property_read_u32_array(const struct device_node *np,
                         const char *propname,
                         u32 *out_values, size_t sz)
函数功能:通过属性名称,获取无符号32位整数列表信息
参数:
    np:节点名称
    propname:无符号32位整数列表属性名称
    out_values:获取到的无符号32位整数列表的信息
    sz:无符号32位整数列表的成员个数
返回值:
    成功返回0
    失败返回错误码     
    
int of_property_read_u8_array(const struct device_node *np,
                        const char *propname,
                        u8 *out_values, size_t sz)     
函数功能:通过属性名称,获取二进制列表信息
参数:
    np:节点名称
    propname:二进制列表属性名称
    out_values:获取到的二进制列表的信息
    sz:二进制列表的成员个数
返回值:
    成功返回0
    失败返回错误码  
      
int of_property_read_u32_index(const struct device_node *np,
                       const char *propname,
                       u32 index, u32 *out_value);   
函数功能:通过属性名称,获取无符号32位整数列表对应索引号的信息
参数:
    np:节点名称
    propname:无符号32位整数列表属性名称
    index:索引号
    out_values:获取到的无符号32位整数列表的信息
返回值:
    成功返回0
    失败返回错误码  

5. 获取子节点信息

5.1 添加子节点

设备树目录:linux@ubuntu:~$ cd linux-5.10.61/arch/arm/boot/dts/

打开设备树源文件:vi stm32mp157a-fsmp1a.dts

添加如下子节点节点信息

编译设备树,并且进行拷贝

5.2 获取子节点API接口

struct device_node *of_get_child_by_name(const struct device_node *node,
                    const char *name);
函数功能:获取子节点信息
参数:
    node:父节点结构体指针
    name:子节点名字
返回值:
    成功返回子节点结构体指针首地址
    失败返回NULL

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

最新可用免费云服务器推荐汇总

随着云计算技术的不断发展&#xff0c;越来越多的企业和个人开始关注并尝试使用云服务器。云服务器以其高度的灵活性、可扩展性和成本效益&#xff0c;成为了部署应用和存储数据的理想选择。本文将为大家汇总目前市场上最新可用的免费云服务器资源&#xff0c;帮助大家更好地了…

HG泄露(ctfhub)

工具准备&#xff1a;dirsearch、dvcs-ripper 网络安全之渗透测试全套工具篇&#xff08;内含安装以及使用方法&#xff09;_dvcs-ripper-CSDN博客 dvcs-ripper&#xff1a;一款perl的版本控制软件信息泄露利用工具&#xff0c;支持bzr、cvs、git、hg、svn... tree //树状…

毕设论文的分类号与UDC查询

对于毕业论文分类号与UDC&#xff0c;可以根据个人研究领域查询。 中图分类号查询链接&#xff1a; 中图分类号查询 | 中国图书馆分类法 | 中图法 | 中图分类号 (clcindex.com)https://www.clcindex.com/category/ UDC查询链接: UDC Summaryhttps://udcsummary.info/php/ind…

Appium Desktop + Appium Inspector + 模拟器连接

一、环境预备 1.你需要安装好配置好adb,确保可以在命令行直接运行adb指令 2.安装Appium Desktop、Appium Inspector 、 模拟器 二、启动appium 服务 启动后&#xff0c;画面如下&#xff1a; 三、启动模拟器 此时&#xff0c;启动模拟器&#xff0c;打开电脑cmd窗口&#x…

数模转换(ADC)、IIC、2440内部IIC寄存器、主机发送、主机接收

我要成为嵌入式高手之4月15日ARM第八天&#xff01;&#xff01; ———————————————————————————— ADC 概念 ADC是模拟到数字转换器的缩写。是一种电子设备或者模块。用于将连续变化的模拟信号转换为离散的数字信号&#xff0c;以便数字系统能够对…

【北京迅为】《iTOP-3588开发板系统编程手册》-第7章 Linux终端会话和进程管理

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

基于ADB的Scrcpy实现电脑控制手机

Scrcpy是一个开源的&#xff0c;基于ADB&#xff08;Android 调试桥&#xff09;的手机到电脑上的投屏操控的实现&#xff0c;本文将介绍如何搭建开发环境&#xff0c;使得在Windows系统中去控制投屏的安卓手机。 1. 安装投屏软件 下载Scrcpy软件到电脑上&#xff0c;该软件中…

类的加载,反射和注解详解

文章目录 类的加载概述类加载器作用分类获取类加载器的方式 双亲委派机制3种加载器的关系工作机制 类加载器的应用 反射概述关键获取类对象获取构造器对象获取方法对象获取成员变量对象作用 注解概述作用自定义注解格式属性类型 元注解常见的元注解 注解解析概述方法技巧 类的加…

windows停掉jenkins服务

在Windows系统中&#xff0c;如果你需要停止Jenkins服务&#xff0c; 使用服务管理器&#xff08;Service Manager&#xff09;: 打开“运行”对话框&#xff08;Win R&#xff09;&#xff0c;输入services.msc&#xff0c;然后回车。 在服务列表中找到“Jenkins”服务&am…

财务软件行业背景-易舟云

财税是每个企业的基本基石之一。财务报告讲述了公司的故事——它的利润和亏损、收益和债务、税收支出以及可用于未来增长的资产。随着信息时代的飞速发展&#xff0c;财务信息化建设日益完善&#xff0c;大量基于计算机网络的应用系统已经逐步深入财务管理领域。传统的会计录入…

1102: 顺序表上数据的划分问题的实现

解法&#xff1a; #include<iostream> #include<vector> #include<stack> #include<queue> using namespace std; int main() {int n;cin >> n;vector<int> arr(n);stack<int> stk;queue<int> que;for (auto& x : arr) c…

【多线程】阻塞队列 | put()方法 | take()方法 | 生产者-消费者模式 |实现阻塞队列

文章目录 阻塞队列1.生产者-消费者模式生产者消费者模型的意义&#xff1a;1.解耦合2.削峰填谷&#xff1a; 2.阻塞队列的使用BlockingQueue 3.实现阻塞队列唤醒&#xff1a;使用阻塞队列实现生产者消费者模型 阻塞队列 阻塞队列是一种特殊的队列&#xff1a; 1.是线程安全的。…