Linux设备树

一、起源

减少垃圾代码

减轻驱动开发工作量

驱动代码和设备信息分离

参考Open Fireware设计

用来记录硬件平台中各种硬件设备的属性信息

二、基本组成

两种源文件:

  1. xxxxx.dts dts是device tree source的缩写
  2. xxxxx.dtsi dtsi是device tree source include的缩写,意味着这样源文件用于被dts文件包含用

实际使用时,需要把dts文件编译成对应的二进制文件(.dtb文件,dtb是device tree binary的缩写 )便于运行时存放在内存加快读取信息的速度

三、基本语法

dts文件主体内容由多个节点组成

每个节点可以包含0或多个子节点,形成树状关系

每个dts文件都有一个根节点,其它节点都是它的子孙

根节点一般来描述整个开发板硬件平台,其它节点用来表示具体设备、总线的属性信息

各个节点可以有多个属性,每个属性用key-value键值对来表示

节点语法:

[label:] node-name[@unit-address] {    [properties definitions];    [child nodes];
};label: 可选项,节点别名,为了缩短节点访问路径,后续节点中可以使用  &label 来表示引用指定节点
node-name: 节点名
unit-address: 设备地址,一般填写该设备寄存器组或内存块的首地址
properties definitions:属性定义
child nodes:子节点

属性语法:

[label:] property-name = value;
[label:] property-name;属性可以无值
有值的属性,可以有三种取值:
1. arrays of cells(1个或多个32位数据, 64位数据使用232位数据表示,空格分隔),用尖括号表示(< >)
2. string(字符串), 用双引号表示(" ")
3. bytestring(1个或多个字节,空格分隔),用方括号表示([])
4.,分隔的多值

四、特殊节点

4.1 根节点

根节点表示整块开发板的信息

#address-cells   // 在子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells      // 在子节点的reg属性中, 使用多少个u32整数来描述大小(size)
compatible       // 定义一系列的字符串, 用来指定内核中哪个machine_desc可以支持本设备,即描述其兼容哪些平台                         
model            // 比如有2款板子配置基本一致, 它们的compatible是一样的,那么就通过model来分辨这2款板子

4.2 /memory

所有设备树文件的必需节点,它定义了系统物理内存的 layout

device_type = "memory";
reg             //用来指定内存的地址、大小

4.3 /chosen

传递内核启动时使用的参数parameter

bootargs  //字符串,内核启动参数, 跟u-boot中设置的bootargs作用一样

4.4 /cpus 多核CPU支持

/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性用来标明自己是哪一个cpu

所以 /cpus 中有以下2个属性:

#address-cells   // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells      // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size) 必须设置为0

五、常用属性

5.1 phandle

​ 数字形式的节点标识,在后续节点中属性值性质表示某节点时,可以引用对应节点

​ 如:

pic@10000000 {    phandle = <1>;    interrupt-controller;
};
another-device-node {    interrupt-parent = <1>;   // 使用phandle值为1来引用上述节点
};

5.2 地址 --------------- 重要

reg属性:表示内存区域region,语法:

reg = <address1 length1 [address2 length2] [address3 length3]>;

#address-cells:reg属性中, 使用多少个u32整数来描述地址(address),语法:

#address-cells = <数字>;

#size-cells:reg属性中, 使用多少个u32整数来描述大小(size),语法:

#size-cells = <数字>;

5.3 compatible --------------- 重要

驱动和设备(设备节点)的匹配依据,compatible(兼容性)的值可以有不止一个字符串以满足不同的需求,语法:

compatible = "字符串1","字符串2",...;

5.4 中断 --------------- 重要

a. 中断控制器节点用的属性:

interrupt-controller 一个无值空属性用来声明这个node接收中断信号,表示该节点是一个中断控制器

#interrupt-cells 这是中断控制器节点的属性,用来标识这个控制器需要几个单位做中断描述符

b. 中断源设备节点用的属性:

interrupt-parent:标识此设备节点属于哪一个中断控制器,如果没有设置这个属性,会自动依附父节点的,语法:

interrupt-parent = <引用某中断控制器节点>

interrupts 一个中断标识符列表,表示每一个中断输出信号,语法:

interrupts = <中断号 触发方式>1 low-to-high 上升沿触发
2 high-to-low 下降沿触发
4 high level  高电平触发
8 low level   低电平触发

5.5 gpio --------------- 重要

gpio也是最常见的IO口,常用的属性有:

a. 对于GPIO控制器:

