OpenHarmony-4.GPIO驱动

  • GPIO

1.功能简介

  GPIO(General-purpose input/output)即通用型输入输出。GPIO又俗称为I/O口,I指的是输入(in),O指的是输出(out)。可以通过软件来控制其输入和输出,即I/O控制。通常,GPIO控制器通过分组的方式管理所有GPIO管脚,每组GPIO有一个或多个寄存器与之关联,通过读写寄存器完成对GPIO管脚的操作。

  • GPIO输入

    输入是检测各个引脚上的电平状态,高电平或者低电平状态。常见的输入模式有:模拟输入、浮空输入、上拉输入、下拉输入。

  • GPIO输出

    输出是当需要控制引脚电平的高低时需要用到输出功能。常见的输出模式有:开漏输出、推挽输出、复用开漏输出、复用推挽输出。

  GPIO接口定义了操作GPIO管脚的标准方法集合,包括:

  • 设置、获取管脚方向:方向可以是输入或者输出(暂不支持高阻态)。

  • 读、写管脚电平值:电平值可以是低电平或高电平。

  • 设置、取消管脚中断服务函数:设置一个管脚的中断响应函数,以及中断触发方式。取消一个管脚的中断服务函数。

  • 使能、禁止管脚中断:禁止或使能管脚中断。

1.1.运作机制

  在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),若采用独立服务模式,则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。GPIO模块接口适配模式采用统一服务模式:
在这里插入图片描述
  在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。

  GPIO模块各分层作用:

  • 接口层提供操作GPIO管脚的标准方法。

  • 核心层主要提供GPIO管脚资源匹配,GPIO管脚控制器的添加、移除以及管理的能力,通过钩子函数与适配层交互,供芯片厂家快速接入HDF框架。

  • 适配层主要是将钩子函数的功能实例化,实现具体的功能。

1.2.接口层

  GPIO模块提供的主要接口:

  • drivers/hdf_core/framework/include/platform/gpio_if.h

在这里插入图片描述

  以gpio_stm32f4xx为例:

GpioRead-> GpioCntlrRead-> cntlr->ops->read 调用哪里?-> LL_GPIO_ReadInputPin

  GpioRead代码分析:

drivers_hdf_core/framework/support/platform/src/gpio/gpio_if.c
int32_t GpioRead(uint16_t gpio, uint16_t *val)
{int32_t ret;struct GpioCntlr *cntlr = GpioCntlrGetByGpio(gpio);ret = GpioCntlrRead(cntlr, GpioCntlrGetLocal(cntlr, gpio), val);GpioCntlrPut(cntlr);return ret;
}drivers_hdf_core/framework/support/platform/src/gpio/gpio_core.c:
int32_t GpioCntlrRead(struct GpioCntlr *cntlr, uint16_t local, uint16_t *val)
{...return cntlr->ops->read(cntlr, local, val);  //调用注册的gpio_stm32f4xx控制器ops接口对应的read函数,即g_GpioCntlrMethod->GpioDevRead
}

  gpio_stm32f4xx驱动:

  • drivers_hdf_core/adapter/platform/gpio/gpio_stm32f4xx.c
struct HdfDriverEntry g_GpioDriverEntry = {.moduleVersion = 1,.moduleName = "ST_GPIO_MODULE_HDF",.Init = GpioDriverInit,.Release = GpioDriverRelease,
};
HDF_INIT(g_GpioDriverEntry);static int32_t GpioDriverInit(struct HdfDeviceObject *device)
{int32_t ret;struct GpioCntlr *gpioCntlr = NULL;ret = PlatformDeviceBind(&g_stmGpioCntlr.device, device);gpioCntlr = GpioCntlrFromHdfDev(device);ret = AttachGpioDevice(gpioCntlr, device); /* GpioCntlr add GpioDevice to priv */gpioCntlr->ops = &g_GpioCntlrMethod;  //注册的ops接口ret = GpioCntlrAdd(gpioCntlr);return HDF_SUCCESS;
}/* GpioMethod definitions */
struct GpioMethod g_GpioCntlrMethod = {.request = NULL,.release = NULL,.write = GpioDevWrite,.read = GpioDevRead,.setDir = GpioDevSetDir,.getDir = GpioDevGetDir,.toIrq = NULL,.setIrq = GpioDevSetIrq,.unsetIrq = GpioDevUnSetIrq,.enableIrq = GpioDevEnableIrq,.disableIrq = GpioDevDisableIrq,
};static int32_t GpioDevRead(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *val)
{(void)cntlr;uint16_t realPin = g_gpioPinsMap[gpio].realPin;uint32_t pinReg = g_stmRealPinMaps[realPin];uint16_t value = 0;GPIO_TypeDef* gpiox = g_gpioxMaps[g_gpioPinsMap[gpio].group];value = LL_GPIO_ReadInputPin(gpiox, pinReg);  //调用ll库对应的函数接口*val = value;return HDF_SUCCESS;
}

