OpenHarmony基于HDF简单驱动开发实例

news/2024/2/29 17:19:15/文章来源:https://blog.csdn.net/m0_70749039/article/details/135588940

OpenHarmony基于HDF简单驱动开发实例

背景

OpenHarmony-3.0-LTS

qemu_small_system_demo

liteos_a

qemu

添加配置

device/qemu/arm_virt/liteos_a/hdf_config/device_info/device_info.hcs

device_info 新增:

sample_host :: host {hostName = "sample_host";sample_device :: device {device0 :: deviceNode {policy = 2;priority = 100;preload = 1;permission = 0664;moduleName = "sample_driver";serviceName = "sample_service";}}
}

添加驱动代码

目录:device/qemu/arm_virt/liteos_a/drivers

新建驱动实现

mkdir sample_driver

vim sample_driver/sample_driver.c

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include "hdf_log.h"
#include "hdf_base.h"
#include "hdf_device_desc.h"#define HDF_LOG_TAG sample_driver#define SAMPLE_WRITE_READ 123static int32_t HdfSampleDriverDispatch(  \struct HdfDeviceIoClient *client, int id, struct HdfSBuf *data, struct HdfSBuf *reply)
{HDF_LOGI("%{public}s: received cmd %{public}d", __func__, id);if (id == SAMPLE_WRITE_READ) {const char *readData = HdfSbufReadString(data);if (readData != NULL) {HDF_LOGE("%{public}s: read data is: %{public}s", __func__, readData);}if (!HdfSbufWriteInt32(reply, INT32_MAX)) {HDF_LOGE("%{public}s: reply int32 fail", __func__);}return HdfDeviceSendEvent(client->device, id, data);}return HDF_FAILURE;
}static void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
{// release resources herereturn;
}static int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject)
{if (deviceObject == NULL) {return HDF_FAILURE;}static struct IDeviceIoService testService = {.Dispatch = HdfSampleDriverDispatch,};deviceObject->service = &testService;return HDF_SUCCESS;
}static int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject)
{if (deviceObject == NULL) {HDF_LOGE("%{public}s::ptr is null!", __func__);return HDF_FAILURE;}HDF_LOGI("Sample driver Init success");return HDF_SUCCESS;
}static struct HdfDriverEntry g_sampleDriverEntry = {.moduleVersion = 1,.moduleName = "sample_driver",.Bind = HdfSampleDriverBind,.Init = HdfSampleDriverInit,.Release = HdfSampleDriverRelease,
};HDF_INIT(g_sampleDriverEntry);

新建Makefile和BUILD.gn

新建Makefile和BUILD.gn,可参考其他平台,例如 device/hisilicon/drivers/rtc/

Makefile:

include $(LITEOSTOPDIR)/config.mk
include $(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mkMODULE_NAME := sample_driverLOCAL_CFLAGS += $(HDF_INCLUDE)LOCAL_SRCS += sample_driver.cLOCAL_CFLAGS += -fstack-protector-strong -Wextra -Wall -Werror -fsigned-char -fno-strict-aliasing -fno-commoninclude $(HDF_DRIVER)

BUILD.gn:

import("//drivers/adapter/khdf/liteos/hdf.gni")#module_switch = defined(LOSCFG_DRIVERS_HDF_PLATFORM_RTC)
module_name = "sample_driver"
hdf_driver(module_name) {sources = [ "sample_driver.c" ]
}

修改上层BUILD.gn

import("//drivers/adapter/khdf/liteos/hdf.gni")group("drivers") {public_deps = [ "../../../drivers" ]#新增deps = ["sample_driver",]}config("public") {configs = [ "../../../drivers:public" ]
}

编写驱动交互代码

目录:vendor/ohemu/qemu_small_system_demo/

新建用户代码实现

mkdir hdf_test

vim hdf_test/sample_service.c

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "hdf_log.h"
#include "hdf_io_service_if.h"#define HDF_LOG_TAG sample_test
#define SAMPLE_SERVICE_NAME "sample_service"#define SAMPLE_WRITE_READ 123int g_replyFlag = 0;static int OnDevEventReceived(void *priv,  uint32_t id, struct HdfSBuf *data)
{const char *string = HdfSbufReadString(data);if (string == NULL) {HDF_LOGE("fail to read string in event data");g_replyFlag = 1;return HDF_FAILURE;}HDF_LOGI("%{public}s: dev event received: %{public}u %{public}s",  (char *)priv, id, string);g_replyFlag = 1;return HDF_SUCCESS;
}static int SendEvent(struct HdfIoService *serv, char *eventData)
{int ret = 0;struct HdfSBuf *data = HdfSBufObtainDefaultSize();if (data == NULL) {HDF_LOGE("fail to obtain sbuf data");return 1;}struct HdfSBuf *reply = HdfSBufObtainDefaultSize();if (reply == NULL) {HDF_LOGE("fail to obtain sbuf reply");ret = HDF_DEV_ERR_NO_MEMORY;goto out;}if (!HdfSbufWriteString(data, eventData)) {HDF_LOGE("fail to write sbuf");ret = HDF_FAILURE;goto out;}ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);if (ret != HDF_SUCCESS) {HDF_LOGE("fail to send service call");goto out;}int replyData = 0;if (!HdfSbufReadInt32(reply, &replyData)) {HDF_LOGE("fail to get service call reply");ret = HDF_ERR_INVALID_OBJECT;goto out;}HDF_LOGI("Get reply is: %{public}d", replyData);
out:HdfSBufRecycle(data);HdfSBufRecycle(reply);return ret;
}int main()
{char *sendData = "default event info";HDF_LOGI(SAMPLE_SERVICE_NAME "start");struct HdfIoService *serv = HdfIoServiceBind(SAMPLE_SERVICE_NAME);if (serv == NULL) {HDF_LOGE("fail to get service %s", SAMPLE_SERVICE_NAME);return HDF_FAILURE;}static struct HdfDevEventlistener listener = {.callBack = OnDevEventReceived,.priv ="Service0"};if (HdfDeviceRegisterEventListener(serv, &listener) != HDF_SUCCESS) {HDF_LOGE("fail to register event listener");return HDF_FAILURE;}if (SendEvent(serv, sendData)) {HDF_LOGE("fail to send event");return HDF_FAILURE;}while (g_replyFlag == 0) {sleep(1);}if (HdfDeviceUnregisterEventListener(serv, &listener)) {HDF_LOGE("fail to  unregister listener");return HDF_FAILURE;}HdfIoServiceRecycle(serv);return HDF_SUCCESS;
}

新建BUILD.gn

vim sample_service/BUILD.gn,可参考huawei/hdf/sample/platform/uart/dispatch/BUILD.gn

import("//build/lite/config/component/lite_component.gni")
HDF_FRAMEWORKS = "//drivers/framework"lite_component("hdf_test") {features = [ ":sample_service" ]
}executable("sample_service") {sources = [ "sample_service.c" ]include_dirs = ["$HDF_FRAMEWORKS/ability/sbuf/include","$HDF_FRAMEWORKS/core/shared/include","$HDF_FRAMEWORKS/core/host/include","$HDF_FRAMEWORKS/core/master/include","$HDF_FRAMEWORKS/include/core","$HDF_FRAMEWORKS/include/utils","$HDF_FRAMEWORKS/utils/include","$HDF_FRAMEWORKS/include/osal","//drivers/adapter/uhdf/posix/include","//third_party/bounds_checking_function/include","//base/hiviewdfx/hilog_lite/interfaces/native/innerkits",]deps = ["//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared","//drivers/adapter/uhdf/manager:hdf_core","//drivers/adapter/uhdf/posix:hdf_posix_osal",]public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ]defines = [ "__USER__" ]cflags = ["-Wall","-Wextra","-Wno-format","-Wno-format-extra-args",]}

