OpenHarmony:如何使用HDF驱动控制LED灯

一、程序简介

该程序是基于OpenHarmony标准系统编写的基础外设类:RGB LED。

目前已在凌蒙派-RK3568开发板跑通。详细资料请参考官网:https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk3568-openharmony/tree/master/samples/b02_hdf_rgb_led。

详细资料请参考OpenHarmony官网:

  • GPIO平台驱动开发
  • GPIO应用程序开发

二、硬件设计

RGB LED灯整体硬件电路如下图所示,硬件电路中包含了三个GPIO控制管脚控制RGB LED灯,低电平点亮LED灯,高电平熄灭LED灯。电路简单,这边不对此进行多余的说明。

三、程序解析

1、目录结构

b02_hdf_rgb_led
├── config              # HDF资源配置文件目录├── config.hcs      # 接口IO配置文件├── device_info.hcs # 设备信息配置文件
├── drivers             # 内核HDF驱动程序目录├── rgb_led_drv.c   # 内核HDF驱动程序├── Makefile        # 内核HDF驱动编译脚本
├── figures             # MD文档图片
├── BUILD.gn            # GN文件
├── rgb_led.c           # 应用层控制程序

2、内核HDF驱动程序

(1)接口函数

  • 函数名:HdfRgbLedDriverInit.
  • 功能说明:HDF初始化注册,读取HDF资源配置文件,获取三色灯控制GPIO管脚。
int32_t HdfRgbLedDriverInit(struct HdfDeviceObject *deviceObject)
{if (deviceObject == NULL) {HDF_LOGE("g_rgbLedDriverEntry: %s failed", __func__);return HDF_ERR_INVALID_OBJECT;}struct DeviceResourceIface *CfgOps = NULL;CfgOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);if (CfgOps == NULL || CfgOps->GetUint32 == NULL) {HDF_LOGE("%s: DeviceResourceGetIfaceInstance failed", __func__);return HDF_FAILURE;}if (CfgOps->GetUint32(deviceObject->property, "rgb_led_version", &g_rgbLedCfg.rgb_led_version, 0) != HDF_SUCCESS) {HDF_LOGE("%s: read rgb_led_version failed", __func__);return HDF_FAILURE;}if (CfgOps->GetUint32(deviceObject->property, "rgb_led_red", &g_rgbLedCfg.rgb_led_red, 0) != HDF_SUCCESS) {g_rgbLedCfg.rgb_led_version = 0;HDF_LOGE("%s: read rgb_led_red failed", __func__);return HDF_FAILURE;}if (CfgOps->GetUint32(deviceObject->property, "rgb_led_green", &g_rgbLedCfg.rgb_led_green, 0) != HDF_SUCCESS) {g_rgbLedCfg.rgb_led_version = 0;HDF_LOGE("%s: read rgb_led_green failed", __func__);return HDF_FAILURE;}if (CfgOps->GetUint32(deviceObject->property, "rgb_led_blue", &g_rgbLedCfg.rgb_led_blue, 0) != HDF_SUCCESS) {g_rgbLedCfg.rgb_led_version = 0;HDF_LOGE("%s: read rgb_led_blue failed", __func__);return HDF_FAILURE;}HDF_LOGI("g_rgbLedDriverEntry: %s success", __func__);return HDF_SUCCESS;
}
  • 函数名:HdfRgbLedDriverRelease。
  • 功能说明:HDF去注册。
void HdfRgbLedDriverRelease(struct HdfDeviceObject *deviceObject)
{if (deviceObject == NULL) {HDF_LOGE("g_rgbLedDriverEntry: %s failed", __func__);return;}HDF_LOGI("g_rgbLedDriverEntry: %s success", __func__);return;
}
  • 函数名:HdfRgbLedDriverBind。
  • 功能说明:HDF绑定解析函数。
int32_t HdfRgbLedDriverBind(struct HdfDeviceObject *deviceObject)
{if (deviceObject == NULL) {HDF_LOGE("g_rgbLedDriverEntry: %s failed", __func__);return HDF_ERR_INVALID_OBJECT;}static struct IDeviceIoService ledDriverServ = {.Dispatch = rgbLedDriverDispatch,};deviceObject->service = (struct IDeviceIoService *)(&ledDriverServ);HDF_LOGI("g_rgbLedDriverEntry: %s success NodeName[%s]", __func__,deviceObject->property->name);return HDF_SUCCESS;
}
  • 函数名:rgbLedDriverDispatch。
  • 功能说明:解析函数,解析应用层下发的命令,执行命令对应操作,RGB_LED_WRITE控制三色灯亮灭。
