Openharmony的用户态应用通过HDF框架驱动消息机制实现的通信实例

news/2025/2/12 23:43:34/

承接上文一个例子了解通过Openharmony的HDF框架实现简易驱动的流程,实现到了test_hdf_newdevice1设备的驱动。应用或服务如何与此设备通过HDF的框架的驱动消息机制,进行通信?

依旧以Openharmony中的V3.1 版本为基座,编写测试代码来进行分析说明。

HDF框架提供统一的驱动消息机制,支持用户应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息。

一、用户态应用测试程序

可以通过创建一个应用程序或动态库.so或静态库.a来与内核的驱动程序进行通信。这里简单以一个应用程序为例进行演示。

创建用户态应用测试程序步骤如下:

  • 创建项目:

  • 新建源文件:

  • 添加编译配置:

  • 编译烧录:

1.1 新建源文件test.c

  • 通过驱动对外发布服务的名称(test_hdf_newdevice1)获取驱动的服务对象。

// test.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <core/hdf_io_service_if.h>
#include "hdf_sbuf.h"
#include "osal_time.h"
#include "hilog/log.h"
...
int main(int arg, char **argv)
{struct HdfIoService *serv = HdfIoServiceBind("test_hdf_newdevice1");if (serv == NULL) {printf("get service fail!\n");return -1;}return 0;
}
  • 注册事件监听对象HdfDevEventlistener

// test.c
...
#define TEST_WRITE_DATA 1234
static int OnDevEventReceive(struct HdfDevEventlistener *listener,struct HdfIoService *service, uint32_t id, struct HdfSBuf *data)
{printf("enter %d, service address is %p, event cmdId is %d\n",__func__, service, id);return 0;
}static struct HdfDevEventlistener listener = {.onReceive = OnDevEventReceive
}int main(int arg, char **argv)
{
...if (HdfDeviceRegisterEventListener(serv, &listener) != 0) {printf("register event listener fail!\n");}
...
}
  • 准备写入的数据与读出数据

// test.c
...
int main(int arg, char **argv)
{
...struct HdfSBuf *data = HdfSbufObtainDefaultSize();if (data == NULL) {printf("fail to obtain sbuf data!\n");return -1;}struct HdfSBuf *reply = HdfSbufObtainDefaultSize();if (reply == NULL) {printf("fail to obtain sbuf reply!\n");HdfSbufRecycle(data);return -1;}// 写入传入的数据if (!HdfSbufWriteString(data, "Send Msg to Driver Message!")) {printf("fail to write sbuf!\n");HdfSbufRecycle(data);HdfSbufRecycle(reply);HdfDeviceUnregisterEventListener(serv, &listener);HdfIoServiceRecycle(serv);return -1;}
...
}
  • 分发消息

...
int main(int arg, char **argv)
{
...if (serv->dispatcher->Dispatch(&service->object, TEST_WRITE_DATA, data, reply) != 0) {printf("fail to send service call!\n");HdfSbufRecycle(data);HdfSbufRecycle(reply);HdfDeviceUnregisterEventListener(serv, &listener);HdfIoServiceRecycle(serv);return -1;}
...
}
  • 读取驱动返回数据

...
int main(int arg, char **argv)
{const char *result = HdfSbufReadString(reply);if (result == NULL) {printf("fail to read result from reply!\n");HdfSbufRecycle(data);HdfSbufRecycle(reply);HdfDeviceUnregisterEventListener(serv, &listener);HdfIoServiceRecycle(serv);  return -1;}printf("read result from driver: %s\n", result);HdfSbufRecycle(data);HdfSbufRecycle(reply);HdfDeviceUnregisterEventListener(serv, &listener);HdfIoServiceRecycle(serv);return 0;
}
...

1.2 添加编译配置BUILD.gn

import("//build/ohos.gni")
import("//drivers/adapter/uhdf2/uhdf.gni")ohos_executable("test_hdf_msg") {sources = ["test.c"]include_dirs = ["//drivers/framework/include","//drivers/framework/include/utils","//drivers/adapter/uhdf2/osal/include","//drivers/framework/include/osal"]deps = ["$hdf_uhdf_path/utils:libhdf_utils",]external_deps = ["device_driver_framework:libhdf_utils","hiviewdfx_hilog_native:libhilog","utils_base:utils"]
}

