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.rhkb.cn/news/294911.html

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

相关文章

github本地仓库push到远程仓库

1.从远程仓库clone到本地 2.生成SSH秘钥&#xff0c;为push做准备 在Ubuntu命令行输入一下内容 [rootlocalhost ~]# ssh-keygen -t rsa < 建立密钥对&#xff0c;-t代表类型&#xff0c;有RSA和DSA两种 Generating public/private rsa key pair. Enter file in whi…

Synchronized锁升级过程

无锁-->偏向锁---> 轻量级锁---->重量级锁 ①、从无锁到偏向锁&#xff1a; 当一个线程首次访问同步块时&#xff0c;如果此对象无锁状态且偏向锁未被禁用&#xff0c;JVM 会将该对象头的锁标记改为偏向锁状态&#xff0c;并记录下当前线程的 ID。此时&#xff0c;对…

Java进阶-反射的详解与应用

本文深入探讨了Java反射机制的核心概念、应用实例及其在现代Java开发中的重要性。文章首先介绍了反射的基本原理和能力&#xff0c;包括在运行时动态获取类信息、操作对象字段和方法的能力。随后&#xff0c;通过具体代码示例&#xff0c;展示了如何利用反射进行字段访问、方法…

3.5网安学习第三阶段第五周回顾(个人学习记录使用)

本周重点 ①SSRF服务器端请求伪造 ②序列化和反序列化 ③Vaudit代码审计 本周主要内容 ①SSRF服务器端请求伪造 一、概述 SSRF: server site request forgery (服务器端请求伪造)。 SSR: 服务端请求&#xff0c;A服务器通过函数向B服务器发送请求。 SSRF发生的前提条件…

Linux:入门篇

文章目录 前言1. Linuxd的安装环境2.Linux的简单介绍2.1 新建目录2.2 新建文件 3.指令到底是什么&#xff1f;4.shell命令以及运行原理5.总结 前言 很多人对于Linux的学习总是感觉无法下手&#xff0c;不知道从何开始学习&#xff0c;相信这篇文章将会为你提供一个清晰的思路。…

高精度算法(加、减、乘、除,使用c++实现)

一、概念 在我们进行计算的过程中&#xff0c;经常会遇到几十位&#xff0c;甚至几百位的数字的计算问题&#xff0c;也有可能会遇到小数点后几十位&#xff0c;几百位的情况&#xff0c;而我们面对这样的情况下&#xff0c; 和 的数据范围显然是不够使用的了。因此这时&am…

Node.js-知识点学习总结归纳

Node.js-知识点学习总结归纳 安装nodenode运行方式通过Node.js直接运行js文件&#xff08;也就不用通过网页html了&#xff09;绝对路径调用:相对路径调用&#xff1a;直接运行js命令&#xff1a; Vscode控制台使用node运行js文件 安装node 这个就不用讲了吧&#xff0c;网上搜…

开源知识库平台Raneto--使用Docker部署Raneto

文章目录 一、Raneto介绍1.1 Raneto简介1.2 知识库介绍 二、阿里云环境2.1 环境规划2.2 部署介绍 三、环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Raneto镜像五、部署Raneto知识库平台5.1 创建挂载目录5.2 编辑config.js文件5.3 编…

Sui Basecamp日程公布,两天超50场密集分享等你来参加

随着4月的来临&#xff0c;我们也怀着激动的心情迎来了Sui全球旗舰品牌会议Sui Basecamp的个位数倒计时。 Sui Basecamp将在4月10–11日巴黎区块链周期间举行&#xff0c;Web3构建者、知名企业和信仰者齐聚一堂&#xff0c;在这里共同创造、学习和建立联系。Basecamp将由具有对…

左值与右值,以及c++11的相关特性。

目录 左值 右值 左值引用总结&#xff1a; 右值引用总结&#xff1a; 右值引用使用场景和意义&#xff1a; 1、左值引用的使用场景&#xff1a; 编译器优化1&#xff1a; 2、移动构造与移动赋值&#xff1a; 3、右值引用的使用场景&#xff1a; 编译器优化2&#xff1a…

excel匹配替换脱敏身份证等数据

假如excel sheet1中有脱敏的身份证号码和姓名&#xff0c;如&#xff1a; sheet2中有未脱敏的数据数据 做法如下&#xff1a; 1、在sheet2的C列用公式 LEFT(A2,6)&REPT("*",8)&RIGHT(A2,4) 做出脱敏数据&#xff0c;用来与sheet1的脱敏数据匹配 2、在sheet…

【卫星家族】 | 高分六号卫星影像及获取

1. 卫星简介 高分六号卫星&#xff08;GF-6&#xff09;于2018年6月2日在酒泉卫星发射中心成功发射&#xff0c;是高分专项中的一颗低轨光学遥感卫星&#xff0c;也是我国首颗精准农业观测的高分卫星&#xff0c;具有高分辨率、宽覆盖、高质量成像、高效能成像、国产化率高等特…

Mysql数据库:故障分析与配置优化

目录 前言 一、Mysql逻辑架构图 二、Mysql单实例常见故障 1、无法通过套接字连接到本地MySQL服务器 2、用户rootlocalhost访问被拒绝 3、远程连接数据库时连接很慢 4、无法打开以MYI结尾的索引文件 5、超出最大连接错误数量限制 6、连接过多 7、配置文件/etc/my.cnf权…

python 哔哩哔哩视频去水印

使用python 去除视频中的水印 1. 需要安装的包 pip install moviepy pip install numpy pip install opencv_python pip install tqdm 2. 代码 import cv2 import numpy as np import glob from moviepy.editor import VideoFileClip import os from tqdm import tqdm# 判…

2024 年每个程序员都应该尝试的 8 个AI工具

随着人工智能技术的极速发展&#xff0c;新的 AI 工具正以前所未有的速度涌现&#xff0c;为开发者们带来了前所未有的机会和挑战。在这个不断演进的时代&#xff0c;掌握最新的 AI 技术已成为每个程序员的必修课。 在本文中&#xff0c;我们收集了8 个程序员在 2024 年值得尝…

idea 报错 Could not list the contents of folder “ftps

idea 报错 Could not list the contents of folder "ftps 解决方案 这里看到了网上的解决方案&#xff0c;顺便再记录一下。打开 【高级】菜单 - 取消勾选 被动模式。然后点击测试连接&#xff0c;显示连接成功&#xff01; ftp中的主动模式和被动模式 主动模式&…

《HelloGitHub》第 96 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/521xueweihan/HelloGitHub 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 …

非关系型数据库-----------探索 Redis高可用 与持久化

目录 一、Redis 高可用 1.1什么是高可用 1.2Redis的高可用技术 二、 Redis 持久化 2.1持久化的功能 2.2Redis 提供两种方式进行持久化 三、Redis 持久化之----------RDB 3.1触发条件 3.1.1手动触发 3.1.2自动触发 3.1.3其他自动触发机制 3.2执行流程 3.3启动时加载…

[蓝桥杯练习题]出差

一道DJ题,重要的是隔离时间,把隔离时间加在边权上即可 现实生活的题大多都是无向图建图,需要边的两端点各自上邻接表和相同权重 #include<bits/stdc.h> using namespace std; #define ll long long const int N1005; const int M10005; struct edge{int to;ll w;edge(int…

【JavaSE】一维数组和二维数组详解

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 一维数组 基本语法 初始化 遍历和打印 数组是引用型变量 基本类型变量与引用类型变量的区别 null 数组传参和返回 总结 二维数组 基本语法 初始化 遍历和打印 一维数组…