首页 > 其他分享 >OpenHarmony平台驱动案例--UART

OpenHarmony平台驱动案例--UART

时间:2023-08-25 11:31:53浏览次数:46  
标签:OpenHarmony center -- uart 如下 UART hljs 驱动

1、程序介绍

本程序是基于OpenHarmony标准系统编写的平台驱动案例:UART 详细资料请参考官网:

2、基础知识

2.1、UART简介

UART指异步收发传输器(Universal Asynchronous Receiver/Transmitter),是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。 两个UART设备的连接示意图如下,UART与其他模块一般用2线(图1)或4线(图2)相连,它们分别是:

  • TX:发送数据端,和对端的RX相连。
  • RX:接收数据端,和对端的TX相连。
  • RTS:发送请求信号,用于指示本设备是否准备好,可接受数据,和对端CTS相连。
  • CTS:允许发送信号,用于判断是否可以向对端发送数据,和对端RTS相连。 图1 UART的2线相连 ::: hljs-center

微信截图_20230817154837.png

::: 图2 UART的4线相连 ::: hljs-center

微信截图_20230817154921.png

::: UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。当UART接收缓存达到预定的门限值时,RTS变为不可发送数据,对端的CTS检测到不可发送数据,则停止发送数据。

2.2、UART驱动开发

2.2.1、UART驱动开发接口

为了保证上层在调用UART接口时能够正确的操作UART控制器,核心层在//drivers/hdf_core/framework/support/platform/include/uart/uart_core.h中定义了以下钩子函数,驱动适配者需要在适配层实现这些函数的具体功能,并与钩子函数挂接,从而完成适配层与核心层的交互。 UartHostMethod定义: 代码1.png UartHostMethod结构体成员的回调函数功能说明: ::: hljs-center

微信截图_20230817155021.png

:::

2.2.2、UART驱动开发步骤

UART模块适配HDF框架包含以下四个步骤:

  • 实例化驱动入口。
  • 配置属性文件。
  • 实例化UART控制器对象。
  • 驱动调试。 我们以///drivers/hdf_core/adapter/khdf/linux/platform/uart/uart_adapter.c为例(该UART驱动是建立于Linux UART子系统基础上创建)。
2.2.2.1、驱动实例化驱动入口

驱动入口必须为HdfDriverEntry(在hdf_device_desc.h中定义)类型的全局变量,且moduleName要和device_info.hcs中保持一致。HDF框架会将所有加载的驱动的HdfDriverEntry对象首地址汇总,形成一个类似数组的段地址空间,方便上层调用。 一般在加载驱动时HDF会先调用Bind函数,再调用Init函数加载该驱动。当Init调用异常时,HDF框架会调用Release释放驱动资源并退出。 UART驱动入口开发参考: 代码2.png

2.2.2.2、配置属性文件