1.3.核心层

  • drivers_hdf_core/adapter/platform/gpio/gpio_stm32f4xx.c

  gpio_stm32f4xx驱动初始化:

struct HdfDriverEntry g_GpioDriverEntry = {.moduleVersion = 1,.moduleName = "ST_GPIO_MODULE_HDF",.Init = GpioDriverInit,.Release = GpioDriverRelease,
};
HDF_INIT(g_GpioDriverEntry);static struct GpioCntlr g_stmGpioCntlr;
static int32_t GpioDriverInit(struct HdfDeviceObject *device)
{int32_t ret;struct GpioCntlr *gpioCntlr = NULL;ret = PlatformDeviceBind(&g_stmGpioCntlr.device, device);gpioCntlr = GpioCntlrFromHdfDev(device);ret = AttachGpioDevice(gpioCntlr, device); /* GpioCntlr add GpioDevice to priv */gpioCntlr->ops = &g_GpioCntlrMethod; /* register callback */ret = GpioCntlrAdd(gpioCntlr);return HDF_SUCCESS;
}

  GpioDriverInit 函数主要工作:

  • 绑定GpioCntlr和HdfDeviceObject;
  • 调用GpioCntlrAdd将gpioCntlr 注册到PlatformManager进行管理。
    GpioCntlrAdd -> PlatformDeviceAdd->PlatformManagerAddDevice

1.4.开发步骤

  GPIO标准API通过GPIO管脚号来操作指定管脚,使用GPIO的一般流程如图所示。

图 2 GPIO使用流程图
1.3.1.确定GPIO管脚号

  两种方式获取管脚号:

  • 根据SOC芯片规则进行计算、通过管脚别名获取
    不同SOC芯片由于其GPIO控制器型号、参数、以及控制器驱动的不同,GPIO管脚号的换算方式不一样。
  • 通过管脚别名获取
    调用接口GpioGetByName进行获取,入参是该管脚的别名,接口返回值是管脚的全局ID。

1.3.2.设置GPIO管脚中断

  为一个GPIO管脚设置中断响应程序,使用如下函数:

int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg);

  以hdf_key 驱动为例:

SetupKeyIrq->GpioSetIrq
drivers_hdf_core/framework/model/input/driver/hdf_key.c:
static int32_t KeyInit(KeyDriver *keyDrv)
{int32_t ret = SetupKeyIrq(keyDrv);CHECK_RETURN_VALUE(ret);return HDF_SUCCESS;
}static int32_t SetupKeyIrq(KeyDriver *keyDrv)
{uint16_t intGpioNum = keyDrv->keyCfg->gpioNum;uint16_t irqFlag = keyDrv->keyCfg->irqFlag;int32_t ret = GpioSetDir(intGpioNum, GPIO_DIR_IN);ret = GpioSetIrq(intGpioNum, irqFlag | GPIO_IRQ_USING_THREAD, KeyIrqHandle, keyDrv);ret = GpioEnableIrq(intGpioNum);return HDF_SUCCESS;
}

GpioSetIrq 函数调用:

GpioSetIrq -> GpioCntlrSetIrq-> GpioIrqRecordCreate-> cntlr->ops->setIrq-> GpioDevSetIrq  //gpio_stm32f4xx.c

代码实现:

drivers_hdf_core/framework/support/platform/src/gpio/gpio_if.c
int32_t GpioSetIrq(uint16_t gpio, uint16_t mode, GpioIrqFunc func, void *arg)
{int32_t ret;struct GpioCntlr *cntlr = GpioCntlrGetByGpio(gpio);ret = GpioCntlrSetIrq(cntlr, GpioCntlrGetLocal(cntlr, gpio), mode, func, arg);GpioCntlrPut(cntlr);return ret;
}int32_t GpioCntlrSetIrq(struct GpioCntlr *cntlr, uint16_t local, uint16_t mode, GpioIrqFunc func, void *arg)
{int32_t ret;struct GpioInfo *ginfo = NULL;struct GpioIrqRecord *irqRecord = NULL;ginfo = &cntlr->ginfos[local];ret = GpioIrqRecordCreate(ginfo, mode, func, arg, &irqRecord);ret = GpioCntlrSetIrqInner(ginfo, irqRecord);return ret;
}static int32_t GpioCntlrSetIrqInner(struct GpioInfo *ginfo, struct GpioIrqRecord *irqRecord)
{int32_t ret;uint16_t local = GpioInfoToLocal(ginfo);struct GpioCntlr *cntlr = ginfo->cntlr;...ginfo->irqRecord = irqRecord;ret = cntlr->ops->setIrq(cntlr, local, irqRecord->mode);return ret;
}drivers_hdf_core/adapter/platform/gpio/gpio_stm32f4xx.c
struct GpioMethod g_GpioCntlrMethod = {....setIrq = GpioDevSetIrq,...
};static int32_t GpioDevSetIrq(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t mode)
{(void)cntlr;uint16_t realPin = g_gpioPinsMap[gpio].realPin;uint32_t pinReg = g_stmRealPinMaps[realPin];if (mode == OSAL_IRQF_TRIGGER_RISING) {g_gpioExitCfg[gpio].trigger = LL_EXTI_TRIGGER_RISING;} else if (mode == OSAL_IRQF_TRIGGER_FALLING) {g_gpioExitCfg[gpio].trigger = LL_EXTI_TRIGGER_FALLING;} else {HDF_LOGE("%s %d, error mode:%d", __func__, __LINE__, mode);return HDF_ERR_NOT_SUPPORT;}return HDF_SUCCESS;
}

refer to

  • git clone https://gitee.com/openharmony/drivers_hdf_core.git
  • http://docs.openharmony.cn/pages/v4.1/zh-cn/device-dev/driver/driver-platform-gpio-des.md/

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

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

相关文章

leetcode 1843 可疑银行账户(postgresql)

需求 表: Accounts -------------------- | Column Name | Type | -------------------- | account_id | int | | max_income | int | -------------------- account_id 是表主键。 每行包含一个银行账户每月最大收入的信息。 表: Transactions ------------------------ |…

【开源代码】图像水印移除-依赖python-tensorflow

下载源码 git clone https://github.com/zuruoke/watermark-removal创建conda环境 conda create -n tensorflow_gpu python=3.7 conda activate tensorflow_gpu conda install tensorflow-gpu==1.15

PyQt信号槽实现页面的登录与跳转 #页面进一步优化

将登录框中的取消按钮使用信号和槽的机制,关闭界面。 将登录按钮使用信号和槽连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否为"admin",密码是否为"123456",如果账号密码匹配成功,当前界面关…

自动化立体仓库项目任务调度系统中任务流程可视化实现

在运维自动化平台中,任务系统无疑是最核心的组成部分之一。它承担着所有打包编译、项目上线、日常维护等运维任务的执行。通过任务系统,我们能够灵活地构建满足不同需求的自定义任务流。早期的任务流后端采用了类似列表的存储结构,根据任务流内子任务的排序依次执行,尽管通…

WEB安全 PHP学习

PHP基础 PHP编码显示问题 header ("Content-type: text/html; charsetgb2312"); header("Content-Type: text/html;charsetutf-8"); windows需要使用gbk编码显示 源码是 <?php header ("Content-type: text/html; charsetgb2312"); sys…

11.爬虫

前言&#xff1a; 正则表达式的作用&#xff1a; 作用一&#xff1a;校验字符串是否满足规则 作用二&#xff1a;在一段文本中查找满足要求的内容 一.Pattern类和Matcher类&#xff1a; 1.Pattern类&#xff1a;表示正则表达式 a.因此获取Pattern对象就相当于获取正则表达式…

Visual Studio 2022 项目配置常用选项

作为一名C++开发者,经常需要配置第三方库,今天来跟大家截图一下,方便大家快速配置: 头文件包含目录: 或者: 库文件包含目录:

如何搭建JMeter分布式集群环境来进行性能测试

在性能测试中&#xff0c;当面对海量用户请求的压力测试时&#xff0c;单机模式的JMeter往往力不从心。如何通过分布式集群环境&#xff0c;充分发挥JMeter的性能测试能力&#xff1f;这正是许多测试工程师在面临高并发、海量数据时最关注的问题。那么&#xff0c;如何轻松搭建…

