当前位置: 首页 > news >正文

Zephyr 入门-设备树与设备驱动模型

学习链接:https://www.bilibili.com/video/BV1L94y1F7qS/?spm_id_from=333.337.search-card.all.click&vd_source=031c58084cf824f3b16987292f60ed3c
讲解清晰,逻辑清楚。

1. 设备树概述(语法,如何配置硬件,c代码如何访问) driver的实现

讲解zephyr设备树的意义:单片机开发过程中,一般使用宏定义来表示硬件引脚,但是为了达成高内聚低耦合的软件架构,又设计了把初始化函数和中断放在一个board.c文件,其他按照功能分开存放。虽然已经很好了,但是切换硬件平台后还是不能很好的移植。(比如我们更换平台后,需要更换调用的GPIO library 库) 而且不同的人又有不同的代码风格,但是zephyr横空出世。规范了这一切,都得按照我的规矩来。这样导致平台移植非常方便,这简直是提高了人类的效率啊。
思考: zephyr把硬件都规定好了,他能不能自己生成board.c文件呢?zephyr的设备树简单了解:芯片厂商会自己适配zephyr,客户可以根据需要修改,同时zephyr会调驱动把有设备树的外设初始化好。同时客户还能够调用和操作寄存器,控制管脚,好灵活。好牛逼啊感觉。

2. device tree的结构和语法

首先按照总线的主从关系,其次按照硬件的包含关系。(总线下面的节点都有地址,而如LED等外设虽然用到了GPIO但是没有地址,所以直接成为根节点下的子节点)device tree 的适用范围:device tree 描述的是板卡级别的硬件信息,当一个办卡上有两个MCU他们不能公用device tree. 当一个MCU有两个独立固件的core,他们不能共用device tree,等。设备树语法跟linux里面一样只是需要注意写法:device tree 的节点: name@address
节点的name可以是字母数字下划线,加减号标点等等。但是c代码得到设备树名称的时候会把不符合字母数字下划线的那部分特殊符号变成下划线。
如果有reg属性,则address必须和reg属性的第一个寄存器地址值相等。如果没有reg属性,则@address必须省略。dts可以引用其他的dts或dtsi,这样板卡级dts就可以引用芯片厂商写好的芯片级dtsi文件。缩短dts开发时间。
dts还可以引用c头文件来使用一些枚举值或宏定义。devicetree文件的位置:
1. 新建工程时可以选择板卡,板子的dts文件位于:zephyr/board/目录
2. 板卡引用的dtsi文件位于 zephyr/dts/arm/nordic 目录
3. 用户不需要自己写dts,直接在自己的工程目录中的board.overlay增删改节点属性。覆盖开发板的配置即可。
使用label指定节点并覆写其属性,/delete-property/ led1;可以删除属性,/delete-node/ leds;可以删除节点。
4. 最后,构建项目时,zephyr build system 会使用一系列脚本把board,soc,用户的overlay合并起来。如果构建目录的名称是build,最终合并后的完整文件位于:
${projector_folder}build/zephyr/zephyr.dts
5. 了解即可,zephyr最终会把zephyr.dts处理成c语言头文件,位于S{project_folder}/build/zephyr/include/generated/devicetree_generated.h。代码最后得到设备树的信息其实是通过这个文件。

3. device tree如何配置硬件信息

reg = <addr1 add1_leng addr2 add2_leng> 可见reg由多对总线上的地址和长度信息组合而成。
当一个节点定义的ranges属性,那他的子节点就可以使用相对地址而非绝对地址。 ranges = <子空间首地址 父空间首地址 长度信息>
status ,只需要注意"okay" 和 disabled, 决定是否初始化该外设。
compatible 设备会通过这个找到合适的驱动程序设备树中的"域", 除了地址树以外,比如GPIO树其下面挂载了LED BUTTON等,中断树,ADC树下面挂载了很多ADC设备。 这些树的出现是为了更好的描述网状的硬件关系。这些虚拟概念上的树被称为"域"。每个域都有自己的根节点被称为controller, 控制器控制了整个域的相关硬件。控制器节点通过给自己一个*-controller的属性(也可能没有),如:gpio-controller, 然后这个GPIO域的子节点就可以通过前面介绍的phandle-array属性来使用这个gpio控制器,如:gpios = <&gpio0 0x18 0x11> 第一个数值指向控制器节点,后续的值是节点在这个域中的配置,被称为specifier。 使用哪一个gpio,后一个指定gpio的配置信息。设备树有一些奇怪的规则,比如有的域控制器有controller有的没有,而且zephyr能自动检测你写的dts是不是符合这些规则的,怎么实现的呢?通过yaml这种描述语言进行检测的,比如这个 ./zephyr/dts/bindings/dma/nxp,mcux-edma.yaml ,这个就是device bingding 文件。 这个文件名字就是compatible属性,zephyr的编译器会用bing文件去dts检查符合这个compatible属性的设备树节点。这个binding文件可以约束子节点怎么写,还可以给specifier中的节点数值做含义解释。zephyr build system 会从一下位置寻找binding文件:
./zephyr/dts/bindings/
${board_dir}/dts/bindings/
${project_dir}/dts/bindings/
也可以在Cmakelist.txt中,用list{APPEND DTS_ROOT /path/to/your/dts}增加binging文件的目录
也可以在编译时增加选项 west build -b <board_name> --DTS_ROOT=<path/to/your/dts>还有一些特殊的节点:
chosen: 为device kernel 选择特定设备
aliase: 为节点起一个别名,别名是属性名
pinctrl: 直属于根节点,数字IO复用
/zephyr,usr: 方便用户开发的节点,直接写spicifier和配置项,不用写binding了

