【linux-imx6ull-设备树点灯】

目录

  • 1. 设备树简介
    • 1.1 编译-引用
    • 1.2 设备树文件结构
    • 1.3 设备树节点介绍
      • 1.3.1 特殊节点chosen
    • 1.4 节点内容追加
  • 2. 设备树常用OF操作函数
    • 2.1 节点寻找类
    • 2.2 属性提取类
    • 2.3 其它常用类
  • 4. 设备树下LED实验
    • 4.1 实验简介
    • 4.2 添加LED设备节点
    • 4.3 获取设备节点并提取属性
      • 4.3.1 获取设备节点
      • 4.3.2 提取设备节点属性
    • 4.4 节点属性使用-总结

1. 设备树简介

  设备树可以理解为一种硬件数据结构,只不过这种数据结构中描述了板子和外设的信息,例如CPU 数量、内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备等等;
  设备树将描述板级硬件信息的内容从 Linux 内核中分离开来,用一个专属的文件格式来描述,文件扩展名为.dts,设备树的主要功能是按照特定的结构来描述板子上的设备信息,它的出现是为了解决在没有设备树时,Linux 通过大量的arch/arm/mach-xxx 和 arch/arm/plat-xxx 文件夹来描述对应平台的板机信息,导致 Linux 内核虚胖的问题。

1.1 编译-引用

  设备树的编译流程,对于C语言我们使用GCC就能把mx.c -> mx.o,同理对于设备树而言我们使用的是DTC的编译工具把mx.dts -> mx.dtb,作为理解就行;
  语法简介,对于dtc而言有自己的一套语法,但是比较简单,对于.dts文件同样支持头文件的扩展,对于C语言而言我们添加头文件是<mx.h>后缀是h文件,对于设备树我们添加的是<mx.dtsi>后缀是dtsi文件;但是我们也可以来引用.h、.dtsi 和.dts 文件,只是,我们在编写设备树头文件的时候最好选择.dtsi 后缀。DTS 语法非常的人性化,是一种 ASCII文本文件,不管是阅读还是修改都很方便;

1.2 设备树文件结构

  对于一个设备树文件而言,其结构也是层级结构,其中根目录为/,如下:不过我们这里称为节点,也就是有父节点,父节点下面有子节点,子节点下面有子子节点等等;


1.3 设备树节点介绍

  我们已经知道对于设备树而言是由一个个节点组成,你把这个节点放在几级目录,那么这个节点就是几级节点,因此下面对一个节点进行一个简要的说明:要注意的就是#address-cells 和#size-cells 表明了子节点应该如何编写 reg 属性值,一般 reg 属性 都是和地址有关的内容,整体结构就是这样,其它的节点中的属性就不再一一介绍;


1.3.1 特殊节点chosen

   uboot 中的 fdt_chosen 函数在设备树的 chosen 节点中加入了 bootargs属性,并且还设置了 bootargs 属性值,在设备树中就是chose的属性:图中框起来的部分就是函数do_bootm_linux函数的执行流程,也就是说do_bootm_linux函数会通过一系列复杂的调用,最终通过fdt_chosen 函数在chosen 节点中加入了 bootargs 属性,而我们通过 bootz 命令启动 Linux 内核的时候会运行do_bootm_linux 函数;


   Linux 内核在启动的时候会解析 DTB 文件,然后在/proc/device-tree 目录下生成相应的设备树节点文件,接下来我们简单分析一下 Linux 内核是如何解析 DTB 文件的,流程如图 所示:


1.4 节点内容追加

  产品开发过程中可能面临着频繁的需求更改,比如第一版硬件上有一个 IIC 接口的六轴芯片 MPU6050,第二版硬件又要把这个 MPU6050 更换为 MPU9250 等。一旦硬件修改了,我们就要同步的修改设备树文件,毕竟设备树是描述板子硬件信息的文件。因此这里例如向iic中追加两个设备节点:对于imx6ull.dtsi文件中iic的节点中的内容很少,如下:


  现在进行追加,追加符是&+标签/节点名字;如下在我们的设备书文件imx6ull-14x14-evk.dts中对iic进行追加,我们这个文件已经引入了imx6ull.dtsi头文件:


2. 设备树常用OF操作函数

  对于设备树而言已经介绍了其结构,节点,属性,但是我们如何把节点中的属性给提取出来呢?例如我们在reg属性中有:reg=<0x454145512 0x04 0x4597911651 0x04>,我们如何把reg中的属性给提取出来呢?我们可以使用OF操作函数,具体而言有下列比较重要的部分:具体的用法用多了就熟练了;

2.1 节点寻找类

 1. 寻找节点类的常用如下:(待补充)

  • static inline struct device_node *of_find_node_by_path(const char *path):
  • struct device_node *of_get_parent(const struct device_node *node):
  • struct device_node *of_get_next_child(const struct device_node *node,struct device_node *prev):

2.2 属性提取类

 2. 提取属性的的常用如下:(待补充)

  • static inline int of_property_read_string(struct device_node *np,const char *propname,const char **out_string):
  • static inline int of_property_read_u32_array(const struct device_node *np,const char *propname,u32 *out_values, size_t sz):
  • int of_property_read_u32(const struct device_node *np,const char *propname,u32 *out_value)
  • int of_n_addr_cells(struct device_node *np)
  • int of_n_size_cells(struct device_node *np)

2.3 其它常用类

 3. 其它的常用如下:(待补充)

  • int of_device_is_compatible(const struct device_node *device,const char *compat)
  • onst __be32 *of_get_address(struct device_node *dev,int index,u64 *size,unsigned int *flags):主要是reg或assigned-addresses属性;
  • u64 of_translate_address(struct device_node *dev,const __be32 *in_addr):
  • int of_address_to_resource(struct device_node *dev,int index,struct resource *r):
  • void __iomem *of_iomap(struct device_node *np,int index):限定reg属性

4. 设备树下LED实验

4.1 实验简介

  我们回顾一下我们几次点灯实验:

  1. 第一次点亮LED实验。我们通过裸机进行操控寄存器进行LED灯的点亮:在裸机下进行LED点灯本质上和单片机开发差不多,是在寄存器层面进行操控,相当于把IMX6ULL当成了一个性能更强的单片机;
  2. 第二次点亮LED实验。linux内核下不用设备树对LED进行点亮,而且我们使用的手动对设备号进行分配,并在Linux系统上手动对驱动节点进行挂载;到这里我们以及慢慢的离开了底层的裸机开发,我们用上了操作系统,也就是给IMX6ULL装上了系统,因此我们在这里引入了内核态和用户态的概念,我们在Linux系统上对LED操控本质归根到底还是要操控寄存器,但是我们在系统上不能直接操控寄存器,而是通过寄存器映射的方式把实际的物理地址映射成虚拟的地址,然后我们对虚拟的寄存器进行操控,以实现在系统层面对LED进行驱动点亮;
  3. 第三次点亮LED实验。我们在第二次点亮实验中已经在系统层面对LED进行了驱动实验,但是缺点还是有的,就是需要我们手动进行设备号的分配以及需要我我们手动对驱动节点的创建,也就是要用到mknod命令,这显然是对用户是不友好的,因此我们在第三次实验中重点是完善了LED的驱动框架,也就是对于LED的驱动,完成了自动对设备号的分配以及自动对设备节点的创建,其流程是常用的驱动框架,不过缺点也有,这种开发驱动的模式是linux系统没有引入设备树之前常用的开发模式,但是对于引入设备树后,这种驱动开发模式就逐渐被抛弃了;
  4. 第四次点亮LED实验 。第四次LED点亮实验是在第三次的基础上引入了设备树,也就是本次的设备树下LED驱动点亮实验:因此这次驱动实验目的就是如何在引入设备树下的情况对LED驱动进行开发:从这几次的点灯实验中我们也可以看到程序也是越来越复杂,但是这种复杂性是必要的,对于大型复杂的程序,这反而是一种更加高效的方式;

4.2 添加LED设备节点

  由于本次点灯实验是在第三次的基础上引入了设备树,因此这节内容主要是记录设备树的引入相关的细节,对于框架搭建和第三次驱动的实验参考我的下面两个连接:
  1.简单驱动框架搭建:连接
  2.完善的驱动框架(未引入设备树):连接
  前面对设备树进行了结构,节点,属性进行简要分析,同时也介绍了一些常用的OF函数,我们要想在驱动中引入设备树,第一件事就是想dts设备树文件中添加我们的LED设备,添加如下:


  添加完毕后.进行make dtbs编译,编译完毕后挂载到板子上,然后在/proc/device-tree/目录中查看是否有“alphaled”这个节点;

