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

news2024/12/26 17:43:18

学习链接: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, 或者直接写寄存器。

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

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

相关文章

【51单片机】程序实验910.直流电机-步进电机

主要参考学习资料&#xff1a;B站【普中官方】51单片机手把手教学视频 前置知识&#xff1a;C语言 单片机套装&#xff1a;普中STC51单片机开发板A4标准版套餐7 码字不易&#xff0c;求点赞收藏加关注(•ω•̥) 有问题欢迎评论区讨论~ 目录 程序实验9&10.直流电机-步进电机…

windows 应用 UI 自动化实战

UI 自动化技术架构选型 UI 自动化是软件测试过程中的重要一环&#xff0c;网络上也有很多 UI 自动化相关的知识或资料&#xff0c;具体到 windows 端的 UI 自动化&#xff0c;我们需要从以下几个方面考虑&#xff1a; 开发语言 毋庸置疑&#xff0c;在 UI 自动化测试领域&am…

我不是挂王-用python实现燕双鹰小游戏

一.准备工作 1.前言提要 作为程序员在浩瀚的数字宇宙中&#xff0c;常常感觉现实世界是一台精密运作的虚拟机&#xff0c;其底层的物理逻辑如同铁律般难以撼动。然而我们拥有在虚拟世界中自由驰骋、创造无限可能的独特力量。突发奇我想用Python写出燕双鹰的小游戏,这样想想就很…

会议直击|美格智能亮相2024紫光展锐全球合作伙伴大会,融合5G+AI共拓全球市场

11月26日&#xff0c;2024紫光展锐全球合作伙伴大会在上海举办&#xff0c;作为紫光展锐年度盛会&#xff0c;吸引来自全球的众多合作伙伴和行业专家、学者共同参与。美格智能与紫光展锐竭诚合作多年&#xff0c;共同面向5G、AI和卫星通信为代表的前沿科技&#xff0c;聚焦技术…

3. STM32_串口

数据通信的基础概念 什么是串行/并行通信&#xff1a; 串行通信就是数据逐位按顺序依次传输 并行通信就是数据各位通过多条线同时传输。 什么是单工/半双工/全双工通信&#xff1a; 单工通信&#xff1a;数据只能沿一个方向传输 半双工通信&#xff1a;数据可以沿两个方向…

RPC与HTTP调用模式的架构差异

RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;和 HTTP 调用是两种常见的通信模式&#xff0c;它们在架构上有以下一些主要差异&#xff1a; 协议层面 RPC&#xff1a;通常使用自定义的二进制协议&#xff0c;对数据进行高效的序列化和反序列化&am…

Microsoft Excel如何插入多行

1.打开要编辑的excel表&#xff0c;在指定位置&#xff0c;鼠标右键点击“插入”一行 2.按住shift键&#xff0c;鼠标的光标箭头会变化成如下图所示 3.一直按住shift键和鼠标左键&#xff0c;往下拖动&#xff0c;直至到插入足够的行

【python】图像、音频、视频等文件数据采集

【python】图像、音频、视频等文件数据采集 先安装所需要的工具一、Tesseract-OCRTesseract-OCR环境变量设置验证是否配置成功示例语言包下载失败 二、ffmpeg验证是否安装成功示例 先安装所需要的工具 一、Tesseract-OCR Tesseract是一个 由HP实验室开发 由Google维护的开源的…

虚拟机docker记录

最近看了一个up的这个视频&#xff0c;感觉docker真的挺不错的&#xff0c;遂也想来搞一下&#xff1a; https://www.bilibili.com/video/BV1QC4y1A7Xi/?spm_id_from333.337.search-card.all.click&vd_sourcef5fd730321bc0e9ca497d98869046942 这里我用的是vmware安装ubu…

C++STL之vector(超详细)

CSTL之vector 1.vector基本介绍2.vector重要接口2.1.构造函数2.2.迭代器2.3.空间2.3.1.resize2.3.2.capacity 2.4.增删查找 3.迭代器失效4.迭代器分类 &#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f68…

深度学习实验十三 卷积神经网络(4)——使用预训练resnet18实现CIFAR-10分类

