创龙瑞芯微RK3568设备树1(修改设备树GPIO和串口)
前言
最近一直在搞3568的东西,涉及到底层的设备树修改,驱动编写等等,忙的焦头烂额的,也没时间往下面写东西了。今天差不多底层的东西快弄完了,把最近的感悟给大家分享下,并且加入点设备树的基础知识。给刚刚涉足开发板学习的小伙伴一点帮助。当然对于大神们来说,写的肯定是皮毛。一起共勉!
基础
涉及到的知识,我会用类比的方法和STM32的硬件做对比,其实弄完之后发现两个差不多,没有什么本质的区别。所以小伙伴看之前的基础是必须编写过单片机的程序,对单片机的架构有一定的了解,要不看完会更迷茫。
题外话
学习这个真是很痛苦,并且不知道自己做的对不对,需要一遍一遍的测试。并且问了其他小伙伴,有一个共同的感觉:随着年龄的增加,学习能力大大下降。并且已经抽不出那么多精力去学习能力了。
每天刷抖音,看到什么35岁失业什么的,其实吧,感觉有三个原因吧,仅仅是自己猜测:
(1)技术没有做扎实就转到管理岗了。公司发展太快,所以刚进去的技术还没有很好的基础,就转到管理,使得自己的技术不扎实,再从管理岗转回来,已经很难了。
(2)技术也不错,但是忘记了学习,一直做自己习惯的东西,然后到了管理。但是到了管理之后,技术更新了,以前的技术已经适应不了现在的东西了。这个应该是大部分人的问题吧。就算在一个技术上做的时间长了,也会不学习了,感觉现在的东西够了。当然学习新的东西会很难、很闹心。其实我也想一直做单片机,也就控制几个灯,控制几个外设。然后搞搞逻辑啥的。一直在自己的舒适区。
(3)技术也够,学习也一直在学,但是换个工作工资低了,不愿将就。但愿每个人都是因为这个原因。
内容
这次介绍4个内容,都是最简单的外设:(1)GPIO,(2)串口,(3)I2C,(4)CAN。这4个应该能包含大部分硬件应用了,当然还有麻烦的,后面再慢慢介绍,一点一点的来。先介绍最基本的,大概有个印象。
1.GPIO
GPIO_InitTypeDef GPIO_Initure;__HAL_RCC_GPIOE_CLK_ENABLE(); GPIO_Initure.Pin = GPIO_PIN_15; GPIO_Initure.Mode = GPIO_MODE_INPUT; GPIO_Initure.Pull = GPIO_PULLUP; GPIO_Initure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; HAL_GPIO_Init(GPIOE, &GPIO_Initure);
这个是单片机的GPIO初始化。定义GPIO结构体,开时钟,管脚号,管脚输入,管脚模式,管脚速度,参数传入结构体。
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_SET);
这个是控制程序。直接根据HALk库给的函数就行。要是不用HAL库,自己控制,也都是别人给好的API函数。
对比下来,在Linux的3568设备树里:
gpioled1 {compatible = "MY,led1";led1-gpio = <&gpio0 RK_PD5 GPIO_ACTIVE_HIGH>;status = "okay";};
先说第二句:gpio的管脚定义,第三句:状态定义。
第一句是匹配定义,这个后面再说。后面牵涉到驱动部分,这个后面会详细介绍,所以现在先由个概念,知道是这么回事。
至此到这里,GPIO的设备树部分介绍完毕。下面说下两者的区别,仅仅说对于GPIO设定部分的区别哈,其他的就不说了,没啥用。
相同点:定义了管脚,并且定义了初始电平;
不同点:单片机定义了管脚的输入和输出,3568定义了匹配字。至于语法的区别,就不做过多的介绍了。
所以,3568里面还需要对其他的进行定义,第一个:输入输出定义,第二个:控制程序。这个后面再说。先说下,输入输出定义在驱动里面定义,控制程序也是线程的API,只要拿过来使用就行了。
2.串口
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;GPIO_InitStruct.Alternate = GPIO_AF7_USART2;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
先说第一部分,管脚定义。这部分应该很熟悉,定义管脚,定义管脚复用,然后定义复用到什么上面,然后参数传入结构体。这部分是管脚的定义。
huart2.Instance = USART2;huart2.Init.BaudRate = 1000000;huart2.Init.WordLength = UART_WORDLENGTH_8B;huart2.Init.StopBits = UART_STOPBITS_1;huart2.Init.Parity = UART_PARITY_NONE;huart2.Init.Mode = UART_MODE_TX_RX;HAL_UART_Init(&huart2);
然后说第二部分,串口定义。前面定义了管脚,相当于管脚已经复用到了串口上,然后定义串口的信息。对应串口2,波特率,起始位,停止位等。
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USART2_IRQn);
然后就是中断函数,接收和发送中断。对应的就是接收和发送函数中断。这个API在it.c里面应该可以找到。要是找不到就直接去库函数里面找。
对比下来,在3568的设备树里:
uart1 {/omit-if-no-ref/uart1m0_xfer: uart1m0-xfer {rockchip,pins =/* uart1_rxm0 */<2 RK_PB3 2 &pcfg_pull_up>,/* uart1_txm0 */<2 RK_PB4 2 &pcfg_pull_up>;};/omit-if-no-ref/uart1m0_ctsn: uart1m0-ctsn {rockchip,pins =/* uart1m0_ctsn */<2 RK_PB6 2 &pcfg_pull_none>;};/omit-if-no-ref/uart1m0_rtsn: uart1m0-rtsn {rockchip,pins =/* uart1m0_rtsn */<2 RK_PB5 2 &pcfg_pull_none>;};/omit-if-no-ref/uart1m1_xfer: uart1m1-xfer {rockchip,pins =/* uart1_rxm1 */<3 RK_PD7 4 &pcfg_pull_up>,/* uart1_txm1 */<3 RK_PD6 4 &pcfg_pull_up>;};/omit-if-no-ref/uart1m1_ctsn: uart1m1-ctsn {rockchip,pins =/* uart1m1_ctsn */<4 RK_PC1 4 &pcfg_pull_none>;};/omit-if-no-ref/uart1m1_rtsn: uart1m1-rtsn {rockchip,pins =/* uart1m1_rtsn */<4 RK_PB6 4 &pcfg_pull_none>;};};
这个是pinctrl里面的设备树结构。里面包含串口的各种复用管脚定义。里面m0和m1可以自己选择,当然选择方法在后面。
对比不同点:单片机里面直接写出来用哪个管脚,用哪个需要自己去写。而3568里面全部给你写出来,然后你自己再配置。
uart1: serial@fe650000 {compatible = "rockchip,rk3568-uart", "snps,dw-apb-uart";reg = <0x0 0xfe650000 0x0 0x100>;interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;clock-names = "baudclk", "apb_pclk";reg-shift = <2>;reg-io-width = <4>;dmas = <&dmac0 2>, <&dmac0 3>;pinctrl-names = "default";pinctrl-0 = <&uart1m0_xfer>;status = "disabled";};
然后底层的设备树,这部分不用修改,别人给写好的。至于怎么写,不用管,只知道在这里就行。
解释下:匹配字,状态,寄存器地址。中断地址,时钟,时钟名称,寄存器偏移,寄存器宽度,DMA,管脚名称,管脚初始定义。
其实在单片机里,中断函数已经给你配好了,而设备树里直接给你写出来了。怎么写的 ,千万别去研究,别人做好的,直接用就行,或者直接知道是啥东西就行。然后管脚选用的是m0。这个是别人的初始定义,后面可以再修改。所以这个地方就看看,知道是啥就行,至于reg啥的,千万别管。
&uart1 {status = "okay";pinctrl-0 = <&uart1m1_xfer>;
};
这是后面的自己定义。前面别人给个初始的,后面用不用看自己。用的话就来个okay,不用就不用管。要是用的话,管脚不一样咋弄,那就给改改。
然后,然后就没了。就那么多东西。
对于GPIO中的驱动,GPIO的驱动简单,可以自己写一个。但是串口的比较麻烦,别人都写好了,不用管。配好设备树之后,linux会自己加载驱动函数。就像单片机里面的收发中断,然后放到buffer里面。其实你也不知道咋驱动的,就是可以收到数,然后解析就行。
切记:千万别深究,千万别深究。
不同
设备树放的比较乱,如果别人开发的不好,放的会更乱,所以选开发板的时候选大厂的。放的位置好,你就好看点,学习起来也快。至于程序放的位置,放哪都行,随你意,但是最好按照别人写好的去放,看起来方便。
单片机里面的东西,都是一块一块的,相对来说,别人都给你封好了,3568或者其他开发板里面的程序都是按照功能一大块放一起,看起来比较麻烦。
总结
设备树就是将单片机的不同的功能,大家放一起,然后自己挑出来。并且用很晦涩的表达方式表达出来,不用看懂具体是啥,也不用纠结怎么去编写,会改管脚就行。给的pdf里面肯定会有说明怎么弄,要是没有,引用别人的话:赶紧跑路,还搞啥,自己肯定编不了。
后续
接触的时候脑袋疼,这是啥,这又是啥。当真的去一个一个的琢磨之后,才发现,哦,和单片机差不多。学习顺序:克服心理障碍,静下心,一句一句的看,不会的查,改,改,改,不用担心改错,反正也改不坏。还有一定要做好备份,在修改任何东西前,一定先保存一份,万一改错了还能复原,再从开始改。
后面介绍I2C和CAN的设备树,然后再介绍GPIO的驱动函数,然后就再ETH,然后再其他的。慢慢来。喜欢的小伙伴点个关注,后续文章继续发送。
相关文章:
创龙瑞芯微RK3568设备树1(修改设备树GPIO和串口)
前言 最近一直在搞3568的东西,涉及到底层的设备树修改,驱动编写等等,忙的焦头烂额的,也没时间往下面写东西了。今天差不多底层的东西快弄完了,把最近的感悟给大家分享下,并且加入点设备树的基础知识。给刚刚…...
R语言【dplyr】——filter保留符合筛选条件的行,以数据的行为单位,创建子集
Package dplyr version 1.1.4 Parameters filter(.data, ..., .by NULL, .preverse FALSE) 参数【.data】:一个数据集(data frame),数据集扩展(比如:tibble),或者 lazy data fra…...
几种串口扩展电路
一、IIC串口扩展电路 LCT200 是一款可以通过 I2C 接口通讯,拓展 2 路独立串口的通讯芯片,同时也支持通过 2 路串口读写 I2C 接口的数据。LCT200 的封装为 TSSOP-20。 主要功能:⚫ 通过对 I2C 接口读写实现拓展 2 路独立串口功能 ⚫ 通过读写…...
实战10 角色管理
目录 1、角色后端接口 2、角色列表查询 2.1 效果图 2.2页面原型代码 2.3 角色api代码 role.js 2.4 查询角色列表代码 4、 新增和编辑角色 5、删除角色 6、分配权限 6.1 分配权限思路 6.2 分配权限回显接口 6.3 分配权限回显前端实现 6.4分配权限后端接口 6.4.1 R…...
Lua的底层原理与C#交互原理浅析【更新中】
目录 lua底层原理浅析 table底层原理浅析 Lua表的C语言定义 原理和实现 userdata lua和C#的交互机制(更新中) 基本介绍 Lua 与 C/C 的数据交互 Lua 调用 C/C 函数 C/C 调用 Lua 函数 基元类型传递 对象类型传递 Lua 调用 C# 总结 网上有很…...
鸿蒙项目二—— 注册和登录
此部分和上篇文章是连续剧 ,如果需要,请查看 一、注册 import http from ohos.net.http; Entry Component struct Reg {// 定义数据:State username: string "";State userpass: string "";State userpass2: string …...
Dijkstra(迪杰斯特拉)算法总结
知识概览 Dijkstra算法适用于解决所有边权都是正数的最短路问题。Dijkstra算法分为朴素的Dijkstra算法和堆优化版的Dijkstra算法。朴素的Dijkstra算法时间复杂度为,适用于稠密图。堆优化版的Dijkstra算法时间复杂度为,适用于稀疏图。稠密图的边数m和是一…...
设计模式?!
如何解决复杂性 链接:不同的设计模式实例代码(更新中) 分解 人们面对复杂性有一个常见的做法:即分而治之,将大问题分解为多个小问题,将复杂问题分解为多个简单问题。 抽象 更高层次来讲,人们处…...
Pytorch项目,肺癌检测项目之三
成功获取到数据之后,我们需要将数据放到Pytorch里面去处理,我们需要将其转换成Dataset数据集,方便去使用相同的API。要转换成Dataset数据集需要实现两个方法,方法一: 方法二: 运行比较慢的话,…...
深圳鼎信|输电线路防山火视频监控预警装置:森林火灾来袭,安全不留白!
受线路走廊制约和环保要求影响,输电线路大多建立在高山上,不仅可以减少地面障碍物和人类活动的干扰,还能提高线路的抗灾能力和可靠性。但同时也会面临其它的难题,例如森林火灾预防。今天,深圳鼎信智慧将从不同角度分析…...
【Bash/Shell】知识总结
文章目录 1. 总体认识1.1. Shell概述1.2. 第一个Shell脚本1.3. 注释 2. 变量2.1. 定义变量2.2. 使用变量2.3. 只读变量2.4. 删除变量2.5. 变量类型2.5.1. 字符串变量2.5.2. 整数变量2.5.3. 数组变量2.5.4. 环境变量2.5.5. 特殊变量 3. 输出3.1. echo命令3.2. printf命令 4. 运算…...
单例模式(C++实现)
RAII运用 只能在栈上创建对象 只能在堆上创建的对象 单例模式 设计模式 懒汉模式 解决线程安全 优化 饿汉模式 饿汉和懒汉的区别 线程安全与STL与其他锁...
ElasticSearch 聚合统计
聚合统计 度量聚合:求字段的平均值,最小值,最大值,总和等 桶聚合:将文档分成不同的桶,桶的划分可以根据字段的值,范围,日期间隔 管道聚合:在桶聚合的结果上执行进一步计…...
SpringIOC之MethodBasedEvaluationContext
博主介绍:✌全网粉丝5W+,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战,博主也曾写过优秀论文,查重率极低,在这方面有丰富的经验✌ 博主作品:《Java项目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…...
【网络安全 | 网络协议】结合Wireshark讲解TCP三次握手
前言 TCP(传输控制协议)是一种面向连接的、可靠的传输层协议。在建立 TCP 连接时,需要进行三次握手,防止因为网络延迟、拥塞等原因导致的数据丢失或错误传输,确保双方都能够正常通信。 TCP三次握手在Wireshark数据包中…...
钦丰科技(安徽)股份有限公司携卫生级阀门管件盛装亮相2024发酵展
钦丰科技(安徽)股份有限公司携卫生级阀门管件盛装亮相2024济南生物发酵展! 展位号:2号馆A65展位 2024第12届国际生物发酵产品与技术装备展览会(济南)于3月5-7日在山东国际会展中心盛大召开,展会同期将举办30余场高质…...
Python模拟动态星空
前言 今天,我们来用Python做个星空。 一、模拟星空 1,.首先导入所需要的库: from turtle import * from random import random, randint 2.初始画面: screen Screen() width, height 800, 600 screen.setup(width, height) screen.tit…...
最新技术整理3款开源免费直播推流工具,实现实时视频推流、视频拉流,目标端可以是服务器、云平台、移动设备等(附源码)
最新技术整理3款开源免费直播推流工具,实现实时视频推流、视频拉流,目标端可以是服务器、云平台、移动设备等(附源码)。 什么是推流? 视频推流是指将实时的视频数据从一个源端发送到一个或多个目标端的过程。推流的源…...
shell ——数组
数组中可以存放多个值,Bash Shell只能支持以为数字,初始化时不需要定义数组大小。 数组中元素下标从0开始。 数组的定义 shell数组用括号来表示,元素用空格分割开。 array_name(value1 value2 value3 ...) 给一个简单数组例子 cat firs…...
GO语言基础笔记(五):包的介绍
在Go语言中,包(package)是代码组织和重用的基本单位。Go的标准库中包含了许多实用的包,它们提供了从基础数据处理到复杂网络编程等各种功能。下面是一些常用的Go标准库包及其作用的介绍: 目录 1. fmt 2. net/http …...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
大数据治理的常见方式
大数据治理的常见方式 大数据治理是确保数据质量、安全性和可用性的系统性方法,以下是几种常见的治理方式: 1. 数据质量管理 核心方法: 数据校验:建立数据校验规则(格式、范围、一致性等)数据清洗&…...
【实施指南】Android客户端HTTPS双向认证实施指南
🔐 一、所需准备材料 证书文件(6类核心文件) 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...
从零手写Java版本的LSM Tree (一):LSM Tree 概述
🔥 推荐一个高质量的Java LSM Tree开源项目! https://github.com/brianxiadong/java-lsm-tree java-lsm-tree 是一个从零实现的Log-Structured Merge Tree,专为高并发写入场景设计。 核心亮点: ⚡ 极致性能:写入速度超…...