4.3 获取设备节点并提取属性

4.3.1 获取设备节点

  当我们成功的在设备树中添加了设备节点,我们就可以在驱动文件中对我们添加的节点进行获取,获取的方式就是利用我们上面所说的OF常用的函数,如下:


4.3.2 提取设备节点属性

  当获取设备节点后就是对节点中的属性进行提取;


4.4 节点属性使用-总结

  我们可以这样认为,我们本质上就是操控寄存器进行LED的控制,只不过我们要操控寄存器就要获取寄存器的地址,当我们不引入设备树时我们直接可以进行地址映射然后进行操控虚拟寄存器,但是当我们引入设备树后,我们就无法直接获取寄存器的地址,因为寄存器的地址被我们写在了设备树中,因此我们想进行虚拟地址的映射我们就必须先获取设备树中LED节点的寄存器节点信息,如果我直接宏定义的话,设备树的引入就没有意义了,当然对于点灯的实验而言是多此一举,但是对以后的学习是必要的;

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

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

相关文章

内网渗透-隧道搭建ssp隧道代理工具

内网渗透-隧道搭建&ssp隧道代理工具 目录 内网渗透-隧道搭建&ssp隧道代理工具spp隧道代理工具spp工作原理图cs上线主机spp代理通信服务端配置客户端配置CS配置设置CS生成木马的监听器配置CS监听上线的监听器生成木马 spp隧道搭建服务端配置客户端配置CS配置 内网穿透&a…

【机器学习300问】100、怎么理解卷积神经网络CNN中的池化操作?

一、什么是池化&#xff1f; 卷积神经网络&#xff08;CNN&#xff09;中的池化&#xff08;Pooling&#xff09;操作是一种下采样技术&#xff0c;其目的是减少数据的空间维度&#xff08;宽度和高度&#xff09;&#xff0c;同时保持最重要的特征并降低计算复杂度。池化操作不…

【吊打面试官系列】Java高并发篇 - 什么是乐观锁和悲观锁?

大家好&#xff0c;我是锋哥。今天分享关于 【什么是乐观锁和悲观锁?】面试题&#xff0c;希望对大家有帮助&#xff1b; 什么是乐观锁和悲观锁? 1、乐观锁&#xff1a; 就像它的名字一样&#xff0c;对于并发间操作产生的线程安全问题持乐观状态&#xff0c; 乐观锁认为竞争…

手拉手springboot整合kafka发送消息

环境介绍技术栈springbootmybatis-plusmysqlrocketmq软件版本mysql8IDEAIntelliJ IDEA 2022.2.1JDK17Spring Boot3.1.7kafka2.13-3.7.0 创建topic时&#xff0c;若不指定topic的分区(Partition主题分区数)数量使&#xff0c;则默认为1个分区(partition) springboot加入依赖kafk…

【深度学习基础】使用Pytorch搭建DNN深度神经网络与手写数字识别

目录 写在开头 一、DNN的搭建 问题描述与数据集 神经网络搭建 模型训练 模型评估 模型复用 二、手写数字识别 任务描述 数据集 神经网络搭建 模型训练 模型评估 写在最后 写在开头 本文将介绍如何使用PyTorch框架搭建深度神经网络模型。实现模型的搭建、模…

Ps系统教程03

选区工具的组合使用 先用魔棒将大致区域点击圈主 会发现一些零散的小区域 使用套索工具进行区域的加减&#xff08;按住shift/alt键进行相关区域加减&#xff09; 可以放大查看 基本处理完细节之后 如果把不用的填充背景直接按delete删除&#xff0c;那么原版图案就会…

【贪心算法题目练习】

1. 分发饼干 这道题目和我们之前讲到的田忌赛马的问题很相似&#xff0c;只不过这这里不需要劣等马去抵消掉优等马&#xff0c;直接上贪心策略&#xff1a; 先将两个数组排序。针对胃口较小的孩子&#xff0c;从小到大挑选饼干: i. 如果当前饼干能满足&#xff0c;直接喂(最小…

大语言模型实战——最小化模型评测

1. 引言 现在国内外的主流模型&#xff0c;在新模型发布时都会给出很多评测数据&#xff0c;用以说明当前模型在不同数据集上的测评表现&#xff08;如下面llama3发布的评测数据&#xff09;。 这些评测数据是如何给出来的呢&#xff1f;这篇文章会用一个最小化的流程来还原下…