目录 一、数据加载 二、数据集类构建 三、模型构建 四、模型训练 五、模型评价及预测 附完整可运行代码&#xff1a; 实验大体步骤&#xff1a; 注&#xff1a; 在自己电脑的CPU跑代码 连接远程服务器跑代码√ 本次实验由于数据量巨大&#xff0c;我的笔记本上还没有…

【Maven Helper】分析依赖冲突案例

目录 Maven Helper实际案例java文件pom.xml文件运行抛出异常分析 参考资料 《咏鹅》骆宾王 鹅&#xff0c;鹅&#xff0c;鹅&#xff0c;曲项向天歌。 白毛浮绿水&#xff0c;红掌拨清波。 骆宾王是在自己7岁的时候就写下了这首杂言 Maven Helper A must have plugin for wor…

Android 桌面窗口新功能推进,聊一聊 Android 桌面化的未来

Android 桌面化支持可以说是 Android 15 里被多次提及的 new features&#xff0c;例如在 Android 15 QPR1 Beta 2 里就提到为 Pixel 平板引入了桌面窗口支持&#xff0c;桌面窗口允许用户在自由窗口同时运行多个应用&#xff0c;同时可以像在传统 PC 平台上一样调整这些窗口的…

【深度学习】四大图像分类网络之VGGNet

2014年&#xff0c;牛津大学计算机视觉组&#xff08;Visual Geometry Group&#xff09;和Google DeepMind公司一起研发了新的卷积神经网络&#xff0c;并命名为VGGNet。VGGNet是比AlexNet更深的深度卷积神经网络&#xff0c;该模型获得了2014年ILSVRC竞赛的第二名&#xff0c…

Pytest框架学习20--conftest.py

conftest.py作用 正常情况下&#xff0c;如果多个py文件之间需要共享数据&#xff0c;如一个变量&#xff0c;或者调用一个方法 需要先在一个新文件中编写函数等&#xff0c;然后在使用的文件中导入&#xff0c;然后使用 pytest中定义个conftest.py来实现数据&#xff0c;参…

【力扣】389.找不同

问题描述 思路解析 只有小写字母&#xff0c;这种设计参数小的&#xff0c;直接桶排序我最开始的想法是使用两个不同的数组&#xff0c;分别存入他们单个字符转换后的值&#xff0c;然后比较是否相同。也确实通过了 看了题解后&#xff0c;发现可以优化&#xff0c;首先因为t相…

HarmonyOS4+NEXT星河版入门与项目实战(23)------组件转场动画

文章目录 1、控件图解2、案例实现1、代码实现2、代码解释3、实现效果4、总结1、控件图解 这里我们用一张完整的图来汇整 组件转场动画的用法格式、属性和事件,如下所示: 2、案例实现 这里我们对上一节小鱼游戏进行改造,让小鱼在游戏开始的时候增加一个转场动画,让小鱼自…

Wireshark常用功能使用说明

此处用于记录下本人所使用 wireshark 所可能用到的小技巧。Wireshark是一款强大的数据包分析工具&#xff0c;此处仅介绍常用功能。 Wireshark常用功能使用说明 1.相关介绍1.1.工具栏功能介绍1.1.1.时间戳/分组列表概况等设置 1.2.Windows抓包 2.wireshark过滤器规则2.1.wiresh…

Vue3 开源UI 框架推荐 (大全)

一 、前言 &#x1f4a5;这篇文章主要推荐了支持 Vue3 的开源 UI 框架&#xff0c;包括 web 端和移动端的多个框架&#xff0c;如 Element-Plus、Ant Design Vue 等 web 端框架&#xff0c;以及 Vant、NutUI 等移动端框架&#xff0c;并分别介绍了它们的特性和资源地址。&#…

探索Python词云库WordCloud的奥秘

文章目录 探索Python词云库WordCloud的奥秘1. 背景介绍&#xff1a;为何选择WordCloud&#xff1f;2. WordCloud库简介3. 安装WordCloud库4. 简单函数使用方法5. 应用场景示例6. 常见Bug及解决方案7. 总结 探索Python词云库WordCloud的奥秘 1. 背景介绍&#xff1a;为何选择Wo…