RK3568驱动指南|第十二篇 GPIO子系统-第136章 实战:实现动态切换引脚复用功能

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。


【公众号】迅为电子

【粉丝群】824412014(加群获取驱动文档+例程)

【视频观看】嵌入式学习之Linux驱动(第十二篇 GPIO子系统_全新升级)_基于RK3568

【购买链接】迅为RK3568开发板瑞芯微Linux安卓鸿蒙ARM核心板人工智能AI主板


第136章 实战:实现动态切换引脚复用功能

再上一个小节中完成了GPIO子系统与pinctrl子系统相结合实验,在本章节中将更进一步,实现引脚动态切换引脚复用功能。

这里仍旧使用RK3568底板背面的20 pin GPIO底座的1号管脚来完成本章节要进行的动态切换引脚复用的功能,该引脚的核心板原理图内容如下所示:

图136-1

 左侧为该引脚的一些其他复用功能,在前面的章节中复用的都是GPIO功能,而本章节中将实现I2C3_SDA和GPIO两个复用功能的动态切换。

136.1 设备树的修改

本小节修改好的设备树以及编译好的boot.img镜像存放路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\90_gpioctrl09\01_内核镜像。

首先根据上图中的复用功能查看设备树中是否已经对该引脚进行了复用,在确保该引脚无任何复用之后,rk3568-evb1-ddr4-v10.dtsi设备树进行内容的添加,将根节点中的gpiol_a0修改为以下内容:

  my_gpio:gpio1_a0 {compatible = "mygpio";my-gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_HIGH>;pinctrl-names = "mygpio_func1", "mygpio_func2";pinctrl-0 = <&mygpio_ctrl>;pinctrl-1 = <&i2c3_sda>;};

pinctrl-names 表示引脚控制器配置的名称,这里有两个值,分别对应复用1和复用2。

pinctrl-0 指定了与该配置相关联的引脚控制器句柄,这里为 &mygpio_ctrl,表示复用为gpio功能。

pinctrl-1 指定了与该配置相关联的引脚控制器句柄,这里为 &i2c3_sda,表示复用为i2c3_sda功能。

添加完成如下图所示:

图136-2

然后找到pinctrl节点,在节点尾部进行修改和添加,具体内容如下所示:

    mygpio_func1 {mygpio_ctrl: my-gpio-ctrl {rockchip,pins = <1 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;};};  mygpio_func2 {i2c3_sda: i2c3_sda {rockchip,pins = <1 RK_PA0 1 &pcfg_pull_none>;};};     

修改添加完成如下图所示:

图136-3

至此,关于设备树相关的修改就完成了,保存退出之后,编译内核,然后将生成的boot.img镜像烧写到开发板上即可。

136.2 驱动程序的编写

本实验对应的网盘路径为:iTOP-RK3568开发板【底板V1.7版本】\03_【iTOP-RK3568开发板】指南教程\02_Linux驱动配套资料\04_Linux驱动例程\88_gpioctrl07\02_module

编写完成的gpio_api.c代码如下所示:

#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio.h>
#include <linux/device.h>
struct pinctrl *gpio_pinctrl;          // GPIO pinctrl 实例指针
struct pinctrl_state *func1_state;     // 功能1状态
struct pinctrl_state *func2_state;     // 功能2状态
int ret;ssize_t selectmux_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{unsigned long select;select = simple_strtoul(buf, NULL, 10);if (select == 1) {pinctrl_select_state(gpio_pinctrl, func1_state);     // 选择功能1状态} else if (select == 0) {pinctrl_select_state(gpio_pinctrl, func2_state);     // 选择功能2状态}return count;
}
DEVICE_ATTR_WO(selectmux);       // 定义可写的设备属性 selectmuxint pinctrl_get_and_lookstate(struct device *dev)
{gpio_pinctrl = pinctrl_get(dev);    // 获取GPIO pinctrl实例if (IS_ERR(gpio_pinctrl)) {printk("pinctrl_get is error\n");return -1;}func1_state = pinctrl_lookup_state(gpio_pinctrl, "mygpio_func1");    // 查找功能1状态if (IS_ERR(func1_state)) {printk("pinctrl_lookup_state is error\n");return -2;}func2_state = pinctrl_lookup_state(gpio_pinctrl, "mygpio_func2");    // 查找功能2状态if (IS_ERR(func2_state)) {printk("pinctrl_lookup_state is error\n");return -2;}return 0;
}// 平台设备初始化函数
static int my_platform_probe(struct platform_device *dev)
{printk("This is mydriver_probe\n");pinctrl_get_and_lookstate(&dev->dev);     // 获取并查找GPIO pinctrl实例和状态device_create_file(&dev->dev, &dev_attr_selectmux);    // 在设备上创建属性件return 0;
}// 平台设备的移除函数
static int my_platform_remove(struct platform_device *pdev)
{printk(KERN_INFO "my_platform_remove: Removing platform device\n");// 清理设备特定的操作// ...return 0;
}const struct of_device_id of_match_table_id[]  = {{.compatible="mygpio"},
};// 定义平台驱动结构体
static struct platform_driver my_platform_driver = {.probe = my_platform_probe,.remove = my_platform_remove,.driver = {.name = "my_platform_device",.owner = THIS_MODULE,.of_match_table =  of_match_table_id,},
};// 模块初始化函数
static int __init my_platform_driver_init(void)
{int ret;// 注册平台驱动ret = platform_driver_register(&my_platform_driver);if (ret) {printk(KERN_ERR "Failed to register platform driver\n");return ret;}printk(KERN_INFO "my_platform_driver: Platform driver initialized\n");return 0;
}// 模块退出函数
static void __exit my_platform_driver_exit(void)
{// 注销平台驱动platform_driver_unregister(&my_platform_driver);printk(KERN_INFO "my_platform_driver: Platform driver exited\n");
}module_init(my_platform_driver_init);
module_exit(my_platform_driver_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("topeet");

136.3运行测试

136.3.1 编译驱动程序

在上一小节中的gpio_api.c代码同一目录下创建 Makefile 文件,Makefile 文件内容如下所示:

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m += gpio_api.o    #此处要和你的驱动源文件同名
KDIR :=/home/topeet/Linux/linux_sdk/kernel    #这里是你的内核目录                                                                                                                            
PWD ?= $(shell pwd)
all:make -C $(KDIR) M=$(PWD) modules    #make操作
clean:make -C $(KDIR) M=$(PWD) clean    #make clean操作

对于Makefile的内容注释已在上图添加,保存退出之后,来到存放gpio_api.c和Makefile文件目录下,如下图(图136-4)所示:

图136-4

然后使用命令“make”进行驱动的编译,编译完成如下图(图136-5)所示:

图136-5

编译完生成gpio_api.ko目标文件,如下图(图136-6)所示:

图136-6

至此驱动模块就编译成功了。

136.3.2 运行测试

首先需要确保当前开发板使用的内核镜像是我们在135.2小节中修改设备树后编译生成的镜像,然后

启动开发板,首先使用以下命令查看gpio1 RK_PA0引脚的复用功能,如下图所示:

cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins | grep 32

图136-7

可以看到在没有加载驱动之前,gpio1 RK_PA0引脚是没有进行复用的,然后使用以下命令进行驱动的加载,如下图(图54-5)所示:

insmod gpio_api.ko

图136-8

然后使用以下命令进入/sys/devices/platform/gpio1_a0/目录,其中的selectmux文件就是用来动态修改服用关系的,如下图所示:

cd /sys/devices/platform/gpio1_a0/

 

图136-9

当向selectmux文件写入0时表示选择功能2,也就是将该引脚复用为I2C3_SDA,当向selectmux文件写入1时表示选择功能1,也就是将该引脚复用为GPIO,这里我们先输入以下命令向selectmux文件写入1,验证GPIO的复用

echo 1 > selectmux

 

图136-10

然后重新使用使用以下命令查看gpio1 RK_PA0引脚的复用功能,如下图所示:

cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins | grep 32

图136-11

根据打印信息可以得到gpio1 RK_PA0已经被设置为了GPIO功能,然后输入以下命令向selectmux文件写入0,验证I2C3_SDA的复用

echo 0 > selectmux

图136-12

然后重新使用使用以下命令查看gpio1 RK_PA0引脚的复用功能,如下图所示:

cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinctrl/pinmux-pins | grep 32

图136-13

根据打印信息可以得到gpio1 RK_PA0已经被复用为了I2C3_SDA功能,最后使用以下命令进行驱动的卸载,如下图所示:

rmmod gpio_api.ko

图136-14

至此,实现动态切换引脚复用功能实战就完成了。

 

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

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

相关文章

sectigo ip证书种类买一年送一月

Sectigo旗下的IP证书是专为只有公网IP地址的网站准备的。Sectigo旗下的数字证书大多是域名证书&#xff0c;例如&#xff0c;单域名SSL证书、多域名SSL证书、通配符SSL证书等。这些证书申请时必须验证域名所有权&#xff0c;申请者需要有一个拥有管理全的域名网站&#xff0c;那…

有了 Prisma,就别用 TypeORM 了

要说2024 年 Node.js 的 ORM 框架应该选择哪个&#xff1f;毫无疑问选 Prisma。至于为何&#xff0c;请听我细细道来。 <!-- truncate --> 本文面向的对象是饱受 TypeORM 折磨的资深用户(说的便是我自己)。只对这两个 ORM 框架从开发体验上进行对比&#xff0c;你也可以…

SRM供应商招标采购管理系统(源码)

软件相关资料获取&#xff1a;点我获取 一、SRM供应商在线采购 SRM供应商在线采购是指企业通过互联网平台&#xff0c;实现对供应商的在线招募、选择、关系管理等一系列活动。这种采购方式具有高效、透明、便于管理的特点&#xff0c;能够帮助企业降低采购成本&#xff0c;提…

陶瓷碗口缺口检测-图像形态学

图像形态学 对得到的灰度图像&#xff0c;需要进行二值化处理和区域填充。二值化涉及两个步骤&#xff0c;第一&#xff0c;对图像行图像分割&#xff0c;将图像分割成目标和和背景&#xff1b;第二&#xff0c;对分割后图像进行区域填充。本例中的背景为黑色&#xff0c;可以…

全自动网页生成系统网站源码重构版

源码优点: 所有模板经过精心审核与修改&#xff0c;完美兼容小屏手机大屏手机&#xff0c;以及各种平板端、电脑端和360浏览器、谷歌浏览器、火狐浏览器等等各大浏览器显示。 免费制作 为用户使用方便考虑&#xff0c;全自动网页制作系统无需繁琐的注册与登入&#xff0c;直…

独立按键控制继电器开关

/*----------------------------------------------- 内容&#xff1a;对应的继电器接口需用杜邦线连接到uln2003继电器控制端 ------------------------------------------------*/ #include<reg52.h> //包含头文件&#xff0c;一般情况不需要改动&#xff0…

x-cmd pkg | csview - 美观且高性能的 csv 数据查看工具

目录 介绍首次用户功能特点类似工具与竞品进一步阅读 介绍 csview 是一个用于在命令行中查看 CSV 文件的工具&#xff0c;采用 Rust 语言编写的&#xff0c;支持中日韩/表情符号。它允许用户在终端中以表格形式查看 CSV 数据&#xff0c;可以对数据进行排序、过滤、搜索等操作…

软件领域新手方向

新手入门指南 —.系统软件 驱动程序&#xff0c;操作系统(大企业要)&#xff1b; 二.C/S架构软件 大型(client客戸端需要下載安装&#xff0c;server服务端与客户交互)&#xff0c;小型(单机游戏)&#xff1b;桌面应用 三.B/S架构软件&#xff08;分前端&#xff0c;后端&…

x-cmd pkg | fx - Warp 支持的 JSON 查看和处理工具

目录 简介首次用户功能特点类似工具与竞品进一步探索 简介 fx 是一款由专为 JSON 定制的双用途命令行工具&#xff0c;提供基于终端的 JSON 查看器和 JSON 处理实用程序。虽然 JSON 查看器是用 Go 编写的&#xff0c;并且无需外部依赖即可运行&#xff0c;但 JSON 处理工具是用…

桌面显示器type-c接口方案6020

TYPE-C接口桌面显示器&#xff0c;与传统的显示器不同的是 新一类的显示器不仅仅支持视频传输&#xff0c;还可以利用显示器的DC电源转成PD协议充电给设备端&#xff08;笔记本&#xff0c;任天堂等HOST设备&#xff09;充电。 这种新型的TYPE-C接口桌面显示器&#xff0c;不仅…

什么是集成测试?

什么是集成测试 集成测试&#xff08;Integration Testing&#xff09;&#xff0c;也叫组装测试或联合测试。在单元测试的基础上&#xff0c;将所有模块按照设计要求&#xff08;如根据结构图&#xff09;组装成为子系统或系统&#xff0c;进行集成测试。 集成测试&#xff…

Logstash配置详解

一、配置文件 Logstash配置文件位于Logstash安装目录下bin/logstash.conf 启动命令: logstash -f logstash.conf文件描述logstash.yml配置Logstash的yml。pipelines.yml包含在单个Logstash实例中运行多个管道的框架和说明。jvm.options配置Logstash的JVM&#xff0c;使用此文…

确定性网络技术怎样实现网络的可靠性?

确定性网络技术通过采用特定的协议、机制和策略&#xff0c;有助于提高网络的可靠性。本文通过一些关键的方面&#xff0c;来说明确定性网络技术如何实现这一目标。 时钟同步机制 时钟同步机制是确定性网络中的核心角色。为了实现高度可靠的通信&#xff0c;需要采用先进的时钟…

算法学习系列(二十):树与图的DFS与BFS

目录 引言一、图的存储1.邻接矩阵2.邻接表 二、图的DFS1.模板2. 例题&#xff1a;树的重心 三、图的BFS1.模板2.例题&#xff1a;图中点的层次 引言 关于这个树与图考察的还是比较多的&#xff0c;其实就是图&#xff0c;树就是一种特殊的图&#xff0c;树是一种无环无向图&am…

brpc: a little source code

之前在https://www.yuque.com/treblez/qksu6c/nqe8ip59cwegl6rk?singleDoc# 《olap/clickhouse-编译器优化与向量化》中我谈过brpc的汇编控制bthread。本文就来看一下brpc作为一个高性能的rpc实现&#xff0c;除了自定义线程栈之外&#xff0c;代码还有什么优秀之处。 因为时间…

三国杀移动版武将台词大全-神

三国杀移动版武将台词大全-魏-CSDN博客 三国杀移动版武将台词大全-蜀-CSDN博客 三国杀移动版武将台词大全-吴-CSDN博客 三国杀移动版武将台词大全-群-CSDN博客 三国杀移动版武将台词大全-神-CSDN博客 # 神&#xff08;17/17&#xff09;&#xff1a; # 神刘备 神华佗 …

Vue3 不同版本的Pinia如何做持久化存储

不同版本的pinia支持的存储插件不同&#xff0c;高/低版本的持久化存储插件整合如下&#xff0c;都是我实践过的&#xff0c;请放心使用。&#x1f60a; 一、Vue3.2&#xff0c;pinia < 2.0.5&#xff0c;用pinia-plugin-persist 提示&#xff1a;不要去下最新的pinia-plug…

QT基础篇(5)QT5主窗口

1.QT5主窗口 QT5主窗口由以下几个部分构成&#xff1a; 标题栏&#xff1a;位于窗口的顶部&#xff0c;显示窗口的标题和控制按钮&#xff08;最小化、最大化、关闭&#xff09;。菜单栏&#xff1a;位于窗口的顶部&#xff0c;包含一系列菜单和菜单项&#xff0c;用于添加和…

K8S后渗透横向节点与持久化隐蔽方式探索

前言 通常在红蓝对抗中&#xff0c;我们可能会通过各种方法如弱口令、sql注入、web应用漏洞导致的RCE等方法获得服务器的权限&#xff1b;在当前云原生迅猛发展的时代&#xff0c;这台服务器很可能是一个容器&#xff0c;在后续的后渗透由传统的提权变为容器逃逸&#xff0c;内…

easyexcel上传校验的方法封装

easyexcel版本3.1.5 使用自定义注解的方式来定义校验的类型&#xff0c;避免冗余代码。 //校验value不能为空&#xff0c;且长度最大为30 RowCheck(value {RowCheckType.EMPTY,RowCheckType.LENGTH},max 30) private String value; 具体代码&#xff1a; 首先定义校验类型…