完成驱动入口注册之后,需要在device_info.hcs文件中添加deviceNode信息,deviceNode信息与驱动入口注册相关。本例以两个UART控制器为例,如有多个器件信息,则需要在device_info.hcs文件增加对应的deviceNode信息。器件属性值与核心层UartDev成员的默认值或限制范围有密切关系,比如Uart设备号,需要在uart_config.hcs文件中增加对应的器件属性。 本次案例以rk3568为案例(即文件//vendor/lockzhiner/rk3568/hdf_config/khdf/device_info/device_info.hcs),添加deviceNode描述,具体修改如下: 代码3.png uart_config.hcs 配置参考//vendor/lockzhiner/rk3568/hdf_config/khdf/platform/rk3568_uart_config.hcs,具体修改如下: 代码4.png

2.2.2.3、实例化UART控制器对象

完成驱动入口注册之后,下一步就是以核心层UartDev对象的初始化为核心,包括驱动适配者自定义结构体(传递参数和数据),实例化UartDev成员UartHostMethod(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind、Init、Release)。 代码5.png

2.2.2.4、驱动调试

建议先在Linux下修改确认,再移植到OpenHarmony。

2.3、UART应用开发

UART模块应用比较广泛,主要用于实现设备之间的低速串行通信,例如输出打印信息,当然也可以外接各种模块,如GPS、蓝牙等。

2.3.1、接口说明

UART模块提供的主要接口如表1所示,具体API详见//drivers/hdf_core/framework/include/platform/uart_if.h。 UART驱动API接口功能介绍如下所示: ::: hljs-center

微信截图_20230817155059.png

::: (1)UartOpen 在使用UART进行通信时,首先要调用UartOpen获取UART设备句柄,该函数会返回指定端口号的UART设备句柄。 代码6..png UartOpen参数定义如下: ::: hljs-center

微信截图_20230817155115.png

::: UartOpen返回值定义如下: ::: hljs-center

微信截图_20230817155127.png

::: 假设系统中的UART端口号为1,获取该UART设备句柄的示例如下: 代码6.png (2)UartSetBaud 在通信之前,需要设置UART的波特率。 代码7..png UartSetBaud参数定义如下: ::: hljs-center

微信截图_20230817155142.png

::: UartSetBaud返回值定义如下: ::: hljs-center

微信截图_20230817155151.png

::: (3)UartGetBaud 设置UART的波特率后,可以通过获取波特率接口来查看UART当前的波特率。 代码7.1.png UartGetBaud参数定义如下: ::: hljs-center

微信截图_20230817155203.png

::: UartGetBaud返回值定义如下: ::: hljs-center

微信截图_20230817155215.png

::: (4)UartSetAttribute 在通信之前,需要设置UART的设备属性。 代码7.2.png UartSetAttribute参数定义如下: ::: hljs-center

微信截图_20230817155230.png

::: UartGetAttribute返回值定义如下: ::: hljs-center

微信截图_20230817155241.png

::: (5)UartGetAttribute 设置UART的设备属性后,可以通过获取设备属性接口来查看UART当前的设备属性。 代码7.3.png UartGetAttribute参数定义如下: ::: hljs-center

微信截图_20230817155255.png

::: UartGetAttribute返回值定义如下: ::: hljs-center

微信截图_20230817155305.png

::: (6)UartSetTransMode 在通信之前,需要设置UART的传输模式。 代码7.4.png UartSetTransMode参数定义如下: ::: hljs-center

微信截图_20230817155320.png

::: UartSetTransMode返回值定义如下: ::: hljs-center

微信截图_20230817160756.png

:::

(7)UartWrite 向UART设备写入指定长度的数据。 代码7.png UartWrite参数定义如下: ::: hljs-center

微信截图_20230817160812.png

:::

UartWrite返回值定义如下: ::: hljs-center

微信截图_20230817160822.png

::: (8)UartRead 从UART设备中读取指定长度的数据。 代码8.png UartRead参数定义如下: ::: hljs-center

微信截图_20230817160835.png

::: UartRead返回值定义如下: ::: hljs-center

微信截图_20230817160846.png

::: (9)UartClose UART通信完成之后,需要销毁UART设备句柄。 代码9.png UartClose参数定义如下: ::: hljs-center

微信截图_20230817160857.png

:::

2.2.2、开发流程

使用UART的一般流程如下图所示: ::: hljs-center

微信截图_20230817160907.png

:::

3、程序解析

3.1、准备工作

查看《凌蒙派-RK3568开发板_排针说明表_》(即Git仓库的//docs/board/凌蒙派-RK3568开发板_排针说明表_v1.0.xlsx),具体如下: ::: hljs-center

微信截图_20230817160917.png

:::

3.2、Linux内核解析

3.2.1、创建Linux内核Git

请参考《OpenHarmony如何为内核打patch》(即Git仓库的//docs/OpenHarmony如何为内核打patch.docx)。

3.2.2、修改设备树PWM7配置

修改//arch/arm64/boot/dts/rockchip/rk3568-lockzhiner-x0.dtsi(即该目录是指已打Patch后的Linux内核,不是OpenHarmony主目录),具体如下所示: 代码10.png

3.2.3、创建内核patch

请参考《OpenHarmony如何为内核打patch》(即Git仓库的//docs/OpenHarmony如何为内核打patch.docx)。

3.2.4、替换OpenHarmony的内核patch

将制作出的kernel.patch替换到//kernel/linux/patches/linux-5.10/rk3568_patch/kernel.patch即可。

3.3、OpenHarmony配置树配置

3.3.1、device_info.hcs

//vendor/lockzhiner/rk3568/hdf_config/khdf/device_info/device_info.hcs已定义好,具体如下: 代码11.png 注意:

  • device2是我们新增的设备节点,给uart5使用。
  • policy必须为2,表示对内核态和用户态提供服务。否则,应用程序无法调用。
  • HDF_PLATFORM_UART_2,后面跟着的数据“2”,是UartOpen()的端口号。
  • HDF_PLATFORM_UART_2,后面跟着的数据“2”,必须是递增的。

3.3.2、rk3568_uart_config.hcs

//vendor/lockzhiner/rk3568/hdf_config/khdf/platform/rk3568_uart_config.hcs,具体内容如下: 代码12.png 注意:

  • device_uart_0x0002是新增的,为uart5准备的。
  • match_attr的名称必须是rockchip_rk3568_uart_2。

3.4、OpenHarmony UART平台驱动

在//drivers/hdf_core/adapter/khdf/linux/platform/uart/uart_adapter.c已编写对接Linux PWM驱动的相关代码,具体内容如下: 代码13.png 该部分代码不细述,感兴趣的读者可以去详读。

3.5、应用程序

3.5.1、uart_test.c

uart相关头文件如下所示: 代码14.png 主函数定义UART接口调用,具体如下: 代码15.jpg

3.5.2、BUILD.gn

编写应用程序的BUILD.gn,具体内容如下: 代码16.png

3.5.3、参与应用程序编译

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

4、程序编译

建议使用docker编译方法,运行如下: 代码18.png

5、运行结果

运行如下: 代码19.png 注意:

  • rbuff获取的时候可能为空。因为本次案例是基于非阻塞,电脑端发送的串口可能没有获取到数据。 建议:
  • 读者可以尝试使用堵塞方式,再测试看看。

本文作者:福州市凌睿智捷电子有限公司

想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com/#bkwz​

标签:OpenHarmony,center,--,uart,如下,UART,hljs,驱动
From: https://blog.51cto.com/harmonyos/7228087

相关文章

  • APT80DQ40BG-ASEMI低功耗半导体APT80DQ40BG
    编辑:llAPT80DQ40BG-ASEMI低功耗半导体APT80DQ40BG型号:APT80DQ40BG品牌:ASEMI封装:TO-3P恢复时间:>50ns正向电流:80A反向耐压:400V芯片个数:2引脚数量:3类型:快恢复二极管特性:插件快恢复二极管、大功率、低功耗半导体浪涌电流:600A正向压降:1.20V封装尺寸:如图工作温度:-55°C~150°CAPT80DQ40BG......
  • Android岗面试少只是正常规律,我们只需要这样做
    自身情况作为一名大专学历的机电专业毕业生,我是在参加Java培训后决定转向Android开发。在培训期间,我发现JavaEE开发涉及很多知识,于是决定投身Android开发。我的第一份安卓工作让我在实习生阶段得到了很好的学习和实践机会。在这里,我想分享一些关于找工作的经验。首先,当你工......
  • cmake生成动静态库文件及目录
    CMakeLists.txtcmake_minimum_required(VERSION3.15)project(test)#set(SRCadd.cpp;div.cpp;mult.cpp;main.cpp;sub.cpp)#${PROJECT_SOURCE_DIR}指定的就是cmakelists所在的路径aux_source_directory(搜索路径)方式一#aux_source_directory(${PROJECT_SOURCE_DIR}/sr......
  • 【lc】 414第三大的数
    地址:https://leetcode.cn/problems/third-maximum-number/description/思路:设置一个set用来存储数据就Ok了,set还能天然去重。注意判断新数据是否在set中。代码:classSolution:defthirdMax(self,nums)->int:tmp_ans=set()fornuminnums:......
  • .NET6 使用AutoMapper
    一、Net6环境下的.netcore项目里如何使用AutoMapper实现依赖注入。注:AutoMapper是一个对象-对象映射器,可以将一个对象映射到另一个对象。第一步,在Nuget引入AutoMapper、AutoMapper.Extensions.DependencyInjection这两个NuGet包  第二步,定义Profile,方便......
  • 编程真好玩Python_2.1你的第一个程序HelloWorld
    一、作业效果。(1)程序首先显示信息:“你好,世界!”(2)询问你的名字(3)输入后,屏幕显示“你好,×××!”二、完成(1)新建文件夹,保存-命名(2)运行代码print("Hello,World!")person=input("Whatisyourname?\n")print("Hello,",person)(3)在编辑窗口中,选择Run-RunModule,运行程序......
  • [算法学习笔记] 换根dp
    换根dp一般不会指定根节点,并且根节点的变化会对一些值进行改变。因此我们需要转移根。换根dp一般需要预处理一下一个节点的值,然后对于任意节点开始树上dp转移。所以我们常用两次dfs,第一次dfs预处理,第二次dfs为树上dp。一般比较套路。接下来会给出一个典型例题。典例1:L......
  • 不会代码该怎么做接口自动化
    今天我们来聊一聊接口自动化测试。以往我们都是以以代码的形式编写自动化测试脚本做自动化测试,网上也有非常多的攻略,那么在不会代码的情况下该怎么做接口自动化呢,今天给大家介绍Apipost自动化测试模块,不用写代码也能做接口自动化!点击左侧菜单栏「自动化测试」按钮进入自动化测试......
  • VisionPro CogPMAlignTool图像匹配工具的使用详解
    PMAlign工具:此工具可用于训练模板,然后使用在连续的输入图像中搜索模板。可指定执行模板训练或模板搜索时要使用的算法类型,并可选择利用图像还是利用形状模型集合创建已训练模板。输入图像内的可选搜索区域可限制模板搜索的范围。目的:这里主要分享一下,如何在一个ToolBlock中使......
  • 【疑难杂症】升级Mac系统后python遇到[SSL: CERTIFICATE_VERIFY_FAILED]
    [本文出自天外归云的博客园]同事升级Mac电脑版本后,遇到了[SSL:CERTIFICATE_VERIFY_FAILED]报错:<urlopenerror[SSL:CERTIFICATE_VERIFY_FAILED]certificateverifyfailed:unabletogetlocalissuercertificate(_ssl.c:1131)>error:<urlopenerror[SSL:CERTIFICATE_......