4. 如何在c代码中获取device tree??

通过API获取,需要包含头文件:#include <zephyr/device_tree.h>
为了获得节点属性,需要先获得节点id作为句柄(节点id就是node identifier),节点id本质上是devicetree_generated.h中的宏定义。方式如下:
DT_ROOT 						得到根节点id
DT_PATH(soc,serial_40001000)	得到/soc/serial@40001000
DT_NODELABLE(serial1)			根据dts中定义的lable找到节点
DT_CHOSEN(zephyr_console)		根据chosen节点配置:zephyr,console=&uart0
还有很多子节点找父节点,父节点找子节点的方式。 还有一种方式,是通过实例ID的方式获取节点ID,如DT_INST(0, nordic_nrf_timer)对应的就是nordic,nrf_timer的第0个实例节点。如果节点中有多个节点有同一个comaptible,就是一个compatible对应多个实例,好处是什么呢就是可以放到for循环中遍历了呀。(但是注意不是c语言中的for,因为这些API都是预编译后的结果,括号里的当然也不是真正的输入参数,哈哈)DT_PROP 宏可以得到普通属性
DT_REG_ADDR 和 DT_REG_SIZE 宏可以读取reg的地址和长度
如果一个节点的属性是其他节点可以通过DT_HANDLE_BY_IDX得到内个节点上面说了zephyr提供的获取节点的ID虽然都不能传入遍历以便于通过for循环调用,但是zephyr提供了可以遍历这些节点的API,如DT_FOREACH_NODE(fn)为设备树中的每一个节点调用宏函数fn。 还有很多API请看 https://docs.zephyrproject.org/latest/build/dts/api/api.html#for-each-macros (这些API看似是循环,其实是宏)
这里这个fn宏函数是用代码模板。再看看还有很多API方便你直接读取specifier等。具体参考
https://docs.zephyrproject.org/latest/build/dts/api/api.html#hardware-specific-apis
https://docs.zephyrproject.org/latest/hardware/index.heml

5. Zephyr Driver 的实现方式

什么是驱动程序?因为zephyr中驱动程序是“面向对象”的,他有个device结构体,结构体如下:struct device {const char *name;const void *config;const void *api;struct device_state *state;void *data;......};
可以看到这个结构体很宽泛,驱动程序需要在application启动之前把这个结构体填充好,然后application才能调用这些api。
根据zeyphr的启动流程,可以把驱动程序放在一下五个级别中的任何一个级别:
start up-> EARLY --> PRE_KERNEL_1 --> PRE_KERNEL_2 --> RTOS KERNEL 启动 --> POST_KERNEL --> APPLICATION -->MAIN| 		放这的不能有log 					| 					| 			放这里可以打log	|Application需要得到这个device结构体才能操作外设对吧,那app如何得到device呢?两种方式:通过name, 通过设备树node id。
第一种方式中,在驱动程序中通过DEVICE_DEFINE宏来定义device结构体,其中第二个参数为该结构体的lable吧。在app中通过device_get_binding这个API即可得到这个device.
第二种方式中,在驱动程序中通过DEVICE_DT_DEFINE来定义结构体,并与节点绑定。在app中通过DEVICE_DT_GET(node id)宏来获得device.(node id可以用DT_PATH(节点名)得到)prj.config中的CONFIG_*选项与dts中的status状态有什么关系?
前者决定是否编译进入固件(嵌入到硬件设备的软件代码),后者决定驱动程序使用宏遍历device结构体时能够为这个okay的节点创建device对象。只有两者都启用app才能操作这个节点。