gpio-controller,无值空属性,用来说明该节点描述的是一个gpio控制器

#gpio-cells,用来表示要用几个cell描述一个 GPIO引脚

b. 对于GPIO使用者节点:

gpio使用节点的属性

xxx-gpio = <&引用GPIO控制器 GPIO标号 工作模式>
工作模式:
1 低电平有效 GPIO_ACTIVE_HIGH
0 高电平有效 GPIO_ACTIVE_LOW

5.6 属性设置套路

一般来说,每一种设备的节点属性设置都会有一些套路,比如可以设置哪些属性?属性值怎么设置?那怎么知道这些套路呢,有两种思路:

  1. 抄类似的dts,比如我们自己项目的平台是4412,那么就可以抄exynos4412-tiny4412.dts、exynos4412-smdk4412.dts这类相近的dts
  2. 查询内核中的文档,比如Documentation/devicetree/bindings/i2c/i2c-imx.txt就描述了imx平台的i2c属性设置方法;Documentation/devicetree/bindings/fb就描述了lcd、lvds这类属性设置方法

六、常用接口

struct device_node 对应设备树中的一个节点
struct property 对应节点中一个属性

6.1 of_find_node_by_path

/**
include/of.h
of_find_node_by_path - 通过路径查找指定节点
@path - 带全路径的节点名,也可以是节点的别名
成功:得到节点的首地址;失败:NULL
*/
struct device_node * of_find_node_by_path(const char *path);

6.2 of_find_property

/*
include/of.h
of_find_property - 提取指定属性的值
@np - 设备节点指针
@name - 属性名称
@lenp - 属性值的字节数
成功:属性值的首地址;失败:NULL
*/
struct property *of_find_property(const struct device_node *np, const char *name, int *lenp);

6.3 of_get_named_gpio

/*** include/of_gpio.h* of_get_named_gpio - 从设备树中提取gpio口* @np - 设备节点指针* @propname - 属性名* @index - gpio口引脚标号 * 成功:得到GPIO口编号;失败:负数,绝对值是错误码*/
int of_get_named_gpio(struct device_node *np, const char *propname, int index);

6.4 irq_of_parse_and_map

/*功能:获得设备树中的中断号并进行映射参数:node:设备节点index:序号返回值:成功:中断号	失败:错误码
*/
unsigned int irq_of_parse_and_map(struct device_node *node, int index)

6.5 读属性值

of_property_read_string

/*
of_property_read_string - 提取字符串(属性值)
@np - 设备节点指针
@propname - 属性名称
@out_string - 输出参数,指向字符串(属性值)
成功:0;失败:负数,绝对值是错误码
*/
int of_property_read_string(struct device_node *np, const char *propname, const char **out_string);

读数值

int of_property_read_u8(const struct device_node *np,const char *propname,u8 *out_value)int of_property_read_u16(const struct device_node *np,const char *propname,u16 *out_value)int of_property_read_u32(const struct device_node *np,const char *propname,u32 *out_value)

判断属性是否存在

int of_property_read_bool(const struct device_node *np,const char *propname)

读数组

int of_property_read_u32_array(const struct device_node *np,const char *propname,u32 *out_value,size_t sz)

七、GPIO接口

7.1 向内核申请GPIO

int gpio_request(unsigned gpio,const char *label)

功能:其实就是让内核检查一下该GPIO引脚是否被其它设备占用,如果没有占用则返回0并用label做一下标记,表示被本设备占用,否则返回负数

void gpio_free(unsigned gpio)

功能:去除本设备对该GPIO的占用标记,表示本设备向内核归还对该GPIO引脚的使用权,此后其它设备可占用该GPIO引脚

7.2 设置GPIO方向

int gpio_direction_input(unsigned gpio)

int gpio_direction_output(unsigned gpio,int value)

7.3 读写GPIO数据

int gpio_get_value(unsigned gpio)

int gpio_set_value(unsigned gpio,int value)

八、led驱动设备树版

  1. 在设备树源文件的根节点下添加本设备的节点(该节点中包含本设备用到的资源信息)

    …/linux3.14/arch/arm/boot/dts/exynos4412-fs4412.dts