int32_t rgbLedDriverDispatch(struct HdfDeviceIoClient *client, int32_t cmdId,struct HdfSBuf *dataBuf, struct HdfSBuf *replyBuf)
{int32_t result = HDF_FAILURE;int32_t rgbLedMode = 0;if (client == NULL || client->device == NULL) {HDF_LOGE("driver device is NULL");return HDF_ERR_INVALID_OBJECT;}if (g_rgbLedCfg.rgb_led_version != RGB_LED_VERSION) {HDF_LOGE("driver rgb_led_version not match");return HDF_FAILURE;}switch (cmdId) {case RGB_LED_WRITE:result = HdfSbufReadInt32(dataBuf, &rgbLedMode);if (result) {HDF_LOGI("%s: mode:[0x%X][%s%s%s]", __func__, rgbLedMode,(rgbLedMode&RGB_LED_RED_BIT)?"R":"-",(rgbLedMode&RGB_LED_GREEN_BIT)?"G":"-",(rgbLedMode&RGB_LED_BLUE_BIT)?"B":"-");LedGpioCtrl(g_rgbLedCfg.rgb_led_red, (rgbLedMode&RGB_LED_RED_BIT)?LED_ON:LED_OFF);LedGpioCtrl(g_rgbLedCfg.rgb_led_green, (rgbLedMode&RGB_LED_GREEN_BIT)?LED_ON:LED_OFF);LedGpioCtrl(g_rgbLedCfg.rgb_led_blue, (rgbLedMode&RGB_LED_BLUE_BIT)?LED_ON:LED_OFF);}break;default:HDF_LOGE("%s: receiving unknown command", __func__);break;}return result;
}
  • 函数名:LedGpioCtrl。
  • 功能说明:LED GPIO控制函数,低电平点亮LED,高电平熄灭LED。
static int32_t LedGpioCtrl(uint16_t gpio, int32_t mode)
{uint16_t level = GPIO_VAL_HIGH;if (HDF_SUCCESS != GpioSetDir(gpio, GPIO_DIR_OUT)) {HDF_LOGE("%s: GpioSetDir failed", __func__);return HDF_FAILURE;}if (mode == LED_ON) {level = GPIO_VAL_LOW;} else if (mode == LED_OFF) {level = GPIO_VAL_HIGH;}if (HDF_SUCCESS != GpioWrite(gpio, level)) {HDF_LOGE("%s: GpioWrite failed", __func__);return HDF_FAILURE;}return HDF_SUCCESS;
}

3、应用层程序

(1)应用层代码分析

程序启动后获取命令行参数,如果命令行不带参数,RGB三色灯运行跑马灯;如果命令行带参数,根据传入的参数的低三位映射点亮对应的红灯、绿灯和蓝灯;通过HdfIoServiceBind绑定RGB三色灯HDF服务,获取HDF空间缓冲区,向缓冲区写入需要控制的RGB三色灯低三位数据,通过RGB_LED_WRITE命令下发到HDF驱动中,从而控制RGB三色灯亮灭。程序运行结束,回收HDF空间缓冲区和HDF服务。

int main(int argc, char* argv[])
{int ret = HDF_SUCCESS;int32_t mode = -1;if (argc == ARGS_NUM) {mode = atoi(argv[1]);/*low-3bits*/mode &= 0x7;HILOG_INFO(LOG_APP, "[%s] main enter: mode[%s%s%s][0x%X]",LOG_TAG,(mode&RGB_LED_BLUE_BIT)?"B":"-",(mode&RGB_LED_GREEN_BIT)?"G":"-",(mode&RGB_LED_RED_BIT)?"R":"-",mode);printf("RGB mode[%s%s%s][0x%X]\n",(mode&RGB_LED_BLUE_BIT)?"B":"-",(mode&RGB_LED_GREEN_BIT)?"G":"-",(mode&RGB_LED_RED_BIT)?"R":"-",mode);} else {HILOG_INFO(LOG_APP, "[%s] main enter: auto test RGB LED", LOG_TAG);printf("auto test RGB LED\n");}struct HdfIoService *serv = HdfIoServiceBind(RGB_LED_SERVICE_NAME);if (serv == NULL) {HILOG_ERROR(LOG_APP, "get service %s failed", RGB_LED_SERVICE_NAME);return -1;}struct HdfSBuf *data = HdfSbufObtainDefaultSize();if (data == NULL) {HILOG_ERROR(LOG_APP, "obtain data failed");return -1;}if (mode == -1) {mode = 0x8;while (mode) {HdfSbufFlush(data);if (!HdfSbufWriteInt32(data, --mode)) {HILOG_ERROR(LOG_APP, "write data failed");return -1;}ret = serv->dispatcher->Dispatch(&serv->object, RGB_LED_WRITE, data, NULL);sleep(1);}} else {if (!HdfSbufWriteInt32(data, mode)) {HILOG_ERROR(LOG_APP, "write data failed");return -1;}ret = serv->dispatcher->Dispatch(&serv->object, RGB_LED_WRITE, data, NULL);}HdfSbufRecycle(data);HdfIoServiceRecycle(serv);HILOG_INFO(LOG_APP, "[%s] main exit.", LOG_TAG);return ret;
}

