1、案例简介
该程序是基于OpenHarmony标准系统编写的基础外设类:简易HDF驱动。
目前已在凌蒙派-RK3568开发板跑通。详细资料请参考官网:https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk3568-openharmony
2、基础知识
2.1、OpenHarmony HDF开发简介HDF(Hardware Driver Foundation)驱动框架,为驱动开发者提供驱动框架能力,包括驱动加载、驱动服务管理、驱动消息机制和配置管理。旨在构建统一的驱动架构平台,为驱动开发者提供更精准、更高效的开发环境,力求做到一次开发,多系统部署。
2.2、OpenHarmony HDF驱动开发HDF(Hardware Driver Foundation)框架以组件化的驱动模型作为核心设计思路,为开发者提供更精细化的驱动管理,让驱动开发和部署更加规范。HDF框架将一类设备驱动放在同一个Host(设备容器)里面,用于管理一组设备的启动加载等过程。在划分Host时,驱动程序是部署在一个Host还是部署在不同的Host,主要考虑驱动程序之间是否存在耦合性,如果两个驱动程序之间存在依赖,可以考虑将这部分驱动程序部署在一个Host里面,否则部署到独立的Host中是更好的选择。Device对应一个真实的物理设备。DeviceNode是设备的一个部件,Device至少有一个DeviceNode。每个DeviceNode可以发布一个设备服务。驱动即驱动程序,每个DevicdNode唯一对应一个驱动,实现和硬件的功能交互。HDF驱动模型如下图所示:
2.3、OpenHarmony HDF驱动加载HDF驱动框架提供把和配置的设备列表匹配成功的驱动程序加载起来的功能。
支持按需加载和按序加载两种策略,具体设备的加载策略由配置文件中的preload字段来控制,配置值参考如下:
- <span><span class="cm-keyword">typedef</span> <span class="cm-keyword">enum</span> {</span>
- <span> <span class="cm-variable">DEVICE_PRELOAD_ENABLE</span> <span class="cm-operator">=</span> <span class="cm-number">0</span>,</span>
- <span> <span class="cm-variable">DEVICE_PRELOAD_ENABLE_STEP2</span> <span class="cm-operator">=</span> <span class="cm-number">1</span>,</span>
- <span> <span class="cm-variable">DEVICE_PRELOAD_DISABLE</span> <span class="cm-operator">=</span> <span class="cm-number">2</span>,</span>
- <span> <span class="cm-variable">DEVICE_PRELOAD_INVALID</span></span>
- <span>} <span class="cm-variable">DevicePreload</span>;</span>
复制代码 2.3.1、按需加载
- preload字段配置为0(DEVICE_PRELOAD_ENABLE),则系统启动过程中默认加载。
- preload字段配置为1(DEVICE_PRELOAD_ENABLE_STEP2),当系统支持快速启动的时候,则在系统完成之后再加载这一类驱动,否则和DEVICE_PRELOAD_ENABLE含义相同。
- preload字段配置为2(DEVICE_PRELOAD_DISABLE),则系统启动过程中默认不加载,支持后续动态加载,当用户态获取驱动服务时,如果驱动服务不存在,HDF框架会尝试动态加载该驱动。
2.3.2、按序加载(默认加载策略)配置文件中的priority(取值范围为整数0到200)是用来表示host(驱动容器)和驱动的优先级。不同的host内的驱动,host的priority值越小,驱动加载优先级越高;同一个host内驱动的priority值越小,加载优先级越高。
2.4、OpenHarmony HDF驱动服务管理驱动服务是HDF驱动设备对外提供能力的对象,由HDF框架统一管理。驱动服务管理主要包含驱动服务的发布和获取。
2.4.1、驱动服务的发布策略
HDF框架定义了驱动对外发布服务的策略,由配置文件中的policy字段来控制,policy字段的取值范围以及含义如下:
- <span><span class="cm-keyword">typedef</span> <span class="cm-keyword">enum</span> {</span>
- <span> <span class="cm-comment">/* 驱动不提供服务 */</span></span>
- <span> <span class="cm-variable">SERVICE_POLICY_NONE</span> <span class="cm-operator">=</span> <span class="cm-number">0</span>,</span>
- <span> <span class="cm-comment">/* 驱动对内核态发布服务 */</span></span>
- <span> <span class="cm-variable">SERVICE_POLICY_PUBLIC</span> <span class="cm-operator">=</span> <span class="cm-number">1</span>,</span>
- <span> <span class="cm-comment">/* 驱动对内核态和用户态都发布服务 */</span></span>
- <span> <span class="cm-variable">SERVICE_POLICY_CAPACITY</span> <span class="cm-operator">=</span> <span class="cm-number">2</span>,</span>
- <span> <span class="cm-comment">/* 驱动服务不对外发布服务,但可以被订阅 */</span></span>
- <span> <span class="cm-variable">SERVICE_POLICY_FRIENDLY</span> <span class="cm-operator">=</span> <span class="cm-number">3</span>,</span>
- <span> <span class="cm-comment">/* 驱动私有服务不对外发布服务,也不能被订阅 */</span></span>
- <span> <span class="cm-variable">SERVICE_POLICY_PRIVATE</span> <span class="cm-operator">=</span> <span class="cm-number">4</span>,</span>
- <span> <span class="cm-comment">/* 错误的服务策略 */</span></span>
- <span> <span class="cm-variable">SERVICE_POLICY_INVALID</span></span>
- <span>} <span class="cm-variable">ServicePolicy</span>;</span>
复制代码 2.4.2、驱动服务的接口说明针对驱动服务管理功能,HDF框架开放了以下接口供开发者调用,如下表所示:
2.5、驱动消息机制管理当用户态应用和内核态驱动需要交互时,可以使用HDF框架的消息机制来实现。
消息机制的功能主要有以下两种:
- 用户态应用发送消息到驱动。
- 用户态应用接收驱动主动上报事件。
消息机制接口如下所示:
2.6、配置树配置HCS(HDF Configuration Source)是HDF驱动框架的配置描述源码,内容以Key-Value为主要形式。它实现了配置代码与驱动代码解耦,便于开发者进行配置管理。
HC-GEN(HDF Configuration Generator)是HCS配置转换工具,可以将HDF配置文件转换为软件可读取的文件格式:
- 在弱性能环境中,转换为配置树源码或配置树宏定义,驱动可直接调用C代码或宏式APIs获取配置。
- 在高性能环境中,转换为HCB(HDF Configuration Binary)二进制文件,驱动可使用HDF框架提供的配置解析接口获取配置。
以下是使用HCB模式的典型应用场景:
HCS经过HC-GEN编译生成HCB文件,HDF驱动框架中的HCS Parser模块会从HCB文件中重建配置树,HDF驱动模块使用HCS Parser提供的配置读取接口获取配置内容。
3、代码解析
3.1、配置文件
3.1.1、device_info.hcs
创建config/device_info.hcs,用于驱动设备描述,具体内容如下:
- <span>#include "config.hcs"</span>
- <span><span></span></span>
- <span>root {</span>
- <span> device_info {</span>
- <span> platform :: host { // led设备节点归类于platform这个host</span>
- <span> hostName = "platform_host";</span>
- <span> priority = 50;</span>
- <span> device_rk3568_sample :: device { // rk3568下的sample类设备</span>
- <span> device0 :: deviceNode { // led类设备下的具体某个设备节点的配置</span>
- <span> policy = 2; // 驱动服务发布策略</span>
- <span> priority = 100; // 驱动启动优先级</span>
- <span> preload = 0; // 驱动按需加载字段</span>
- <span> permission = 0666; // 驱动创建设备节点权限</span>
- <span> moduleName = "rk3568_sample_driver"; // 驱动名称,必须和驱动入口结构的moduleName值一致</span>
- <span> serviceName = "rk3568_sample_service"; // 驱动对外发布服务的名称,必须唯一</span>
- <span> deviceMatchAttr = "rk3568_sample_config"; // 驱动私有数据匹配关键字,必须和驱动私有数据配置节点的match_attr匹配</span>
- <span> }</span>
- <span> }</span>
- <span> }</span>
- <span> }</span>
- <span>}</span>
复制代码注意:
- device_rk3568_sample:为配置树的类设备结点。
- deviceMatchAttr:关键字必须与config.hcs的match_attr匹配。
3.1.2、config.hcs
创建config/config.hcs,用于定义私有变量,具体内容如下:
- <span>root {</span>
- <span> platform {</span>
- <span> rk3568_sample_config {</span>
- <span> match_attr = "rk3568_sample_config"; //该字段的值必须和device_info.hcs中的deviceMatchAttr值一致</span>
- <span> }</span>
- <span> }</span>
- <span>}</span>
复制代码由于我们没有用到其他私有变量,故不做定义。
3.1.3、参与配置树编译
编辑//vendor/lockzhiner/rk3568/hdf_config/khdf/hdf.hcs,将device_info.hcs添加配置树中。具体内容如下所示:
- #include "../../samples/b01_hdf_sample/config/device_info.hcs"
复制代码 3.2、HDF驱动 3.2.1、driver_hdf_sample.c
3.2.1.1、头文件- <span><span class="cm-meta">#include "hdf_log.h" </span><span class="cm-comment">// HDF框架提供的日志接口头文件</span></span>
- <span><span class="cm-meta">#include "hdf_base.h" </span><span class="cm-comment">// HDF架构提供的基础接口头文件</span></span>
- <span><span class="cm-meta">#include "hdf_device_desc.h" </span><span class="cm-comment">// HDF架构提供的驱动开发相关能力接口的头文件</span></span>
- <span><span class="cm-meta">#include "device_resource_if.h" </span><span class="cm-comment">// 声明用于查询配置树的API</span></span>
复制代码 3.2.1.2、定义打印标签- <span><span class="cm-comment">// 打印信息的标签</span></span>
- <span><span class="cm-meta">#define HDF_LOG_TAG rk3568_sample_driver</span></span>
- <span><span class="cm-meta">#define PRINT_INFO(fmt, args...) printk("%s, %s, %d, info: "fmt, __FILE__, __func__, __LINE__, ##args)</span></span>
- <span><span class="cm-meta">#define PRINT_ERROR(fmt, args...) printk("%s, %s, %d, error: "fmt, __FILE__, __func__, __LINE__, ##args)</span></span>
复制代码建议读者用HDF_LOGI、HDF_LOGE等打印信息。
3.2.1.3、驱动初始化- <span><span class="cm-comment">/***************************************************************</span></span>
- <span> <span class="cm-comment">* 函数名称: HdfSampleDriverInit</span></span>
- <span> <span class="cm-comment">* 说 明: 驱动自身业务初始化的接口</span></span>
- <span> <span class="cm-comment">* 参 数:</span></span>
- <span> <span class="cm-comment">* @deviceObject hdf设备</span></span>
- <span> <span class="cm-comment">* 返 回 值: HDF_SUCCESS为成功,反之为失败</span></span>
- <span><span class="cm-comment">***************************************************************/</span></span>
- <span><span class="cm-keyword">static</span> <span class="cm-variable-3">int</span> <span class="cm-def">HdfSampleDriverInit</span>(<span class="cm-keyword">struct</span> <span class="cm-def">HdfDeviceObject</span> <span class="cm-operator">*</span><span class="cm-variable">deviceObject</span>)</span>
- <span>{</span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-variable">deviceObject</span> <span class="cm-operator">==</span> <span class="cm-variable">NULL</span>) {</span>
- <span> <span class="cm-variable">HDF_LOGE</span>(<span class="cm-string">"%s::ptr is null!"</span>, <span class="cm-variable">__func__</span>);</span>
- <span> <span class="cm-variable">PRINT_ERROR</span>(<span class="cm-string">"deviceObject is null\n"</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_FAILURE</span>;</span>
- <span> }</span>
- <span> <span class="cm-variable">HDF_LOGI</span>(<span class="cm-string">"Sample driver Init success"</span>);</span>
- <span> <span class="cm-variable">PRINT_INFO</span>(<span class="cm-string">"Sample driver Init success"</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_SUCCESS</span>;</span>
- <span>}</span>
复制代码 3.2.1.4、驱动释放- <span><span class="cm-comment">/***************************************************************</span></span>
- <span> <span class="cm-comment">* 函数名称: HdfSampleDriverRelease</span></span>
- <span> <span class="cm-comment">* 说 明: 驱动资源释放的接口</span></span>
- <span> <span class="cm-comment">* 参 数:</span></span>
- <span> <span class="cm-comment">* @deviceObject hdf设备</span></span>
- <span> <span class="cm-comment">* 返 回 值: HDF_SUCCESS为成功,反之为失败</span></span>
- <span><span class="cm-comment">***************************************************************/</span></span>
- <span><span class="cm-keyword">static</span> <span class="cm-variable-3">void</span> <span class="cm-def">HdfSampleDriverRelease</span>(<span class="cm-keyword">struct</span> <span class="cm-def">HdfDeviceObject</span> <span class="cm-operator">*</span><span class="cm-variable">deviceObject</span>)</span>
- <span>{</span>
- <span> <span class="cm-comment">// release resources here</span></span>
- <span> <span class="cm-variable">HDF_LOGI</span>(<span class="cm-string">"Sample driver release success"</span>);</span>
- <span> <span class="cm-keyword">return</span>;</span>
- <span>}</span>
复制代码 3.2.1.5、驱动绑定将驱动对外提供的服务能力接口绑定到HDF框架,通过struct IDeviceIoService设置Dispatch函数。
- <span><span class="cm-comment">/***************************************************************</span></span>
- <span> <span class="cm-comment">* 函数名称: HdfSampleDriverBind</span></span>
- <span> <span class="cm-comment">* 说 明: 将驱动对外提供的服务能力接口绑定到HDF框架</span></span>
- <span> <span class="cm-comment">* 参 数:</span></span>
- <span> <span class="cm-comment">* @deviceObject hdf设备</span></span>
- <span> <span class="cm-comment">* 返 回 值: HDF_SUCCESS为成功,反之为失败</span></span>
- <span><span class="cm-comment">***************************************************************/</span></span>
- <span><span class="cm-keyword">static</span> <span class="cm-variable-3">int</span> <span class="cm-def">HdfSampleDriverBind</span>(<span class="cm-keyword">struct</span> <span class="cm-def">HdfDeviceObject</span> <span class="cm-operator">*</span><span class="cm-variable">deviceObject</span>)</span>
- <span>{</span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-variable">deviceObject</span> <span class="cm-operator">==</span> <span class="cm-variable">NULL</span>) {</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_FAILURE</span>;</span>
- <span> }</span>
- <span> <span class="cm-keyword">static</span> <span class="cm-keyword">struct</span> <span class="cm-def">IDeviceIoService</span> <span class="cm-def">testService</span> <span class="cm-operator">=</span> {</span>
- <span> .<span class="cm-variable">Dispatch</span> <span class="cm-operator">=</span> <span class="cm-variable">HdfSampleDriverDispatch</span>,</span>
- <span> };</span>
- <span> <span class="cm-variable">deviceObject</span><span class="cm-operator">-></span><span class="cm-variable">service</span> <span class="cm-operator">=</span> <span class="cm-operator">&</span><span class="cm-variable">testService</span>;</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_SUCCESS</span>;</span>
- <span>}</span>
复制代码HdfSampleDriverDispatch()挂载载struct IDeviceIoService的函数指针成员Dispatch,它相当于Linux的ioctl,可与应用程序进行数据交互。
- <span><span class="cm-comment">/***************************************************************</span></span>
- <span> <span class="cm-comment">* 函数名称: HdfSampleDriverDispatch</span></span>
- <span> <span class="cm-comment">* 说 明: 通过服务中的Dispatch方法向驱动发送消息。</span></span>
- <span> <span class="cm-comment">* 参 数:</span></span>
- <span> <span class="cm-comment">* @client client指向服务的客户端对象的指针</span></span>
- <span> <span class="cm-comment">* @id cmdId业务接口的命令字</span></span>
- <span> <span class="cm-comment">* @data data指向调用程序传递的数据的指针</span></span>
- <span> <span class="cm-comment">* @reply reply指向需要返回给调用者的数据的指针</span></span>
- <span> <span class="cm-comment">* 返 回 值: HDF_SUCCESS为成功,反之为失败</span></span>
- <span><span class="cm-comment">***************************************************************/</span></span>
- <span><span class="cm-keyword">static</span> <span class="cm-variable-3">int32_t</span> <span class="cm-def">HdfSampleDriverDispatch</span>(<span class="cm-keyword">struct</span> <span class="cm-def">HdfDeviceIoClient</span> <span class="cm-operator">*</span><span class="cm-variable">client</span>,</span>
- <span> <span class="cm-variable-3">int</span> <span class="cm-variable">id</span>,</span>
- <span> <span class="cm-keyword">struct</span> <span class="cm-def">HdfSBuf</span> <span class="cm-operator">*</span><span class="cm-variable">data</span>,</span>
- <span> <span class="cm-keyword">struct</span> <span class="cm-def">HdfSBuf</span> <span class="cm-operator">*</span><span class="cm-variable">reply</span>)</span>
- <span>{</span>
- <span> <span class="cm-variable-3">int32_t</span> <span class="cm-variable">ret</span> <span class="cm-operator">=</span> <span class="cm-variable">HDF_SUCCESS</span>;</span>
- <span><span></span></span>
- <span> <span class="cm-variable">HDF_LOGI</span>(<span class="cm-string">"%s: received cmd %d"</span>, <span class="cm-variable">__func__</span>, <span class="cm-variable">id</span>);</span>
- <span> <span class="cm-variable">PRINT_INFO</span>(<span class="cm-string">"received cmd %d\n"</span>, <span class="cm-variable">id</span>);</span>
- <span><span></span></span>
- <span> <span class="cm-keyword">switch</span> (<span class="cm-variable">id</span>) {</span>
- <span> <span class="cm-keyword">case</span> <span class="cm-variable">SAMPLE_WRITE_READ</span>: {</span>
- <span> <span class="cm-keyword">const</span> <span class="cm-variable-3">char</span> <span class="cm-variable-3">*</span><span class="cm-variable">readData</span> <span class="cm-operator">=</span> <span class="cm-variable">HdfSbufReadString</span>(<span class="cm-variable">data</span>);</span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-variable">readData</span> <span class="cm-operator">!=</span> <span class="cm-variable">NULL</span>) {</span>
- <span> <span class="cm-variable">HDF_LOGE</span>(<span class="cm-string">"%s: read data is: %s"</span>, <span class="cm-variable">__func__</span>, <span class="cm-variable">readData</span>);</span>
- <span> <span class="cm-variable">PRINT_ERROR</span>(<span class="cm-string">"read data is %s\n"</span>, <span class="cm-variable">readData</span>);</span>
- <span> }</span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-operator">!</span><span class="cm-variable">HdfSbufWriteInt32</span>(<span class="cm-variable">reply</span>, <span class="cm-variable">INT32_MAX</span>)) {</span>
- <span> <span class="cm-variable">HDF_LOGE</span>(<span class="cm-string">"%s: reply int32 fail"</span>, <span class="cm-variable">__func__</span>);</span>
- <span> <span class="cm-variable">PRINT_ERROR</span>(<span class="cm-string">"reply int32 failed\n"</span>);</span>
- <span> }</span>
- <span><span></span></span>
- <span> <span class="cm-variable">ret</span> <span class="cm-operator">=</span> <span class="cm-variable">HdfDeviceSendEvent</span>(<span class="cm-variable">client</span><span class="cm-operator">-></span><span class="cm-variable">device</span>, <span class="cm-variable">id</span>, <span class="cm-variable">data</span>);</span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-variable">ret</span> <span class="cm-operator">!=</span> <span class="cm-variable">HDF_SUCCESS</span>) {</span>
- <span> <span class="cm-variable">PRINT_ERROR</span>(<span class="cm-string">"HdfDeviceSendEvent failed and ret = %d\n"</span>, <span class="cm-variable">ret</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">ret</span>;</span>
- <span> }</span>
- <span><span></span></span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_SUCCESS</span>;</span>
- <span> }</span>
- <span> <span class="cm-keyword">break</span>;</span>
- <span><span></span></span>
- <span> <span class="cm-keyword">default</span>:</span>
- <span> <span class="cm-variable">HDF_LOGE</span>(<span class="cm-string">"id %d is out of the range\n"</span>, <span class="cm-variable">id</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_ERR_INVALID_PARAM</span>;</span>
- <span> <span class="cm-keyword">break</span>;</span>
- <span> }</span>
- <span><span></span></span>
- <span><span class="cm-variable">out</span>:</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_FAILURE</span>;</span>
- <span>}</span>
复制代码 3.2.1.6、驱动注册- <span><span class="cm-comment">// 定义驱动入口的对象,必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量。</span></span>
- <span><span class="cm-keyword">struct</span> <span class="cm-def">HdfDriverEntry</span> <span class="cm-def">g_rk3568SampleDriverEntry</span> <span class="cm-operator">=</span> {</span>
- <span> .<span class="cm-variable">moduleVersion</span> <span class="cm-operator">=</span> <span class="cm-number">1</span>,</span>
- <span> .<span class="cm-variable">moduleName</span> <span class="cm-operator">=</span> <span class="cm-string">"rk3568_sample_driver"</span>,</span>
- <span> .<span class="cm-variable">Bind</span> <span class="cm-operator">=</span> <span class="cm-variable">HdfSampleDriverBind</span>,</span>
- <span> .<span class="cm-variable">Init</span> <span class="cm-operator">=</span> <span class="cm-variable">HdfSampleDriverInit</span>,</span>
- <span> .<span class="cm-variable">Release</span> <span class="cm-operator">=</span> <span class="cm-variable">HdfSampleDriverRelease</span>,</span>
- <span>};</span>
- <span><span></span></span>
- <span><span class="cm-comment">// 调用HDF_INIT将驱动入口注册到HDF框架中</span></span>
- <span><span class="cm-variable">HDF_INIT</span>(<span class="cm-variable">g_rk3568SampleDriverEntry</span>);</span>
复制代码 3.2.2、Makefile- <span><span class="cm-string">include </span>drivers/hdf/khdf/platform/platform.mk</span>
- <span>obj-y += driver_hdf_sample.o</span>
复制代码 3.2.3、参与Linux内核编译编辑//drivers/hdf_core/adapter/khdf/linux/Makefile,添加一段代码,将sample驱动参与Linux内核编译中。具体如下所示:
- obj-<span class="cm-quote">$(CONFIG_DRIVERS_HDF)</span> += ../../../../../vendor/lockzhiner/rk3568/samples/b01_hdf_sample/driver/
复制代码 3.3、应用程序
3.3.1、sample_test.c- <span><span class="cm-variable-3">int</span> <span class="cm-def">main</span>()</span>
- <span>{</span>
- <span> <span class="cm-variable-3">char</span> <span class="cm-variable-3">*</span><span class="cm-variable">sendData</span> <span class="cm-operator">=</span> <span class="cm-string">"default event info"</span>;</span>
- <span> <span class="cm-keyword">struct</span> <span class="cm-def">HdfIoService</span> <span class="cm-operator">*</span><span class="cm-variable">serv</span> <span class="cm-operator">=</span> <span class="cm-variable">NULL</span>;</span>
- <span> <span class="cm-keyword">static</span> <span class="cm-keyword">struct</span> <span class="cm-def">HdfDevEventlistener</span> <span class="cm-def">listener</span> <span class="cm-operator">=</span> {</span>
- <span> .<span class="cm-variable">callBack</span> <span class="cm-operator">=</span> <span class="cm-variable">OnDevEventReceived</span>,</span>
- <span> .<span class="cm-variable">priv</span> <span class="cm-operator">=</span><span class="cm-string">"Service0"</span></span>
- <span> };</span>
- <span><span></span></span>
- <span> <span class="cm-comment">// 绑定HDF驱动</span></span>
- <span> <span class="cm-variable">serv</span> <span class="cm-operator">=</span> <span class="cm-variable">HdfIoServiceBind</span>(<span class="cm-variable">SAMPLE_SERVICE_NAME</span>);</span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-variable">serv</span> <span class="cm-operator">==</span> <span class="cm-variable">NULL</span>) {</span>
- <span> <span class="cm-variable">PRINT_ERROR</span>(<span class="cm-string">"fail to get service %s\n"</span>, <span class="cm-variable">SAMPLE_SERVICE_NAME</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_FAILURE</span>;</span>
- <span> }</span>
- <span><span></span></span>
- <span> <span class="cm-comment">// 用户态程序注册接收驱动上报事件的操作方法</span></span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-variable">HdfDeviceRegisterEventListener</span>(<span class="cm-variable">serv</span>, <span class="cm-operator">&</span><span class="cm-variable">listener</span>) <span class="cm-operator">!=</span> <span class="cm-variable">HDF_SUCCESS</span>) {</span>
- <span> <span class="cm-variable">PRINT_ERROR</span>(<span class="cm-string">"fail to register event listener\n"</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_FAILURE</span>;</span>
- <span> }</span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-variable">SendEvent</span>(<span class="cm-variable">serv</span>, <span class="cm-variable">sendData</span>)) {</span>
- <span> <span class="cm-variable">PRINT_ERROR</span>(<span class="cm-string">"fail to send event\n"</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_FAILURE</span>;</span>
- <span> }</span>
- <span><span></span></span>
- <span> <span class="cm-comment">// 等待</span></span>
- <span> <span class="cm-keyword">while</span> (<span class="cm-variable">g_replyFlag</span> <span class="cm-operator">==</span> <span class="cm-number">0</span>) {</span>
- <span> <span class="cm-variable">sleep</span>(<span class="cm-number">1</span>);</span>
- <span> }</span>
- <span><span></span></span>
- <span> <span class="cm-comment">// 注销驱动上报事件</span></span>
- <span> <span class="cm-keyword">if</span> (<span class="cm-variable">HdfDeviceUnregisterEventListener</span>(<span class="cm-variable">serv</span>, <span class="cm-operator">&</span><span class="cm-variable">listener</span>)) {</span>
- <span> <span class="cm-variable">PRINT_ERROR</span>(<span class="cm-string">"fail to unregister listener\n"</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_FAILURE</span>;</span>
- <span> }</span>
- <span><span></span></span>
- <span> <span class="cm-comment">// 释放驱动服务</span></span>
- <span> <span class="cm-variable">HdfIoServiceRecycle</span>(<span class="cm-variable">serv</span>);</span>
- <span> <span class="cm-keyword">return</span> <span class="cm-variable">HDF_SUCCESS</span>;</span>
- <span>}</span>
复制代码 3.3.2、BUILD.gn- <span>import("//build/ohos.gni")</span>
- <span>import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni")</span>
- <span><span></span></span>
- <span>print("samples: compile rk3568_sample_test")</span>
- <span>ohos_executable("rk3568_sample_test") {</span>
- <span> sources = [ "sample_test.c" ]</span>
- <span> include_dirs = [</span>
- <span> "$hdf_framework_path/include",</span>
- <span> "$hdf_framework_path/include/core",</span>
- <span> "$hdf_framework_path/include/osal",</span>
- <span> "$hdf_framework_path/include/platform",</span>
- <span> "$hdf_framework_path/include/utils",</span>
- <span> "$hdf_uhdf_path/osal/include",</span>
- <span> "$hdf_uhdf_path/ipc/include",</span>
- <span> "//base/hiviewdfx/hilog/interfaces/native/kits/include",</span>
- <span> "//third_party/bounds_checking_function/include",</span>
- <span> ]</span>
- <span><span></span></span>
- <span> deps = [</span>
- <span> "$hdf_uhdf_path/platform:libhdf_platform",</span>
- <span> "$hdf_uhdf_path/utils:libhdf_utils",</span>
- <span> "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",</span>
- <span> ]</span>
- <span><span></span></span>
- <span> cflags = [</span>
- <span> "-Wall",</span>
- <span> "-Wextra",</span>
- <span> "-Werror",</span>
- <span> "-Wno-format",</span>
- <span> "-Wno-format-extra-args",</span>
- <span> ]</span>
- <span><span></span></span>
- <span> subsystem_name = "applications"</span>
- <span> part_name = "product_rk3568"</span>
- <span> install_enable = true</span>
- <span>}</span>
复制代码 3.3.3、参与应用程序编译编辑//vendor/lockzhiner/rk3568/samples/BUILD.gn,开启sample编译。具体如下:
- "b01_hdf_sample/app:rk3568_sample_test",
复制代码 4、编译说明建议使用docker编译方法,运行如下:
- <span>hb <span class="cm-keyword">set</span> <span class="cm-attribute">-root</span> .</span>
- <span>hb <span class="cm-keyword">set</span></span>
- <span><span class="cm-comment"># 选择lockzhiner下的rk3568编译分支。</span></span>
- <span>hb build <span class="cm-attribute">-f</span></span>
复制代码 5、运行结果该程序运行结果如下所示:
- <pre class="md-fences md-end-block ty-contain-cm modeLoaded"><span><span class="cm-comment"># rk3568_sample_test</span></span>
- <span>../../vendor/lockzhiner/rk3568/samples/b01_hdf_sample/app/sample_test.c, SendEvent, <span class="cm-number">94</span>, info: Get reply is: <span class="cm-number">9999999</span></span>
- <span>../../vendor/lockzhiner/rk3568/samples/b01_hdf_sample/app/sample_test.c, OnDevEventReceived, <span class="cm-number">41</span>, info: Service0: dev event received: <span class="cm-number">123</span> default event info</span>
- <span><span class="cm-comment"># </span></span></pre>
复制代码