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_adapter
                    deviceMatchAttr = "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学习资料

总结

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

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

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

相关文章

Java基础语法(三)| 循环语句

前言 Hello,大家好!很开心与你们在这里相遇,我是一个喜欢文字、喜欢有趣的灵魂、喜欢探索一切有趣事物的女孩,想与你们共同学习、探索关于IT的相关知识,希望我们可以一路陪伴~ 1. if语句 1.1 格式一 if (关系表达式) …

探讨企业邮箱安全问题:必须关注的四个关键要点

近年来,虽然出现了微信、企微等沟通方式,但电子邮件无疑仍然是公司对内对外沟通的首选方式。根据Statista的研究,每天大约有3330亿封电子邮件被发送和接收,预计这一数字在未来几年还会增长。然而,邮件诈骗的问题也一直…

SiameseRPN原理详解(个人学习笔记)

参考资源: 视觉目标跟踪SiamRPNSiameseRPN详解CVPR2018视觉目标跟踪之 SiameseRPN 目录) 1. 模型架构1.1 Siamese Network1.2 RPN 2. 模型训练2.1 损失函数2.2 端到端训练2.3 正负样本选择 3. 跟踪阶段总结 SiamRPN是在SiamFC的基础上进行改进而得到的一…

web布局——说清楚fixed布局

极限省流 想要fixed做导航页面:指定清楚top、left、right、bottom,没指定清楚布局位置就会采用默认的方式: 0)父元素的padding:fixed元素相对位移 1)同级元素是fixed元素:覆盖 2&#xff09…

unrealbuildtool 无法找到,执行 Generate Visual Studio Project 错误

参考链接 Generate cpp project Couldnt find UnrealBuildTool - Pipeline & Plugins / Plugins - Epic Developer Community Forums (unrealengine.com) 错误提示如下图: 解决方案: 打开 UnrealBuildTool,生成解决方案就可以了

解决Veeam做replication复制或备份任务时速度很慢问题

在网络层面配置无问题,比如都是万兆网情况下,发现对一个10T大小Linux虚拟机执行replication复制任务时,每次都需要30几个小时才可以跑完。如下图: 如何能让它更快一点跑完任务呢? 解决方法:登录Veeam,进入…

Verilog语法回顾--门级和开关级模型

目录 门和开关的声明 门和开关类型 支持驱动强度的门 延迟 实例数组 and,nand,nor,or,xor,xnor buf,not bufif1,bufif0,notif1,notif0 MOS switches Bidirecti…

Ubuntu20.04LTS+uhd3.15+gnuradio3.8.1源码编译及安装

文章目录 前言一、卸载本地 gnuradio二、安装 UHD 驱动三、编译及安装 gnuradio四、验证 前言 本地 Ubuntu 环境的 gnuradio 是按照官方指导使用 ppa 的方式安装 uhd 和 gnuradio 的,也是最方便的方法,但是存在着一个问题,就是我无法修改底层…

2013年认证杯SPSSPRO杯数学建模A题(第一阶段)护岸框架全过程文档及程序

2013年认证杯SPSSPRO杯数学建模 A题 护岸框架 原题再现: 在江河中,堤岸、江心洲的迎水区域被水流长期冲刷侵蚀。在河道整治工程中,需要在受侵蚀严重的部位设置一些人工设施,以减弱水流的冲刷,促进该处泥沙的淤积&…

在Windows中部署redis

下载redis Windows版redis在GitHub开源,由microsoftarchive维护,项目地址为 https://github.com/microsoftarchive/redis 找到releases,然后在latest中选择msi,或者zip进行下载 安装 msi安装包安装 下载完成后双击运行,同意协…

【御控物联】JavaScript JSON结构转换(11):数组To数组——综合应用

文章目录 一、JSON结构转换是什么?二、术语解释三、案例之《JSON数组 To JSON数组》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么? JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0…

公司服务器被.rmallox攻击了如何挽救数据?

公司服务器被.rmallox攻击了如何挽救数据? .rmallox这种病毒与之前的勒索病毒变种有何不同?它有哪些新的特点或功能? .rmallox勒索病毒与之前的勒索病毒变种相比,具有一些新的特点和功能。这种病毒主要利用加密技术来威胁用户&am…

消费盲返:新型返利模式引领购物新潮流

消费盲返,一种引领潮流的新型消费返利模式,其核心在于:消费者在平台选购商品后,不仅能享受优惠价格,更有机会获得后续订单的部分利润作为额外奖励。这种创新的返利机制,既提升了消费者的购物体验&#xff0…

小赢科技公布2023年业绩:业绩稳健增长,服务“触角”有效延伸

近日,金融科技公司小赢科技(NYSE:XYF)发布了2023年第四季度及全年未经审计的财务业绩。 财报显示,小赢科技2023年全年总净营收约为48.15亿元,同比增长35.1%;净利润约为11.87亿元,同比增长46.2%…

CCSDS CONVOLUTIONAL CODING 卷积码 规范

文章目录 3 CONVOLUTIONAL CODING3.1 overview3.2 general3.2.1 ATTACHED SYNC MARKER3.2.2 DATA RANDOMIZATION3.2.3 FRAME VALIDATION3.2.4 QUANTIZATION 3.3 BASIC CONVOLUTIONAL CODE SPECIFICATION3.4 PUNCTURED CONVOLUTIONAL CODES matlab中的 comm.ConvolutionalEncode…

Linux IRC

目录 入侵框架检测 检测流程图 账号安全 查找账号中的危险信息 查看保存的历史命令 检测异常端口 入侵框架检测 1、系统安全检查(进程、开放端口、连接、日志) 这一块是目前个人该脚本所实现的功能 2、Rootkit 建议使用rootkit专杀工具来检查&#…

OSPF之单区域配置

文章目录 单区域配置项目背景项目分析拓扑图配置思路基础配置命令查看路由器接口IP地址信息OSPF配置 测试PC1与PC2互通查看OSPF邻居表修改OSPF路由器的router-id完美的OSPF配置命令写法常用查询命令 单区域配置 项目背景 企业内部存在多个部门,分别属于不同的网段…

经纬恒润AUTOSAR产品成功适配芯来RISC-V车规内核

近日,经纬恒润AUTOSAR基础软件产品INTEWORK-EAS(ECU AUTOSAR Software,以下简称EAS)在芯来提供的HP060开发板上成功适配芯来科技的RISC-V处理器NA内核,双方携手打造了具备灵活、可靠、高性能、强安全性的解决方案。这极…

C语言-printf和scanf的区别详解

fprintf(指定的格式写到文件里面。适用于所有的输出流,可以打印在屏幕上面)fscanf(指定的格式读取出来,适用于所有的输入流) fprintf(指定的格式写到文件里面) 两个函数是一样的 打开…

DFS:二叉树的深搜与回溯

一、计算布尔二叉树的值 . - 力扣(LeetCode) class Solution { public:bool evaluateTree(TreeNode* root) {if(root->leftnullptr) return root->val0?false:true; bool left evaluateTree(root->left);bool rightevaluateTree(root->rig…