【限免】短时傅里叶变换时频分析【附MATLAB代码】

来源&#xff1a;微信公众号&#xff1a;EW Frontier 简介 一种能够同时对信号时域和频域分析的方法——短时傅里叶变换&#xff08;STFT&#xff09;&#xff0c;可以在时频二维角度准确地描述信号 的时间、频域的局部特性&#xff0c;与其他算法不同&#xff0c;通过该算法可…

Open3D(C++) OTSU点云二值化

目录 一、算法原理二、代码实现三、结果展示1、原始点云2、二值化本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 最大类间方差法(Between-class scatter method)是一种用于分割的方法,它通过计算图…

【C++】命名空间

命名空间 为了解决C语言命名冲突问题而诞生 namespace 命名空间名 {...... }命名空间内函数作用域只在此命名空间内 错误 using std::cout; //为了保证正常输出先忽略此行 using std::endl; //为了保证正常输出先忽略此行 #include <iostream>namespace a {int n10…

git 代码提交规范,feat,fix,chore都是什么意思?

写到前面 经常看到别人提交的代码记录里面包含一些feat、fix、chore等等&#xff0c;而我在提交时也不会区分什么&#xff0c;直接写下提交信息&#xff0c;今天就来看一下怎么个事&#xff0c;就拿 element-plus 举例来看一下 其实这么写是一种代码提交规范&#xff0c;当然…

SpringBoot六种API请求参数读取方式

SpringBoot六种API请求参数读取方式 同步请求和异步请求 同步: 指单线程依次做几件事异步: 指多线程同时做几件事 同步请求: 指客户端浏览器只有一个主线程, 此线程负责页面的渲染和发出请求等操作, 如果此主线程发出请求的话则停止渲染而且会清空页面显示的内容 直到服务器响…

前端html-docx实现html转word,并导出文件,文字+图片

前端html-docx实现html转word&#xff0c;并导出文件 前端web页面 有文字&#xff0c;有图片&#xff0c;保存web的css效果 使用工具&#xff1a;html-docx 官方网址&#xff1a;http://docs.asprain.cn/html-docx/readme.html 步骤&#xff1a; 1 npm install html-docx-js…

输入3个字符串,要求将字母按由小到大顺序输出

对于将3个整数按由小到大顺序输出&#xff0c;是很容易处理的。可以按照同样的算法来处理将3个字符串按大小顺序输出。可以直接写出程序。 编写程序&#xff1a; 运行结果&#xff1a; 这个程序是很好理解的。在程序中对字符串变量用关系运算符进行比较&#xff0c;如同对数值…

GUI 01:GUI 编程概述,AWT 相关知识,Frame 窗口,Panel 面板,及监听事件的应用

一、前言 记录时间 [2024-05-30] 疑问导航 GUI 是什么&#xff1f;GUI 如何使用&#xff1f;GUI 有哪些应用&#xff1f; 学习目的 写一些自己心中的小工具&#xff1b;Swing 界面的维护&#xff1b;了解 MVC 架构&#xff0c;以及监听事件。 本文对图形用户界面&#xff08…

基于BP神经网络的64QAM解调算法matlab性能仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心程序 ....................................................... % 第一部分&#xff1a;加载并可视…

CSS绘制圆弧

css绘制如图的圆弧&#xff1a; 这种矩形弧形的效果中&#xff0c;弧形的效果一般是由一条曲线拉伸出来的&#xff0c;这条曲线往往是属于一个椭圆的&#xff0c;所以可以绘制一个椭圆&#xff0c;截取部分可视区域实现效果。 <style> .wrapper{width: 400px;height: 60…

Minio篇:初识MinIO

1. MinIO快速入门 1.1.MinIO核心概念 下面介绍MinIO中的几个核心概念&#xff0c;这些概念在所有的对象存储服务中也都是通用的。 对象&#xff08;Object&#xff09; 对象是实际的数据单元&#xff0c;例如我们上传的一个图片。 存储桶&#xff08;Bucket&#xff09; 存储…

C语言分支和循环(2)

我的相关博客&#xff1a; C语言的分支与循环&#xff08;1&#xff09; 1.switch语句 除了 if 语句外&#xff0c;C语⾔还提供了 switch 语句来实现分⽀结构。 switch 语句是⼀种特殊形式的 的 if...else 结构&#xff0c;⽤于判断条件有多个结果的情况。它把多重 else if…