6. Zephyr标准驱动

zephyr是个跨平台操作系统,少不了对标准硬件的跨平台支持。
详见:https://docs.zephyrproject.org/latest/hardware/peripherals/index.html
以DMA为例,在zephyr/include/zephyr/drivers/dma.h目录中规定好了dma驱动应该有哪些API。在zephyr/drivers/dma/目录下有各个厂家写好的对字节芯片的driver驱动。通过zephyr/drivers/dma/Kconfig.nxp_edma可以看到各个CONFIG选项的作用,在./zephyr/build/zephyr/.config设置好对应的CONFIG_*=y,则zephyr就会把板子对应厂商的dma驱动编译进来。zephyr标准驱动支持硬件的全部功能吗???
zephyr只支持最基础最标准的硬件驱动,不支持各个厂商的硬件特性。如果想要硬件特性功能,需要使用厂商自己的driver library, 或者直接写寄存器。

相关文章:

Zephyr 入门-设备树与设备驱动模型

学习链接&#xff1a;https://www.bilibili.com/video/BV1L94y1F7qS/?spm_id_from333.337.search-card.all.click&vd_source031c58084cf824f3b16987292f60ed3c 讲解清晰&#xff0c;逻辑清楚。 1. 设备树概述&#xff08;语法&#xff0c;如何配置硬件&#xff0c;c代码如…...

点云标注软件SUSTechPOINTS的安装和使用,自测win10和ubuntu20.04下都可以用

点云标注软件SUSTechPOINTS的安装和使用 github项目源码&#xff1a;https://github.com/naurril/SUSTechPOINTS gitee源码以及使用教程&#xff1a;https://gitee.com/cuge1995/SUSTechPOINTS 首先拉取源码 git clone https://github.com/naurril/SUSTechPOINTS最好是在cond…...

etcd资源超额

集群内apiserver一直重启&#xff0c;重启kubelet服务后查看日志发现一下报错&#xff1a; Error from server: etcdserver: mvcc: database space exceeded 报错原因&#xff1a; etcd服务未设置自动压缩参数&#xff08;auto-compact&#xff09; etcd 默认不会自动 compa…...

AndroidStudio-常见界面控件