fs4412-leds {compatible = "fs4412,led2-5";led2-gpio = <&gpx2 7 0>;led3-gpio = <&gpx1 0 0>;led4-gpio = <&gpf3 4 0>;led5-gpio = <&gpf3 5 0>;
};
  1. 在linux内核源码的顶层目录下执行:make dtbs (生成对应的dtb文件)

  2. cp ???.dtb /tftpboot

  3. 编写驱动代码:

    a. 通过本设备在设备树中的路径找到对应节点(struct device_node类型的地址值)

    b. 调用 of_get_named_gpio 函数得到某个GPIO的编号

    c. struct leddev结构体中记录所有用到的GPIO编号

    d. 使用某个GPIO引脚前需先通过gpio_request函数向内核申请占用该引脚,不用该引脚时可通过gpio_free归还给内核

    e. 通过gpio_direction_input和gpio_direction_output函数来设置某个GPIO的作用

    f. 通过gpio_get_value函数可以获取某个GPIO引脚的当前电平

    g. 通过gpio_set_value函数可以改变某个GPIO引脚的电平

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

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

相关文章

HarmonyOS4.0从零开始的开发教程08构建列表页面

HarmonyOS&#xff08;六&#xff09;构建列表页面 List组件和Grid组件的使用 简介 在我们常用的手机应用中&#xff0c;经常会见到一些数据列表&#xff0c;如设置页面、通讯录、商品列表等。下图中两个页面都包含列表&#xff0c;“首页”页面中包含两个网格布局&#xff…

鸿蒙HarmonyOS4.0开发应用学习笔记

黑马程序员鸿蒙4.0视频学习笔记&#xff0c;供自己回顾使用。1.安装开发工具DevEco Studio 鸿蒙harmony开发文档指南 DevEco Studio下载地址 选择或者安装环境 选择和下载SDK 安装总览 编辑器界面 2.TypeScript语法 2.1变量声明 //string 、number、boolean、any、u…

清理oracle库30亿的表后,释放删除空间

1.创建中间表 请以HADES_COD.HDS_COD_BUSI_DETAIL为模板&#xff0c; 手动创建中间表&#xff1a;HADES_COD.HDS_COD_BUSI_DETAIL_1 以及它的constraint约束 示例&#xff1a; -- Create table create table HADES_COD.HDS_COD_BUSI_DETAIL_1 ( id …

HarmonyOS学习--初次下载安装和配置环境

一、Windows下载与安装软件 运行环境要求&#xff1a; 为保证DevEco Studio正常运行&#xff0c;建议电脑配置满足如下要求&#xff1a; 操作系统&#xff1a;Windows10 64位、Windows11 64位内存&#xff1a;8GB及以上硬盘&#xff1a;100GB及以上分辨率&#xff1a;1280*80…

鼎捷受邀出席“中国制造业产品创新数字化国际峰会”,共话工业软件创新发展

11月30日&#xff0c; 由e-works数字化企业网、四川省智能制造创新中心、重庆制信信息技术服务有限公司主办的第十九届中国制造业产品创新数字化国际峰会在四川成都盛大开幕。 作为制造业研发信息化领域规模、影响力兼具的专业论坛&#xff0c;本届峰会以“构建基于数字底座的…

2023年【R2移动式压力容器充装】最新解析及R2移动式压力容器充装模拟考试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年R2移动式压力容器充装最新解析为正在备考R2移动式压力容器充装操作证的学员准备的理论考试专题&#xff0c;每个月更新的R2移动式压力容器充装模拟考试题祝您顺利通过R2移动式压力容器充装考试。 1、【多选题】…

唯创知音WT2003Hx系列单片机语音芯片:家庭理疗产品的智能声音伴侣

随着科技的不断创新&#xff0c;家庭理疗产品正迎来一场智能化的变革。唯创知音的WT2003Hx系列单片机语音芯片以其强大的功能和高品质音频播放能力&#xff0c;为家庭理疗产品带来了更为智能、沉浸式的用户体验。 1. MP3高品质音频播放 WT2003Hx系列语音芯片支持高品质的MP3音…

简单自定义vuex的设计思路

vuex集中式存储管理应用所有组件的状态&#xff0c;并以响应的规则保证状态以可预测的方式 发生变化。 步骤&#xff1a; 1.Store类&#xff0c;保存选项&#xff0c;_mutations&#xff0c;_actions&#xff0c;getters 2.响应式状态&#xff1a;new Vue方式设置响应式。 …

Vue 的异步更新机制是如何实现的

vue 的异步更新机制是如何实现的 实现原理 – 使用事件循环&#xff08;Event Loop&#xff09;和任务队列&#xff08;Task Queue&#xff09;vue 的异步更新机制步骤扩展&#xff1a;this.$nextTick .$nextTick](#扩展thisnexttick) vue 的异步更新机制是如何实现的 实现原…

