OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序

ADC(Analog to Digital Converter),即模拟-数字转换器,可将模拟信号转换成对应的数字信号,便于存储与计算等操作。除电源线和地线之外,ADC只需要1根线与被测量的设备进行连接。

一、案例简介

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

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

详细资料请参考OpenHarmony官网:

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

二、基础知识

1、ADC简介

ADC(Analog to Digital Converter),即模拟-数字转换器,可将模拟信号转换成对应的数字信号,便于存储与计算等操作。除电源线和地线之外,ADC只需要1根线与被测量的设备进行连接。

2、ADC平台驱动

在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),若采用独立服务模式,则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。ADC模块即采用统一服务模式。如下图所示:

OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序-开源基础软件社区

OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序-开源基础软件社区

ADC模块各分层的作用为:

  • 接口层:提供打开设备,写入数据,关闭设备的能力。
  • 核心层:主要负责服务绑定、初始化以及释放管理器,并提供添加、删除以及获取控制器的能力。
  • 适配层:由驱动适配者实现与硬件相关的具体功能,如控制器的初始化等。

在统一模式下,所有的控制器都被核心层统一管理,并由核心层统一发布一个服务供接口层,因此这种模式下驱动无需再为每个控制器发布服务。

3、ADC应用程序

ADC模块提供的主要接口如表1所示,具体API详见//drivers/hdf_core/framework/include/platform/adc_if.h。

ADC驱动API接口功能介绍如下所示:

接口名

接口描述

DevHandle AdcOpen(uint32_t number)

打开ADC设备

void AdcClose(DevHandle handle)

关闭ADC设备

int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val)

读取AD转换结果值

使用ADC设备的一般流程如下所示:

OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序-开源基础软件社区

OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序-开源基础软件社区

三、程序解析

1、准备工作

查看《凌蒙派-RK3568开发板_排针说明表_》(即Git仓库的//docs/board/凌蒙派-RK3568开发板_排针说明表_v1.0.xlsx),选中ADC5(即ADC5)。

2、配置文件

(1)device_info.hcs

创建config/device_info.hcs,用于驱动设备描述,具体内容如下:

#include "adc_config.hcs"root {device_info {platform :: host {device_adc :: device {device0 :: deviceNode {                         // ADC控制器信息描述policy = 2;                                 // 对外发布服务,必须为2,用于定义ADC管理器的服务priority = 50;permission = 0644;moduleName = "HDF_PLATFORM_ADC_MANAGER";    // 这与drivers/hdf_core/framework/support/platform/src/adc/adc_core.c的g_adcManagerEntry.moduleName对应,它主要负责ADC的管理serviceName = "HDF_PLATFORM_ADC_MANAGER";}device1 :: deviceNode {policy = 0;                                 // 等于0,不需要发布服务priority = 55;                              // 驱动驱动优先级permission = 0644;                          // 驱动创建设备节点权限moduleName = "linux_adc_adapter";           // 用于指定驱动名称,必须是linux_adc_adapterdeviceMatchAttr = "linux_adc_adapter";      // 用于配置控制器私有数据,必须与adc_config.hcs中对应控制器保持一致}}}}
}

注意:

  • device0:ADC控制器,为了引入HDF_PLATFORM_ADC_MANAGER驱动,必须要。
  • device1:ADC实际操作接口。
  • moduleName:该驱动名称,必须是linux_adc_adapter,//drivers/hdf_core/adapter/khdf/linux/platform/adc/adc_iio_adapter.c已编写好。
  • deviceMatchAttr:关键字必须与config.hcs的match_attr匹配。
(2)adc_config.hcs

创建config/adc_config.hcs,用于定义私有变量,具体内容如下:

root {platform {adc_config {match_attr = "linux_adc_adapter";       // 与device_info.hcs的deviceMatchAttr的值一致template adc_device {                   // 必须与//drivers/hdf_core/adapter/khdf/linux/platform/adc/adc_iio_adapter.c的配置树定义保持一致deviceNum = 0;                      // 设备号标识channelNum = 8;                     // ADC通道数量driver_channel0_name = "";          // 通道0在linux文件系统路径driver_channel1_name = "";          // 通道1在linux文件系统路径driver_channel2_name = "";          // 通道2在linux文件系统路径driver_channel3_name = "";          // 通道3在linux文件系统路径driver_channel4_name = "";          // 通道4在linux文件系统路径driver_channel5_name = "";          // 通道5在linux文件系统路径driver_channel6_name = "";          // 通道6在linux文件系统路径driver_channel7_name = "";          // 通道7在linux文件系统路径scanMode = 0;                       // 扫描模式(必要,但无意义)rate = 1000;                        // 转换速率(必要,但无意义)}device_0 :: adc_device {deviceNum = 0;channelNum = 8;driver_channel0_name = "/sys/bus/iio/devices/iio:device0/in_voltage0_raw";driver_channel1_name = "/sys/bus/iio/devices/iio:device0/in_voltage1_raw";driver_channel2_name = "/sys/bus/iio/devices/iio:device0/in_voltage2_raw";driver_channel3_name = "/sys/bus/iio/devices/iio:device0/in_voltage3_raw";driver_channel4_name = "/sys/bus/iio/devices/iio:device0/in_voltage4_raw";driver_channel5_name = "/sys/bus/iio/devices/iio:device0/in_voltage5_raw";driver_channel6_name = "/sys/bus/iio/devices/iio:device0/in_voltage6_raw";driver_channel7_name = "/sys/bus/iio/devices/iio:device0/in_voltage7_raw";}}}
}

ADC实际驱动是//drivers/hdf_core/adapter/khdf/linux/platform/adc/adc_iio_adapter.c,template adc_device定义的各项关键变量是由adc_iio_adapter.c决定,不可修改。

adc_iio_adapter.c实际是对Linux IIO子系统进行操作来控制ADC。

注意:

  • channelNum:表示通道数量。
  • driver_channelX_name:必须是从0开始。
(3)参与配置树编译

编辑//vendor/lockzhiner/rk3568/hdf_config/khdf/hdf.hcs,将device_info.hcs添加配置树中。具体内容如下所示:

#include "../../samples/b04_platform_device_adc/config/device_info.hcs"

3、HDF驱动

ADC平台驱动是//drivers/hdf_core/adapter/khdf/linux/platform/adc/adc_iio_adapter.c,用户不必编写HDF驱动。

4、参与Linux内核编译

编辑//kernel/linux/config/linux-5.10/arch/arm64/configs/rk3568_standard_defconfig,启用CONFIG_DRIVERS_HDF_PLATFORM_ADC,具体内容如下:

CONFIG_DRIVERS_HDF_PLATFORM_ADC=y

5、应用程序

(1)adc_test.c

添加平台驱动ADC的头文件,具体内容如下:

#include "adc_if.h"                 // ADC标准接口头文件

程序可通过,具体内容如下:

int main(int argc, char* argv[])
{DevHandle handle = NULL;int32_t ret;uint32_t value;// 解析参数parse_opt(argc, argv);printf("adc_device: %d\n", m_adc_device);printf("adc_channel: %d\n", m_adc_channel);// 打开ADC设备handle = AdcOpen(m_adc_device);if (handle == NULL) {PRINT_ERROR("AdcOpen failed\n");return -1;}// 进行AD转换并读取转换结果ret = AdcRead(handle, m_adc_channel, &value);if (ret != 0) {PRINT_ERROR("AdcRead failed and ret = %d\n", ret);AdcClose(handle);return -1;}printf("Adc Device(%d), Channel(%d) read successful and value = %d\n", m_adc_device, m_adc_channel, value);// 关闭ADC设备AdcClose(handle);return 0;
}
(2)BUILD.gn
import("//build/ohos.gni")
import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni")print("samples: compile rk3568_adc_test")
ohos_executable("rk3568_adc_test") {sources = [ "adc_test.c" ]include_dirs = ["$hdf_framework_path/include","$hdf_framework_path/include/core","$hdf_framework_path/include/osal","$hdf_framework_path/include/platform","$hdf_framework_path/include/utils","$hdf_uhdf_path/osal/include","$hdf_uhdf_path/ipc/include","//base/hiviewdfx/hilog/interfaces/native/kits/include","//third_party/bounds_checking_function/include",]deps = ["$hdf_uhdf_path/platform:libhdf_platform","$hdf_uhdf_path/utils:libhdf_utils","//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",]cflags = ["-Wall","-Wextra","-Werror","-Wno-format","-Wno-format-extra-args",]subsystem_name = "applications"part_name = "product_rk3568"install_enable = true
}
(3)参与应用程序编译

编辑//vendor/lockzhiner/rk3568/samples/BUILD.gn,开启编译选项。具体如下:

"b04_platform_device_adc/app:rk3568_adc_test",

四、程序编译

建议使用docker编译方法,运行如下:

hb set -root .
hb set
# 选择lockzhiner下的rk3568编译分支。
hb build -f

五、运行结果

该程序运行结果如下所示:

# rk3568_adc_test -d 0 -c 5
../../vendor/lockzhiner/rk3568/samples/b21_platform_device_adc/app/adc_test.c, main, 103, info: adc_device: 0
../../vendor/lockzhiner/rk3568/samples/b21_platform_device_adc/app/adc_test.c, main, 104, info: adc_channel: 5
Adc Device(0), Channel(5) read successful and value = 955
#

可以将ADC引脚通过引线接入排针线中的GNU或3V3中,可以查看ADC的变化。

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

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

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

相关文章

为何网易游戏会选择引入OceanBase数据库

本文作者:田维繁,网易游戏关系型数据库小组负责人 作为中国游戏开发领域的佼佼者,网易游戏始终站在网络游戏自主研发的前沿。其产品及周边产品线丰富多样,因此,为满足各种业务场景的需求,需要多种不同的数据…

STM32 DWT数据观察触发器作为延时函数的使用

STM32 DWT数据观察触发器作为延时函数的使用 📑DWT(Data Watchpoint and Trace数据观察触发器)描述 📝DWT是属于处理器内核单元中的调试组件之一,由四个比较器组成。它们可配置为:硬件监视点或对ETM或PC采样器或数据地…

实验四 微信小程序智能手机互联网程序设计(微信程序方向)实验报告

请编写一个用户登录界面&#xff0c;提示输入用户名和密码进行登录&#xff1b; 代码 index.wxml <view class"user"> <form bindreset""> <view>用户名&#xff1a;</view><input type"text"name""/>…

为什么要选择第三方软件测试机构?CMA、CNAS第三方软件测试机构推荐

第三方软件测试机构是独立于软件开发方和软件使用方的中立机构&#xff0c;致力于对软件产品进行全面、客观、专业的测试和评估&#xff0c;为软件开发方和使用方提供全面的技术支持和服务。 一、为什么要选择第三方软件测试机构   1、专业性强&#xff1a;拥有专业的测试团…

AI论文速读 | 【综述】用于轨迹数据管理和挖掘的深度学习:综述与展望

论文标题&#xff1a;Deep Learning for Trajectory Data Management and Mining: A Survey and Beyond 作者&#xff1a;Wei Chen(陈伟), Yuxuan Liang(梁宇轩), Yuanshao Zhu, Yanchuan Chang, Kang Luo, Haomin Wen(温浩珉), Lei Li, Yanwei Yu(于彦伟), Qingsong Wen(文青…

短视频短剧小程序搭建支持抖音快手百度微信h5端源码+教程

短视频短剧小程序搭建支持抖音快手百度微信h5端源码教程 预览 https://duanju.baicaitang.cn/h5/#/ 安装 一个备案域名服务器阿里云oss 后端搭建 1、导入数据库sql 2、设置运行目录 /public 3、伪静态 location / {index index.html index.htm index.php;#主要是这一段一定要…

力扣刷题Days31-第二题-125.验证回文串(js)

目录 1&#xff0c;题目 2&#xff0c;代码 2.1自己完成 2.2双指针 1&#xff0c;题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你…

软件资源分享六:EPLAN Electric P8 2024 | Eplan 2024 中文版软件介绍+保姆级安装教程

原文链接&#xff1a;安装激活教程 EPLAN Electric P8 2024 | Eplan 2024 中文版软件介绍安装教程 EPLAN 2024是一款电气设计软件&#xff0c;它可以用于自动化系统的设计、文档编制和维护。EPLAN可以对电气设计的各个方面进行完整的支持&#xff0c;包括电气控制系统、机械设…

MATLAB科研绘图与学术图表绘制从入门到精通

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

字母异位分组-考察哈希表

题目 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词是由重新排列源单词的所有字母得到的一个新单词。 思路 同一个字母异位词之间的联系&#xff1a; 如 e a t eat eat、 a t e ate ate能够转变成 a e t aet aet(按…

【JavaScript】函数 ④ ( 函数返回值 | 函数返回值语法 return 关键字 | 函数默认返回值 undefined )

文章目录 一、JavaScript 函数返回值1、函数返回值引入2、函数返回值语法3、函数默认返回值4、函数默认返回值 一、JavaScript 函数返回值 1、函数返回值引入 JavaScript 函数 可以 实现某种特定的功能 , 执行完毕后 , 可以返回一个 " 返回值 " ; 当 函数 被调用执行…

基于RDMA的云服务能力实践与探索

01 背景 随着基于大数据大模型构建的数据系统越来越有商业价值&#xff0c;机器学习的玩家也越来越多&#xff0c;数据量越来越大。为解决海量数据在服务器之间的同步效率问题&#xff0c;RDMA(Remote Direct Memory Access) 技术逐渐走进了网络技术人员的视野。RDMA为什么…