xilinx linux AXI GPIO 驱动学习

news/2024/4/28 23:02:19/文章来源:https://blog.csdn.net/qq_41873311/article/details/136927846

vivado工程

vivado 配置一个 AXI GPIO, 全输出,宽度为1
在这里插入图片描述

设备树解读

生成的对应pl.dtsi设备树文件如下

		axi_gpio: gpio@40020000 {#gpio-cells = <2>;clock-names = "s_axi_aclk";clocks = <&clkc 15>;compatible = "xlnx,axi-gpio-2.0", "xlnx,xps-gpio-1.00.a";gpio-controller ;reg = <0x40020000 0x10000>;xlnx,all-inputs = <0x0>;xlnx,all-inputs-2 = <0x0>;xlnx,all-outputs = <0x1>;xlnx,all-outputs-2 = <0x1>;xlnx,dout-default = <0x00000000>;xlnx,dout-default-2 = <0x00000000>;xlnx,gpio-width = <0x1>;xlnx,gpio2-width = <0x1>;xlnx,interrupt-present = <0x0>;xlnx,is-dual = <0x1>;xlnx,tri-default = <0xFFFFFFFF>;xlnx,tri-default-2 = <0xFFFFFFFF>;};

根据 compatible = “xlnx,xps-gpio-1.00.a” 找到内核文档 Documentaion/devicetree/bindings/gpio/gpio-xilinx.txt

关注以下部分

- #gpio-cells : Should be two or three. The first cell is the pin number,The second cell is used to specify channel offset:0 - first channel8 - second channelThe third cell is optional and used to specify flags. Use the macrosdefined in include/dt-bindings/gpio/gpio.h
- gpio-controller : Marks the device node as a GPIO controller.

意思是需要至少两个参数,第一个是引脚号,第二个是用来指定通道,第三个参数可有可无,只是一个flag
而对于刚才生成的双通道axi gpio,引脚号从0开始,而第一个通道号为0,第二个为8

例如,可以这样访问

	name1-gpios = <&axi_gpio 0 0 GPIO_ACTIVE_LOW>;	name2-gpios = <&axi_gpio 0 8 GPIO_ACTIVE_HIGH>;

gpio驱动

先去看文档 Documentaion/gpio/consumer.txt
首先要 #include <linux/gpio/consumer.h>,定义了几个flags和重要的函数

The flags parameter is used to optionally specify a direction and initial value
for the GPIO. Values can be:
* GPIOD_IN to initialize the GPIO as input.
* GPIOD_OUT_LOW to initialize the GPIO as output with a value of 0.
* GPIOD_OUT_HIGH to initialize the GPIO as output with a value of 1.

flags 讲的就很清楚,设置flags 可以指定方向和初始值

使用GPIOs 部分解读

按照以前的理解,GPIO肯定要先初始化,再设置方向,再设置高低电平

Obtaining and Disposing GPIOs
=============================
Like many other kernel subsystems, gpiod_get() takes the
device that will use the GPIO and the function the requested GPIO is supposed to
fulfill:struct gpio_desc *gpiod_get(struct device *dev, const char *con_id,enum gpiod_flags flags)

也就是可以调用gpiod_get()函数来请求使用GPIO并实现某种功能
然后根据指示,通过 see Documentation/gpio/board.txt 来理解 the con_id parameter in the DeviceTree

假设有个设备树

	foo_device {compatible = "acme,foo";...led-gpios = <&gpio 15 GPIO_ACTIVE_HIGH>, /* red */<&gpio 16 GPIO_ACTIVE_HIGH>, /* green */<&gpio 17 GPIO_ACTIVE_HIGH>; /* blue */power-gpios = <&gpio 1 GPIO_ACTIVE_LOW>;};

可以使用以下函数访问

struct gpio_desc *red, *green, *blue, *power;red = gpiod_get_index(dev, "led", 0, GPIOD_OUT_HIGH);
green = gpiod_get_index(dev, "led", 1, GPIOD_OUT_HIGH);
blue = gpiod_get_index(dev, "led", 2, GPIOD_OUT_HIGH);power = gpiod_get(dev, "power", GPIOD_OUT_HIGH);

但是gpiod_get()还需要其他函数搭配使用吗?继续看

Using GPIOs
===========
Setting Direction
-----------------
The first thing a driver must do with a GPIO is setting its direction. If no
direction-setting flags have been given to gpiod_get*(), this is done by
invoking one of the gpiod_direction_*() functions:int gpiod_direction_input(struct gpio_desc *desc)int gpiod_direction_output(struct gpio_desc *desc, int value)

但是这里说,如果没有在调用gpiod_get*()函数时给一个 direction-setting flags,那就需要调用gpiod_direction_*() 这两个函数之一

换句话说,如果在调用gpiod_get*()函数时给一个 direction-setting flag,就不需要设置其他函数了

所以,gpiod_get*()函数 完成了三件事:申请使用GPIO,通过flags设置了方向并初始化值

重要函数

struct gpio_desc *devm_gpiod_get_optional(struct device *dev, const char *con_id, enum gpiod_flags flags)
很多驱动文件里在用,文档里只提到了是一个变体函数,调用关系如下

devm_gpiod_get_optional -> devm_gpiod_get_index_optional -> //index为0 devm_gpiod_get_index -> gpiod_get_index

本质就是 gpiod_get_index

因此,对于我们的设备树

	name1-gpios = <&axi_gpio 0 0 GPIO_ACTIVE_LOW>;	name2-gpios = <&axi_gpio 0 8 GPIO_ACTIVE_HIGH>;

可以这么用

struct i2c_client *client;
struct gpio_desc name1_gpio;
name1_gpio = devm_gpiod_get_optional(&client->dev, "name1", GPIOD_OUT_HIGH);
if(IS_ERR(name1_gpio)){dev_err(&client->dev, "can't get %s name1 GPIO in DT\n", "name1");return PTR_ERR(name1_gpio);
}

做了几件事:

  1. 寻找设备树中有没有 name1-gpios
  2. 申请GPIO使用
  3. 通过 flag 初始化方向并设置高低电平

结束语

多看内核文档,多看参考驱动代码,多理解

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

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

相关文章

淘宝app商品数据API接口|item_get_app-获得淘宝app商品详情原数据

获得淘宝app商品详情原数据 API返回值说明 item_get_app-获得淘宝app商品详情原数据 公共参数​​​​​​ 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地…

[ Linux ] git工具的基本使用(仓库的构建,提交)

1.安装git yum install -y git 2.打开Gitee&#xff0c;创建你的远程仓库&#xff0c;根据提示初始化本地仓库&#xff08;这里以我的仓库为例&#xff09; 新建好仓库之后跟着网页的提示初始化便可以了 3.add、commit、push三板斧 git add . //add仓库新增&#xff08;变…

软考 - 系统架构设计师 - 关系模型的完整性规则

前言 关系模型的完整性规则是一组用于确保关系数据库中数据的完整性和一致性的规则。这些规则定义了在关系数据库中如何存储、更新和查询数据&#xff0c;以保证数据的准确性和一致性。 详情 关系模型的完整性规则主要包括以下三类&#xff1a; 实体完整性规则 这是确保每个…

C++判断点是否在三角形内部

1.问题 判断点是否在三角形内部。 2.思路 计算向量AB和AP的叉积、向量BC和BP的叉积、向量CA和CP的叉积&#xff0c;如果所有的叉积符号相同&#xff0c;则点在三角形内部。 3.代码实现和注释 #include <iostream> #include <vector>// 计算两个二维向量的叉积 …

第十一届蓝桥杯大赛第二场省赛试题 CC++ 研究生组-回文日期

solution1&#xff08;通过50%&#xff09; #include<stdio.h> void f(int a){int t a;while(a){printf("%d", a % 10);a / 10;}if(t < 10) printf("0"); } int isLeap(int n){if(n % 400 0 || (n % 4 0 && n % 100 ! 0)) return 1;r…

QT+GDAL实现影像的读取和显示

详细流程参考https://blog.csdn.net/deirjie/article/details/37872743 代码 //open_image.h #pragma once #include <QtWidgets/QMainWindow> #include "ui_open_image.h" #include "gdal_priv.h" #include <QMessageBox> #include <QFi…

是谁?阻止CXL在AI场景大展身手~

CXL虽然被视为业内新宠&#xff0c;但好像在AI场景的应用反而没有得到广泛的响应。 AI场景对内存带宽、容量以及数据一致性有着极高需求&#xff0c;特别是在深度学习训练和推理过程中&#xff0c;大量数据需要在CPU、GPU、加速器以及内存之间快速、高效地流动。CXL作为一种新…

Java基础面试复习

一、java基础 1、jdk、jre、jvm的区别 jdk&#xff1a;Java程序开发工具包。 jre&#xff1a;Java程序运行环境。 jvm&#xff1a;Java虚拟机。 2、一个Java源文件中是否可以包含多个类有什么限制 解&#xff1a;可以包含多个类但是只有一个类生命成public并且要和文件名一致 …

代码随想录训练营day18

第六章 二叉树 part05 1.LeetCode.找树左下角的值 1.1题目链接&#xff1a;513.找树左下角的值 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;B站卡哥视频 1.2思路&#xff1a;本题要找出树的最后一行的最左边的值。此时大家应该想起用层序遍历是非常简单的了&…

24计算机考研调剂 | 【官方】北京科技大学

北京科技大学 考研调剂招生信息 招生专业&#xff1a; 085404&#xff08;计算机技术&#xff09; 081200&#xff08;计算机科学与技术&#xff09; 调剂要求&#xff1a;&#xff08;调剂基本分数&#xff09; 我中心将在教育部“全国硕士生招生调剂服务系统”&#xff08…

MRC是谁?- 媒体评级委员会 Media Rating Council

在在线广告的世界里&#xff0c;有许多不同的技术和实践用于提供和衡量广告。对于广告商、出版商和营销人员来说&#xff0c;了解这些技术是如何工作的以及如何有效使用这些技术很重要。在这方面发挥关键作用的一个组织是媒体评级委员会&#xff08;MRC&#xff09;。 1. 了解…

市场复盘总结 20240328

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 40% 最常用的…

C#手术麻醉系统源码 可对接HIS LIS PACS 医疗系统各类设备 医院手麻系统源码

C#手术麻醉系统源码 可对接HIS LIS PACS 医疗系统各类设备 手术麻醉信息管理系统主要还是为了手术室开发提供全面帮助的系统&#xff0c;其主要是由监护设备数据采集子系统和麻醉临床系统两个子部分组成。包括从手术申请到手术分配&#xff0c;再到术前访视、术中记录及术后…

并发编程之Callable方法的详细解析(带小案例)

Callable &#xff08;第三种线程实现方式&#xff09; Callable与Runnable的区别 Callable与Runnable的区别 实现方法名称不一样 有返回值 抛出了异常 ​class Thread1 implements Runnable{Overridepublic void run() { ​} } ​ class Thread2 implements Callable<…

软件推荐 篇三十七:安卓软件推荐IP Tools「IP工具」:全面解析网络状态与管理的必备神器

引言&#xff1a; 随着互联网的普及&#xff0c;网络已经成为我们日常生活中不可或缺的一部分。无论是工作、学习还是娱乐&#xff0c;我们都需要通过网络来进行各种操作。然而&#xff0c;网络问题的出现往往会给我们带来诸多困扰。为了更好地管理和优化网络&#xff0c;我们…

虹科Pico汽车示波器 | 免拆诊断案例 | 2018款东风风神AX7车发动机怠速抖动、加速无力

一、故障现象 一辆2018款东风风神AX7车&#xff0c;搭载10UF01发动机&#xff0c;累计行驶里程约为5.3万km。该车因发动机怠速抖动、加速无力及发动机故障灯异常点亮而进厂维修&#xff0c;维修人员用故障检测仪检测&#xff0c;提示气缸3失火&#xff1b;与其他气缸对调点火线…

【Qt】使用Qt实现Web服务器(五):QtWebApp上传文件、详解请求数据处理过程

1、示例 1)演示 2)上传图片 3)显示图片 2、源码 示例源码Demo1->FileUploadController void FileUploadController::service(HttpRequest& request, HttpResponse& response)

快速幂算法在Java中的应用

引言&#xff1a; 在计算机科学和算法领域中&#xff0c;快速幂算法是一种用于高效计算幂运算的技术。在实际编程中&#xff0c;特别是在处理大数幂运算时&#xff0c;快速幂算法能够显著提高计算效率。本文将介绍如何在Java中实现快速幂算法&#xff0c;并给出一些示例代码和应…

Kubernetes 知识体系 系列一

多年前&#xff0c;大多数软件应用程序都是大型的单体&#xff0c;要么作为单个进程运行&#xff0c;要么作为少数服务器上的少量进程运行。这种过时的系统一直延续很久。 它们的发布周期较慢&#xff0c;更新相对较少。 在每个发布周期结束时&#xff0c;开发人员将整个系统…

2024最新华为OD机试试题库全 -【二叉树计算】- C卷

1. 🌈题目详情 1.1 ⚠️题目 给出一个二叉树如下图所示: 请由该二叉树生成一个新的二叉树,它满足其树中的每个节点将包含原始树中的左子树和右子树的和。 左子树表示该节点左侧叶子节点为根节点的一颗新树;右子树表示该节点右侧叶子节点为根节点的一颗新树。 1.2 �…