使用Java8的Stream流的Collectors.toMap来生成Map结构

问题描述 在日常开发中总会有这样的代码&#xff0c;将一个List转为Map集合&#xff0c;使用其中的某个属性为key&#xff0c;某个属性为value。 常规实现 public class CollectorsToMapDemo {DataNoArgsConstructorAllArgsConstructorpublic static class Student {private…

OpenCV-python numpy和基本作图

文章目录 一、实验目的二、实验内容三、实验过程Numpy1.NumPy 操作2.NumPy Ndarray 对象3.NumPy 基本类型4.NumPy 数组属性ndarray.ndimndarray.shapendarray.itemsizendarray.flags 5.NumPy 创建数组numpy.emptynumpy.zerosnumpy.ones 6.NumPy 从已有的数组创建数组numpy.asar…

SpringDataRedis 操作 Redis,并指定数据序列化器

文章目录 1. SpringDataRedis 概述2. 快速入门2.1 导入pom坐标2.2 配置文件2.3 测试代码2.4 数据序列化器2.5 StringRedisTemplate2.6 总结 1. SpringDataRedis 概述 SpringData 是Spring 中数据操作的模块&#xff0c;包含对各种数据库的集成&#xff0c;其中对Redis的集成模…

使用vue UI安装路由插件

1.使用vue创建项目 vue create vue-appvue ui 2.使用vue ui界面创建管理项目 终端页面输入&#xff1a;vue ui 创建项目 安装完成。可以直接在ui界面运行&#xff0c;也可以在编辑器中使用命令运行 安装路由&#xff0c;安装状态 选择插件 - 添加vue-router、添加vuex 安装…

C# WebSocket简单使用

文章目录 前言Fleck调试工具初始化简单使用 前言 最近接到了一个需求&#xff0c;需要网页实现上位机的功能。那就对数据传输的实时性要求很高。那就只能用WebSocket了。这里简单说一下我的WebSocket如何搭建 Fleck C# WebSocket(Fleck) 客户端:html Winfrom Fleck Github官网…

Unity3D中实现箭头指向目标点的效果(shader)

系列文章目录 Unity工具 文章目录 系列文章目录前言一、效果如下二、制作步骤2-1、制作shader2-2、shader代码2-3、制作材质球2-4、新建Quad2-5、制作预制体2-6 、实现代码2-7、设置Quad到脚本2-8、路径设置如下 三、说明四、运行程序总结 前言 大家好&#xff0c;我是心疼你…

要求CHATGPT高质量回答的艺术:提示工程技术的完整指南—第 15 章:问题解答提示

要求CHATGPT高质量回答的艺术&#xff1a;提示工程技术的完整指南—第 15 章&#xff1a;问题解答提示 问题解答提示是一种允许模型生成回答特定问题或任务的文本的技术。要做到这一点&#xff0c;需要向模型提供一个问题或任务作为输入&#xff0c;以及与该问题或任务相关的任…

机器学习笔记 - 使用深度学习提高传统机器学习性能

一、简述 深度学习在许多不同领域实现最先进的性能,包括图像分类、自然语言处理和语音识别。这里主要探讨了如何使用深度学习来增强经典机器学习模型的有效性。 决策树、随机森林和线性回归只是多年来在商业中广泛使用的经典机器学习模型的几个例子。由于其简单性、清晰性和可…

鸿蒙开发—UI框架概述

基本概念 UI框架 HarmonyOS提供了一套UI开发框架&#xff0c;即方舟开发框架&#xff08;ArkUI框架&#xff09;。方舟开发框架可为开发者提供应用UI开发所必需的能力&#xff0c;比如多种组件、布局计算、动画能力、UI交互、绘制等。 方舟开发框架针对不同目的和技术背景的…

数据结构与算法编程题47

无向图的邻接表 #include <iostream> using namespace std;#define MVnum 100 typedef string VertexType;typedef struct ArcNode {int adjvex;struct ArcNode* nextarc;int weight; }ArcNode;typedef struct VNode {VertexType data;struct ArcNode* firstarc; }VNode,…

性能测试工具:Jmeter介绍

JMeter是一个开源的Java应用程序&#xff0c;由Apache软件基金会开发和维护&#xff0c;可用于性能测试、压力测试、接口测试等。 1. 原理 JMeter的基本原理是模拟多用户并发访问应用程序&#xff0c;通过发送HTTP请求或其他协议请求&#xff0c;并测量响应时间、吞吐量、并发…