一、Button package com.example.review01import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.widget.Button import android.widget.TextViewclass Review01Activity : AppCompatActivity() {override fun onCreate(savedInstanceStat…...

网络协议(TCP/IP模型)

目录 网络初识 网络协议 协议分层 协议拆分 分层 协议分层的优势 1.封装效果 2.解耦合 TCP/IP五层模型 协议之间配合工作&#xff08;详解&#xff09; 网络初识 网络核心概念&#xff1a; 局域网&#xff1a;若干电脑连接在一起&#xff0c;通过路由器进行组网。 …...

python 清华pip镜像源报HTTP error 403

报错信息 ERROR: HTTP error 403 while getting https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/52/79/a64937a2185b91a96cc5406e3ea58120980c725543d047e112fb3084a972/fake_useragent-2.0.0-py3-none-any.whl (from https://mirrors.tuna.tsinghua.edu.cn/pypi/we…...

swift 屏幕录制

步骤 1&#xff1a;导入 ReplayKit import ReplayKit步骤 2&#xff1a;开始录屏 let screenRecorder RPScreenRecorder.shared() // 麦克风或系统音频 screenRecorder.isMicrophoneEnabled truefunc startRecording() {guard screenRecorder.isAvailable else {print(&quo…...

通过精密时间协议(PTP)对计算机网络中的多个设备进行时间同步

PTP 模块 - 使用教程 目录 PTP 模块 - 使用教程简介第 1 步&#xff1a;为主时钟创建一个 PTP 时钟实例第 2 步&#xff1a;添加 PTP 端口第 3 步&#xff1a;查询 PTP 时钟或 PTP 端口的状态第 4 步&#xff1a;清除 FAULTY 状态第 5 步&#xff1a;为 PTP 事件安装处理程序第…...

Docker 安装系列

Centos8 安装Docker Docker安装mysql8.0 Docker安装稳定版本nginx-1.26.2 Docker 安装最新版本 Jenkins Docker Redis Docker 安装 eclipse-mosquitto Docker mongo:5.0 Docker 安装 Redis的完全体版本RedisMod docker pull elasticsearch:8.0.0 docker 安装nacos v2.…...

使用springboot-3.4.1搭建一个netty服务并且WebSocket消息通知(适用于设备直连操作,以及回复操作)

引入最新版本 <!--websocket--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>启动类加入 //netty 协议服务端口启动 NettyTcpHandler.start()…...

4. 设计模式分类

4.1 创建型模式 这类模式提供创建对象的机制,能够提升已有代码的灵活性和可复用性。 序 号 类 型 业务场景 实现要点 1 工 厂 方 法 多种类型商品不同接口,统一发奖服 务搭建场景 定义一个创建对象的接口,让其子类自 己决定实例化哪一个工厂类,工厂模式 使其创建过程延迟…...

Hive分区值的插入

对于Hive分区表&#xff0c;在我们插入数据的时候需要指定对应的分区值&#xff0c;而这里就会涉及很多种情况。比如静态分区插入、动态分区插入、提供的分区值和分区字段类型不一致&#xff0c;或者提供的分区值是NULL的情况&#xff0c;下面我们依次来展现下不同情况下的表现…...

【多个图片合并成PDF】

因工作安排,小编最近参加了几场学术会议,被多名业界大佬的汇报所震撼。当然也不是白来的,好东西要留存下来回来分享给科室。因此,小编变成了幻灯片专职摄影师,参会的同时对着大牛的PPT就是一顿咔咔咔。回来后,面对手机里数百张照片却犯了难,就这样一张张发到群里么?还是…...

Flutter动画(三)内建显式动画Widget

常见的内建显式动画Widget&#xff1a; ListenableBuilder&#xff1a; AnimatedBuilder AnimatedWidget AlignTransition DecoratedBoxTransition DefaultTextStyleTransition PositionedTransition RelativePositionedTransition RotationTransition ScaleTransiti…...

本地运行打包好的dist

首先输入打包命令 每个人设置不一样 一般人 是npm run build如果不知道可以去package.json里去看。 打包好文件如下 命令行输入 :npm i -g http-server 进入到dist目录下输入 命令cmd 输入 http-server 成功...

什么是Layer Normalization?

一、概念 前面的文章中&#xff0c;我们介绍了Batch Normalization。BN的目的是使得每个batch的输入数据在每个维度上的均值为0、方差为1&#xff08;batch内&#xff0c;数据维度A的所有数值均值为0、方差为1&#xff0c;维度B、C等以此类推&#xff09;&#xff0c;这是由于神…...

17. Threejs案例-Three.js创建多个立方体

17. Threejs案例-Three.js创建多个立方体 实现效果 知识点 WebGLRenderer (WebGL渲染器) WebGLRenderer 是 Three.js 中用于渲染 WebGL 场景的核心类。它负责将场景中的对象渲染到画布上。 构造器 new THREE.WebGLRenderer(parameters) 参数类型描述parametersObject可选…...

RK3568 Android14 打开蓝牙时默认同意

1、最近给一个项目做了一款基础功能的自动测试&#xff0c;在打开蓝牙时&#xff0c;有一个是否同意的提示框要去掉&#xff0c;即默认同意打开蓝牙。 2、路径&#xff1a; packages/apps/Settings/src/com/android/settings/bluetooth/RequestPermissionActivity.java// Sho…...

多模态视频大模型Aria在Docker部署

多模态视频大模型Aria在Docker部署 契机 ⚙ 闲逛HuggingFace的时候发现一个25.3B的多模态大模型&#xff0c;支持图片和视频。刚好我有H20的GPU所以部署来看看效果&#xff0c;因为我的宿主机是cuda-12.1所以为了防止环境污染采用docker部署&#xff0c;通过一系列的披荆斩棘…...

Ant-Design-Vue 全屏下拉日期框无法显示,能显示后小屏又位置错乱

问题1&#xff1a;在全屏后 日期选择器的下拉框无法显示。 解决&#xff1a;在Ant-Design-Vue的文档中&#xff0c;很多含下拉框的组件都有一个属性 getPopupContainer可以用来指定弹出层的挂载节点。 在该组件上加上 getPopupContainer 属性,给挂载到最外层盒子上。 <temp…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

C++_哈希表

本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、基础概念 1. 哈希核心思想&#xff1a; 哈希函数的作用&#xff1a;通过此函数建立一个Key与存储位置之间的映射关系。理想目标&#xff1a;实现…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...

2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版

1.题目描述 2.思路 当前的元素可以重复使用。 &#xff08;1&#xff09;确定回溯算法函数的参数和返回值&#xff08;一般是void类型&#xff09; &#xff08;2&#xff09;因为是用递归实现的&#xff0c;所以我们要确定终止条件 &#xff08;3&#xff09;单层搜索逻辑 二…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...