四、运行程序

系统启动后,命令行运行命令:

rgb_led

五、运行结果

运行结果:

# rgb_led
auto test RGB LED# rgb_led 1
RGB mode[--R][0x1]
# rgb_led 2
RGB mode[-G-][0x2]
# rgb_led 3
RGB mode[-GR][0x3]
# rgb_led 4
RGB mode[B--][0x4]
# rgb_led 5
RGB mode[B-R][0x5]
# rgb_led 6
RGB mode[BG-][0x6]
# rgb_led 7
RGB mode[BGR][0x7]

最后,推荐一款应用开发神器

扯个嗓子!关于目前低代码在技术领域很活跃!

低代码是什么?一组数字技术工具平台,能基于图形化拖拽、参数化配置等更为高效的方式,实现快速构建、数据编排、连接生态、中台服务等。通过少量代码或不用代码实现数字化转型中的场景应用创新。它能缓解甚至解决庞大的市场需求与传统的开发生产力引发的供需关系矛盾问题,是数字化转型过程中降本增效趋势下的产物。

这边介绍一款好用的低代码平台——JNPF快速开发平台。近年在市场表现和产品竞争力方面表现较为突出,采的是最新主流前后分离框架(SpringBoot+Mybatis-plus+Ant-Design+Vue3。代码生成器依赖性低,灵活的扩展能力,可灵活实现二次开发。

以JNPF为代表的企业级低代码平台为了支撑更高技术要求的应用开发,从数据库建模、Web API构建到页面设计,与传统软件开发几乎没有差异,只是通过低代码可视化模式,减少了构建“增删改查”功能的重复劳动,还没有了解过低代码的伙伴可以尝试了解一下。

应用:https://www.jnpfsoft.com/?csdn

有了它,开发人员在开发过程中就可以轻松上手,充分利用传统开发模式下积累的经验。所以低代码平台对于程序员来说,有着很大帮助。

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

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

相关文章

C++ 判断

C 判断 判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。 下面是大多数编程语言中典型的判断结构的一般形式: 判断语句 C 编…

SpringMVC之前端增删改查实现

SpringMVC是一个基于MVC架构的框架&#xff0c;它可以帮助我们实现前后端的分离&#xff0c;同时也能很好地支持前端的增删改查操作。 配置 Cloudjun <?xml version"1.0" encoding"UTF-8" ?><taglib xmlns"http://java.sun.com/xml/ns/j…

TSINGSEE青犀/视频分析/边缘计算/AI算法·人员/区域入侵功能——多场景高效运用

TSINGSEE青犀视频人员/区域入侵功能可对重要区域进行实时监测&#xff0c;对监控区域进行7*24全天候管控&#xff0c;当监测到有人员靠近、闯入时&#xff0c;AI算法后台就会立即发出告警及时通知管理人员&#xff0c;变被动“监督”为主动“监控”&#xff0c;真正做到事前预警…

2023计算机毕业设计题目 毕设选题大全

文章目录 0 前言1 java web 管理系统 毕设选题2 java web 平台/业务系统 毕设选题3 游戏设计、动画设计类 毕设选题 (适合数媒的同学)4 算法开发5 数据挖掘 毕设选题6 大数据处理、云计算、区块链 毕设选题7 网络安全 毕设选题8 通信类/网络工程 毕设选题9 嵌入式 毕设选题10 开…

Newman+Jenkins实现接口自动化测试

一、是什么Newman Newman就是纽曼手机这个经典牌子&#xff0c;哈哈&#xff0c;开玩笑啦。。。别当真&#xff0c;简单地说Newman就是命令行版的Postman&#xff0c;查看官网地址。 Newman可以使用Postman导出的collection文件直接在命令行运行&#xff0c;把Postman界面化运…

leetcode127单词接龙刷题打卡

127. 单词接龙 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk&#xff1a; 每一对相邻的单词只差一个字母。对于 1 < i < k 时&#xff0c;每个 si 都在 wordList 中。注意&am…

边缘计算物联网网关在机械加工行业中的效用分享

随着工业4.0的推进&#xff0c;物联网技术正在逐渐渗透到各个行业领域。机械加工行业作为制造业的基础领域之一&#xff0c;其生产过程的自动化、智能化水平直接影响到产品质量和生产效率。边缘计算物联网网关作为物联网技术的重要组成部分&#xff0c;在机械加工行业中发挥着越…

代码随想录算法训练营19期第46天

139.单词拆分 视频讲解&#xff1a;动态规划之完全背包&#xff0c;你的背包如何装满&#xff1f;| LeetCode&#xff1a;139.单词拆分_哔哩哔哩_bilibili 代码随想录 初步思路&#xff1a;动态规划。 总结&#xff1a; 单词就是物品&#xff0c;字符串s就是背包&#xff…

uniapp项目实践总结(十三)封装文件操作方法

导语&#xff1a;在日常 APP 开发过程中&#xff0c;经常要进行文件的保存、读取列表以及查看和删除文件等操作&#xff0c;接下来就看一下具体的方法。 目录 原理分析方法实现实战演练案例展示 原理分析 主要是以下 API。 uni.saveFile&#xff1a;保存文件到本地缓存列表…

小白备战大厂算法笔试(四)——哈希表

文章目录 哈希表常用操作简单实现冲突与扩容链式地址开放寻址线性探测多次哈希 哈希表 哈希表&#xff0c;又称散列表&#xff0c;其通过建立键 key 与值 value 之间的映射&#xff0c;实现高效的元素查询。具体而言&#xff0c;我们向哈希表输入一个键 key &#xff0c;则可以…

Github Copilot连接不上服务器

现象 报错&#xff1a;[ERROR] [default] [2023-09-08T15:47:01.542Z] GitHub Copilot could not connect to server. Extension activation failed: “connect ETIMEDOUT 20.205.243.168:443” 原因 DNS解析api.github.com的地址到20.205.243.168&#xff0c;但实际上这个地…

K210-CanMV IDE开发软件

K210-CanMV IDE开发软件 界面功能简介连接设备临时运行开机运行程序 界面功能简介 区域①菜单栏&#xff1a;操作文件&#xff0c;使用工具等。 区域②快捷按钮&#xff1a;区域①中的文件和编辑中部分功能的快捷方式。 区域③连接设备&#xff1a;连接设备和程序控制按钮。 …

云计算 入门名词

SDN (Software Defined Network),软件定义网络&#xff0c;是Emulex网络一种新型网络创新架构&#xff0c;是网络虚拟化的一种实现方式。 VDC&#xff08;Virtual Date Center,&#xff09;,虚拟数据中心。VDC是将云计算概念运用于数据中心的一种新型的数据中心的形态。VDC可以…

2023-9-8 求组合数(二)

题目链接&#xff1a;求组合数 II #include <iostream> #include <algorithm>using namespace std;typedef long long LL; const int mod 1e9 7; const int N 100010;// 阶乘&#xff0c;阶乘的逆 int fact[N], infact[N];LL qmi(int a, int k, int p) {int res…

基于单片机压力传感器MPX4115检测-报警系统-proteus仿真-源程序

一、系统方案 本设计采用52单片机作为主控器&#xff0c;液晶1602显示&#xff0c;MPX4115检测压力&#xff0c;按键设置报警&#xff0c;LED报警。 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 /***************************************…

2023年高教社杯全国大学生数学建模竞赛-【比赛规则篇】比赛规则及比赛指导

目录 前言 前辈分享的国赛获奖经验 多看历年的竞赛题 集训时长 模拟题量

分布式秒杀方案--java

前提&#xff1a;先把商品详情和秒杀商品缓存redis中&#xff0c;减少对数据库的访问&#xff08;可使用定时任务&#xff09; 秒杀商品无非就是那几步&#xff08;前面还可能会有一些判断&#xff0c;如用户是否登录&#xff0c;一人一单&#xff0c;秒杀时间验证等&#xff0…

多线程中的忙循环是什么?

多线程中的忙循环&#xff08;Busy-Wait&#xff09;是一种同步机制&#xff0c;它通常用于等待某个条件满足的情况下&#xff0c;不断地检查条件是否已经满足&#xff0c;而不是通过休眠或阻塞线程来等待条件满足。在忙循环中&#xff0c;线程会反复执行一段代码&#xff0c;通…

OpenCV 03(数据结构--Mat)

一、Mat介绍 Mat是OpenCV在C语言中用来表示图像数据的一种数据结构.在python中转化为numpy的ndarray. Mat由header和data组成, header中记录了图片的维数, 大小, 数据类型等数据. 1.1 Mat拷贝 - Mat共享数据 在python中Mat数据对应numpy的ndarray, 使用numpy提供的深浅拷贝方…

C++——类与对象(下篇)

前言 前面已经介绍了类与对象&#xff08;上&#xff09;&#xff0c;类与对象&#xff08;中&#xff09;的两篇文章&#xff0c;下面是类与对象的最后一些重要知识点的介绍和总结。 目录 再谈构造函数Static成员友元内部类匿名对象拷贝对象时的一些编译器优化再次理解封装…