说明: 用户态应用程序使用了HDF框架中的消息发送接口,因此在编译用户态程序的过程中需要依赖HDF框架对外提供的hdf_core和osal的动态库,在gn编译文件中添加如下依赖项:

deps = [
​ "//drivers/hdf_core/adapter/uhdf/manager:hdf_core",
​ "//drivers/hdf_core/adapter/uhdf/posix:hdf_posix_osal",
]

修改上层BUILD.gn

group("qemu_small_system_demo") {deps = ["apps","init_configs","hdf_test",  #新增]
}

以上都是趟过了许多坑后再跑通的

编译测试

使用 hb 重新编译镜像,会生成对应带新增驱动的内核和带用户程序的镜像

#编译
hb clean
hb build

运行新编译的镜像


#运行qemu
./vendor/ohemu/qemu_small_system_demo/patches/qemu-run

注: 需要修改上述脚本中的 rebuild=yes,让其每次都重新生成qemu镜像

开机log有如下打印,说明驱动已加载成功,并且在/dev/hdf/下面会生成 sample_service的节点:

...01-01 00:00:00.119 2 4 W 02500/driver_loader: failed to load node, property is null, match attr is: 
01-01 00:00:00.119 2 4 I 02500/sample_driver: Sample driver Init success
01-01 00:00:00.119 2 4 I 02500/osal_cdev: OsalRegisterCdev:register /dev/hdf/sample_service
01-01 00:00:00.119 2 4 D 02500/devmgr_service: DevmgrServiceUpdateStatus host:sample_host 0 device:sample_service 0 status:1...
OHOS:/$ ls /dev/hdf/                                                           
dev_mgr  event2  hdf_input_event1  input_dev_manager  sample_service 

运行测试应用 sample_service,会有如下打印:

OHOS:/$ sample_service                                                         
01-01 00:00:59.059 10 44 I 02500/sample_test: sample_servicestart
01-01 00:00:59.063 10 44 I 02500/sample_driver: HdfSampleDriverDispatch: received cmd 123
01-01 00:00:59.063 10 44 E 02500/sample_driver: HdfSampleDriverDispatch: read data is: default event info
01-01 00:00:59.064 10 44 I 02500/sample_test: Get reply is: 2147483647
01-01 00:00:59.068 10 45 I 02500/sample_test: Service0: dev event received: 123 default event info
01-01 00:01:00.065 10 44 D 02500/hdf_syscall_adapter: ioctl send poll thread(4) exit event, ret=0
OHOS:/$ 01-01 00:01:00.066 10 45 I 02500/hdf_syscall_adapter: event listener task received exit event
01-01 00:01:00.066 10 45 I 02500/hdf_syscall_adapter: event listener task exit
01-01 00:01:00.067 10 44 I 02500/hdf_syscall_adapter: poll thread exited
^C
OHOS:/$ ^C

想学习更多华为鸿蒙HarmonyOS开发知识,在这里我为大家准备了华为鸿蒙HarmonyOS开发者资料大全,大家可以自行点击链接领取:《做鸿蒙应用开发到底学习些啥?》

其次就是考虑到市场上还没有系统性的学习资料,同时我也整理了一份《鸿蒙 (Harmony OS)开发学习手册》特意整理成PDF文档方式,分享给大家参考学习,大家可以根据自身情况进行获取:《做鸿蒙应用开发到底学习些啥?》

《鸿蒙 (Harmony OS)开发学习手册》

一、入门必看

1. 应用开发导读(ArkTS)

2. 应用开发导读(Java)

3.......

二、HarmonyOS 概念

1. 系统定义

2. 技术架构

3. 技术特性

4. 系统安全

5......

三、如何快速入门?《做鸿蒙应用开发到底学习些啥?》

1. 基本概念

2. 构建第一个ArkTS应用

3. 构建第一个JS应用

4. ……

四、开发基础知识

1. 应用基础知识

2. 配置文件

3. 应用数据管理

4. 应用安全管理

5. 应用隐私保护

6. 三方应用调用管控机制

7. 资源分类与访问

8. 学习ArkTS语言

9. ……

五、基于ArkTS 开发

1. Ability开发

2. UI开发

3. 公共事件与通知

4. 窗口管理

5. 媒体

6. 安全

7. 网络与链接

8. 电话服务

9. 数据管理

10. 后台任务(Background Task)管理

11. 设备管理

12. 设备使用信息统计

13. DFX

14. 国际化开发

15. 折叠屏系列

16. ……

更多了解更多鸿蒙开发的相关知识可以参考:《做鸿蒙应用开发到底学习些啥?》

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

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

相关文章

Docker 配置国内镜像源加速

1. 国内镜像源总览 名称路径中国官方镜像https://registry.docker-cn.com网易163镜像http://hub-mirror.c.163.com中科大镜像https://docker.mirrors.ustc.edu.cn阿里云镜像https://[xxx].mirror.aliyuncs.com 2. 阿里云镜像源 地址&#xff1a;https://cr.console.aliyun.c…

基于Java SSM框架实现医院管理系统项目【项目源码】计算机毕业设计

基于java的SSM框架实现医院管理系统演示 SSM框架 当今流行的“SSM组合框架”是Spring SpringMVC MyBatis的缩写&#xff0c;受到很多的追捧&#xff0c;“组合SSM框架”是强强联手、各司其职、协调互补的团队精神。web项目的框架&#xff0c;通常更简单的数据源。Spring属于…

尼科彻斯定理----C语言

大家好我是Beilef许久未见了&#xff0c;小弟学校考试刚结束。这个过程懂的都懂。痛------ 文章目录 目录 文章目录 前言(一不好懂可以直接跳到二&#xff09; 一、尼科彻斯定理是什么&#xff1f; 二、尼科彻斯定理解析 这是ai的回答 尼科彻斯定理&#xff08;Nikomačs theor…

计算机网络 —— 数据链路层

数据链路层 3.1 数据链路层概述 数据链路层把网络层交下来的数据构成帧发送到链路上&#xff0c;以及把收到的帧数据取出并上交给网络层。链路层属于计算机网络的底层。数据链路层使用的信道主要由以下两种类型&#xff1a; 点对点通信。广播通信。 数据链路和帧 链路&…

京东年度数据报告-2023全年度笔记本十大热门品牌销量(销额)榜单

2023年度&#xff0c;在电脑办公市场整体销售下滑的环境下&#xff0c;笔记本市场的整体销售也不景气。 根据鲸参谋平台的数据显示&#xff0c;京东平台上笔记本的年度销量为650万&#xff0c;同比下滑约16%&#xff1b;销售额约为330亿&#xff0c;同比下滑约19%。同时&#…

基于ssm的实验室排课系统论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&#x…

【k8s】Kubernetes 声明式 API、命令式

1. 资源管理方式&#xff1a; 1>. 命令式对象管理∶直接使用命令去操作kubernetes资源 kubectl run nginx-pod --imagenginx:1.17.1 --port802>. 命令式对象配置∶通过命令配置和配置文件去操作kubernetes资源 kubectl create/patch -f nginx-pod.yaml3>. 声明式对…

CSS 选择器全攻略:从入门到精通(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

环境变量详细说明

Windows之系统环境变量 配置操作&#xff1a; 计算机→属性→高级系统设置→高级→环境变量 系统变量→新建&#xff1a;JAVA_HOME 变量值&#xff1a;C:\Program Files\Java\jdk1.8.0_121 系统变量→Path→编辑&#xff1a;在变量值最后输入 &#xff1a;%JAVA_HOME%\bin;%J…

Linux基础工具的使用(yum,vim,gcc,g++,gdb,make/makefile)【详解】

目录 linux软件包管理器-yum什么是软件包&#xff1f;查找软件包如何安装软件卸载软件 linux编辑器 - vimvim的基本概念vim模式之间的切换vim命令模式各命令汇总vim底行模式各命令汇总 Linux编译器 - gcc/ggcc/g的作用gcc/g选项预处理编译汇编链接静态库与动态库 Linux调试器 -…

【liunx】线程池+单例模式+STL,智能指针和线程安全+其他常见的各种锁+读者写者问题

线程池单例模式STL,智能指针和线程安全其他常见的各种锁读者写者问题 1.线程池2.线程安全的单例模式3.STL,智能指针和线程安全4.其他常见的各种锁4.读者写者问题 喜欢的点赞&#xff0c;收藏&#xff0c;关注一下把&#xff01; 1.线程池 目前我们学了挂起等待锁、条件变量、信…

优雅设计之美:实现Vue应用程序的时尚布局

前言 页面布局是减少代码重复和创建可维护且具有专业外观的应用程序的基本模式。如果使用的是Nuxt&#xff0c;则可以提供开箱即用的优雅解决方案。然而&#xff0c;令人遗憾的是&#xff0c;在Vue中&#xff0c;这些问题并未得到官方文档的解决。 经过多次尝试&#xff0c;小…

设计模式-委托模式

设计模式专栏 模式介绍模式特点应用场景委托模式在GUI编程场景的应用代码示例Java实现委托模式Python实现委托模式 委托模式在spring中的应用 模式介绍 委托模式是一种软件设计模式&#xff0c;其中一个对象&#xff08;委托对象&#xff09;将某些操作委托给另一个对象&#…

ppt怎么录屏录音并且导出?好用录屏软件推荐

ppt已经成为了日常工作与学习中必不可少的工具&#xff0c;而ppt屏幕录制功能&#xff0c;可以方便用户将他人的演讲或视频中的内容记录下来&#xff0c;以便进一步学习与研究。录制ppt演示并将其导出为视频文件&#xff0c;可以帮助我们进行分享&#xff0c;但是很多人不知道p…

基于Python的汽车信息爬取与可视化分析系统

介绍 这款汽车信息网站是基于多项技术和框架设计的全面的汽车信息展示及查询系统。其中&#xff0c;采用了Python Django框架和Scrapy爬虫技术实现数据的抓取和处理&#xff0c;结合MySQL数据库进行数据存储和管理&#xff0c;利用Vue3、Element-Plus、ECharts以及Pinia等前端…

C++设计模式-- 2.代理模式 和 外观模式

文章目录 代理模式外观模式角色和职责代码演示一&#xff1a;代码演示二&#xff1a;外观模式适用场景 代理模式 代理模式的定义&#xff1a;为其他对象提供一种代理以控制对这个对象的访问。在某些情况下&#xff0c;一个对象不适合 或不能直接引用另一个对象&#xff0c;而代…

Spring高手之路-Spring事务失效的场景详解

目录 前言 Transactional 应用在非 public 修饰的方法上 同一个类中方法调用&#xff0c;导致Transactional失效 final、static方法 Transactional的用法不对 Transactional 注解属性 propagation 设置不当 Transactional注解属性 rollbackFor 设置错误 用错注解 异常…

控制网页的灰度显示

1.代码&#xff1a; 普通网页 <style>html {filter: grayscale(100%);}</style> 或是:webkit内核浏览器写法 <style>html {-webkit-filter: grayscale(100%)}</style> 2.说明&#xff1a; grayscale(amount) :进行灰度转换。 amount转换值的大小&…

国内开源环境漫谈

我国开源软件产业相较于欧美发达国家而言起步相对较晚&#xff0c;开源项目很少超过五年&#xff0c;开发者较年轻。国外很多开源项目都是10年以上的规划与投入。在开源社区发展初期、发展期、协作期、结晶期与流行期的五个阶段中&#xff0c;中国的开源社区平台大多处于前三个…

一个简易的PHP论坛系统

一个简易的PHP论坛系统 php课程设计&#xff0c;毕业设计 预览 技术 bootstrap 4.x jquery css php mysql 5.7 目录结构 登录 管理员 admin/123456 测试用户 user1/123456 更多文章和源码获取查看