1.3 编译烧录

./build.sh --product-name rk3568
# 将生成的执行文件test_hdf_msg通过hdc发送开发板执行
# 上一篇中HdfNewdeviceIoServiceDispatch中接收到信息打印如下
# HdfNewdeviceIoServiceDispatch read data is: Send Msg to Driver Message!
# 返回如下信息
# read result from driver: I am driver's reply string!

二、HDF特性

  • HDF驱动加载包括按需加载和按序加载。

  • 按需加载:HDF框架支持驱动在系统启动过程中默认加载,或者在系统启动之后动态加载。

  • 按序加载:HDF框架支持驱动在系统启动的过程中按照驱动的优先级进行加载。

  • HDF框架可以集中管理驱动服务,开发者可直接通过HDF框架对外提供的能力接口获取驱动相关的服务。

  • DF框架提供统一的驱动消息机制,支持用户态应用向内核态驱动发送消息,也支持内核态驱动向用户态应用发送消息。

  • HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。

参考资料

https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/driver/Readme-CN.md


http://www.ppmy.cn/news/22927.html

相关文章

Ajax 原生请求方法

<html> <head> <script type"text/javascript" src"/jquery/jquery.js"></script> <script type"text/javascript"> //创建XMLHttpRequest 对象 //参数&#xff1a;无 //返回值&#xff1a;XMLHttpRequest 对象 f…

AC耦合电容位置对信号的影响

AC耦合电容位置对信号的影响 上期文章说到&#xff0c;电容焊盘对整个无缘通道的影响&#xff0c;仿真观察了焊盘大小&#xff0c;焊盘参考层掏空尺寸&#xff0c;以及具体参考哪一层。 单从焊盘这一点来看&#xff0c;可以看到阻抗一般会比较小&#xff0c;但是对信号未必造…

支付系统核心架构设计思路(万能通用)

文章目录1. 支付系统总览核心系统交互业务图谱2. 核心系统解析交易核心交易核心基础交易类型抽象多表聚合 & 订单关联支付核心支付核心总览支付行为编排异常处理渠道网关资金核算3. 服务治理平台统一上下文数据一致性治理CAS校验幂等 & 异常补偿对账准实时对账DB拆分异…

【C++提高编程】list 容器详解(附测试用例与结果图)

目录1. list容器1.1 list基本概念1.2 list构造函数&#xff08;初始化&#xff09;1.3 list 赋值和交换1.4 list 大小操作1.5 list 插入和删除1.6 list 数据存取1.7 list 反转&#xff08;reverse&#xff09;、排序&#xff08;sort&#xff09;和去重&#xff08;unique&…

PyQt6-QTextEdit学习笔记

一、概述技术PyQt6中QTextEdit控件的基本用法。QTextEdit是一个先进的所见即所得查看器/编辑器&#xff0c;支持使用html风格标签或Markdown格式的富文本格式。它经过优化&#xff0c;可以处理大型文档并快速响应用户输入。QTextEdit工作在段落和字符。段落是一个格式化的字符串…

算法_爬楼梯题解

leetcode链接 70. 爬楼梯 - 爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 爬楼梯问题的本质是斐波那契数。这个题可以用递归来解决&#xff1a; int climbStairs(int n) {if(n1)return 1;if(n2)return 2;else return climbStairs(n-1)climbStairs(n-2); } 但是&#xf…

C++ 浅谈之适配器

C 浅谈之适配器 HELLO&#xff0c;各位博友好&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 这里是 C 浅谈系列&#xff0c;收录在专栏 C 语言中 &#x1f61c;&#x1f61c;&#x1f61c; 本系列阿呆将记录一些 C 语言重要的语法特性 &#x1f3c3;&#…

不坑盒子:强大的word插件,让工作更高效

不坑盒子简介 很多朋友在工作过程中需要对Word文档进行编辑处理&#xff0c;如果想让Word排版更有效率可以试试小编带来的这款不坑盒子软件&#xff0c;这是一个非常好用的插件工具&#xff0c;专门应用在Word文档中&#xff0c;支持Office 2010以上的版本&#xff0c;用户可以…