WebRover :一个功能强大的 Python 库,用于从 Web 内容生成高质量的数据集,专为训练大型语言模型和 AI 应用程序而设计。

2024-11-30 &#xff0c;由Area-25团队开发的一个专门用于生成高质量网络内容数据集的Python库。该数据集旨在为大型语言模型&#xff08;LLM&#xff09;和人工智能应用的训练提供丰富的数据资源。 数据集地址&#xff1a;WebRover Dataset|自然语言处理数据集|AI模型训练数据…

计算机毕业设计hadoop+spark民宿推荐系统 民宿数据分析可视化大屏 民宿爬虫 民宿大数据 知识图谱 机器学习 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

云原生数据库 PolarDB

PolarDB 是阿里云推出的一款云原生数据库&#xff0c;旨在为企业提供高性能、高可靠性的数据库解决方案。它基于云计算环境设计&#xff0c;特别适用于云上的大规模数据处理和存储需求。PolarDB 是一种兼具关系型数据库&#xff08;RDS&#xff09;和分布式数据库特性的新型数据…

zookeeper在确认config无误后仍处于standalone模式的解决方法

jps查看是否有QuorumPeerMain进程 停止服务后该进程仍然存在&#xff0c;输入&#xff1a; ps -ef | grep QuorumPeerMain | grep -v grep | awk {print $2} | xargs kill 之后再启动一次进程 bin/zkServer.sh start 查看状态 bin/zkServer.sh status 发现报错解决&#…

mac中全局 flutter fvm 控制版本遇到的不生效问题解决

1、下载 dart pub global activate fvm 或者 brew tap leoafarias/fvmbrew install fvm fvm use 3.22.1 上面的每次运行都需要加fvm flutter 我觉得麻烦 我期望的是修改全局的 那么就需要使用到fvm global 命令 如&#xff1a; fvm global 3.24.0 但是我发现flutter --vers…

eltable el-table 横向 滚动条常显

又遇到了难受的问题&#xff0c;el-table嵌入在一个div里面&#xff0c;结果因为内容太多,横向、纵向我都得滚动查看&#xff01; 结果发现横向滚动时只能让它纵向触底后才能进行横向操作&#xff0c;这就很变态&#xff0c;明显不符合用户操作习惯。如下图&#xff1a; 要先纵…

【webApp之h5端实战】项目基础结构搭建及欢迎页面的实现

这是一个实战项目的webapp,主要是使用原生js/css/html来实现我们的业务。预览下面的实战效果,我们将会从0到1实现这个系列的项目。包括大量的原生js知识,css3动画的开发,以及页面的交互实现。 效果预览 项目准备工作 封装的工具类,用于获取原生dom节点,处理原生dom事件的…

【AI模型对比】Kimi与ChatGPT的差距:真实对比它们在六大题型中的全面表现!

文章目录 Moss前沿AI语义理解文学知识数学计算天文学知识物理学知识英语阅读理解详细对比列表总结与建议 Moss前沿AI 【OpenAI】获取OpenAI API Key的多种方式全攻略&#xff1a;从入门到精通&#xff0c;再到详解教程&#xff01;&#xff01; 【VScode】VSCode中的智能AI-G…

[go-redis]客户端的创建与配置说明

创建redis client 使用go-redis库进行创建redis客户端比较简单&#xff0c;只需要调用redis.NewClient接口创建一个客户端 redis.NewClient(&redis.Options{Addr: "127.0.0.1:6379",Password: "",DB: 0, })NewClient接口只接收一个参数red…

图形开发基础之在WinForms中使用OpenTK.GLControl进行图形绘制

前言 GLControl 是 OpenTK 库中一个重要的控件&#xff0c;专门用于在 Windows Forms 应用程序中集成 OpenGL 图形渲染。通过 GLControl&#xff0c;可以轻松地将 OpenGL 的高性能图形绘制功能嵌入到传统的桌面应用程序中。 1. GLControl 的核心功能 OpenGL 渲染上下文&…

shell编程7,bash解释器的 for循环+while循环

声明&#xff01; 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&#…

【Java-数据结构篇】Java 中栈和队列:构建程序逻辑的关键数据结构基石

我的个人主页 我的专栏&#xff1a;Java-数据结构&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01;点赞❤ 收藏❤ 一、引言 1. 栈与队列在编程中的角色定位 栈和队列作为两种基本的数据结构&#xff0c;在众多编程场景中都有着独特的地位。它们为数据的有序…