0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【北京迅为】iTOP-RK3568开发板鸿蒙OpenHarmony系统南向驱动开发实操-HDF驱动配置UART

北京迅为电子 2025-03-25 11:02 次阅读

瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工艺,搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码,支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU,可用于轻量级人工智能应用。RK3568 支持安卓 11 和 linux 系统,主要面向物联网网关、NVR 存储、工控平板、工业检测、工控盒、卡拉 OK、云终端、车载中控等行业。

wKgZO2fiHHWAdIEQAARFwUG-xCw112.png

【本文摘自】【北京迅为】iTOP-RK3568OpenHarmony系统南向驱动开发

【相关视频】OpenHarmony学习开发系列教程(第1期 北向基础篇一)

OpenHarmony学习开发系列教程(第2期 南向基础篇一)

第6章 实操-HDF驱动配置UART

6.1 修改HCS配置

对于不同的平台,需要在对应的平台目录修改对应的hcs文件,接下来示例为在rk3568下新增uart4 uart9 uart7的修改方法。

修改vendor/hihope/rk3568/hdf_config/khdf/device_info/device_info.hcs文件,device_info.hcs中添加以下内容:

device3 :: deviceNode {

policy = 2;

permission = 0644;

priority = 40;

moduleName = "HDF_PLATFORM_UART";

serviceName = "HDF_PLATFORM_UART_4";

deviceMatchAttr = "rockchip_rk3568_uart_4";

}

device4 :: deviceNode {

policy = 2;

permission = 0644;

priority = 40;

moduleName = "HDF_PLATFORM_UART";

serviceName = "HDF_PLATFORM_UART_7";

deviceMatchAttr = "rockchip_rk3568_uart_7";

}

device5 :: deviceNode {

policy = 2;

permission = 0644;

priority = 40;

moduleName = "HDF_PLATFORM_UART";

serviceName = "HDF_PLATFORM_UART_9";

deviceMatchAttr = "rockchip_rk3568_uart_9";

}

在配置过程中要注意以下几点:

1 device3,device4,device5是自定义的,可以根据实际情况修改

2 policy表示服务策略,取值为0时,表示不发布服务,取值为1时表示向内核态发布服务,取值为2时表示向内核用户态发布服务

3 moduleName的值要与驱动实现的HdfDriverEntry结构体中的moduleName相同。

4 deviceMatchAttr的值表示驱动的私有配置信息

5 serviceName表示服务名称,服务加载成功之后会在开发板的/dev/目录下生成节点。例如HDF_PLATFORM_UART_9后面跟着的数据9是UartOpen()的端口

6.2 配置rk3568_uart_config.hcs

修改vendor/hihope/rk3568/hdf_config/khdf/platform/rk3568_uart_config.hcs文件,添加如下内容,如下所示:

device_uart_0x0004 :: uart_device {

num = 4;

match_attr = "rockchip_rk3568_uart_4";

}

device_uart_0x0007 :: uart_device {

num = 7;

match_attr = "rockchip_rk3568_uart_7";

}

device_uart_0x0009 :: uart_device {

num = 9;

match_attr = "rockchip_rk3568_uart_9";

}

在上面的配置中需要注意以下几点:

1 device_uart_0x0004中的后缀“0x0004”是串口编号。

2 num 与driver_name值“ttyS”组成驱动设备名,例如ttyS4。UartOpen函数参数port,则表示上述uart设备排列序号,比如num=4 的UartOpen函数port=4。

3 match_attr的名称必须是rockchip_rk3568_uart_x,和device_info.hcs中要写一样。

6.3 Openharmony UART平台驱动

在drivers/hdf_core/adapter/khdf/linux/platform/uart/uart_adapter.c 中编写了对接Linux UART驱动的相关代码,这部分不需要大家进行修改,感兴趣的话可以自己研究下uart_adapter.c文件。

6.4 UART应用开发

6.4.1 UART驱动API接口介绍

UART驱动API接口如下所示,具体的API详见drivers/hdf_core/framework/include/platform/uart_if.h文件。

wKgZO2fiHHKASJeFAACAICQUFZQ055.png

UartOpen

在使用UART进行通信时,首先要调用UartOpen获取UART设备句柄,该函数会返回指定端口号的UART设备句柄。函数原型如下所示:

DevHandle UartOpen(uint32_t port);

其中,参数port是UART设备号。UartOpen返回值为NULL表示获取UART设备句柄失败,正常情况下返回UART设备句柄。

假设系统重的UART端口号为4,获取该UART设备句柄的示例如下所示

DevHandle handle = NULL; // UART设备句柄

uint32_t port = 4; // UART设备端口号

handle = UartOpen(port);

if (handle == NULL) {

HDF_LOGE("UartOpen: open uart_%u failed!\n", port);

return;

}

UartSetBaud

在通信之前,需要设置UART的波特率,函数原型如下所示:

int32_t UartSetBaud(DevHandle handle, uint32_t baudRate);

其中,参数handle表示UART设备句柄,baudRate表示待设置的波特率值。UartSetBaud返回值为HDF_SUCCESS表示波特率设置成功,返回值为负数表示UART设置波特率失败。

UartGetBaud

设置UART的波特率后,可以通过获取波特率接口来查看UART当前的波特率。函数原型如下所示:

int32_t UartGetBaud(DevHandle handle, uint32_t *baudRate);

其中,参数handle表示UART设备句柄,baudRate表示待设置的波特率值。UartSetBaud返回值为HDF_SUCCESS表示获取波特率成功,返回值为负数表示UART获取波特率失败。

UartSetAttribute

在通信之前,需要设置UART的设备属性。函数原型如下所示:

int32_t UartSetAttribute(DevHandle handle, struct UartAttribute *attribute);

其中,handle表示UARt设备句柄,attribute表示待设置的设备属性。UartSetAttribute返回值为HDF_SUCCESS表示UART设置属性成功,返回值为负数表示UART设置设备属性失败。

UartGetAttribute

设置UART的设备属性后,可以通过获取设备属性接口来查看UART当前的设备属性。函数原型如下所示:

int32_t UartGetAttribute(DevHandle handle, struct UartAttribute *attribute);

其中,handle表示UART设备句柄,attribute表示接收UART设备属性的指针。UartGetAttribute返回值为HDF_SUCCESS表示UART获取属性成功,返回值为负数表示UART获取设备属性失败。

UartSetTransMode

在通信之前,需要设置UART的传输模式。函数原型如下所示:

int32_t UartSetTransMode(DevHandle handle, enum UartTransMode mode);

其中,handle表示UART设备句柄,mode表示待设置的传输模式。UartSetTransMode返回值为HDF_SUCCESS表示UART设置传输模式成功,返回值返回负数表示UART设置传输模式失败。

UartWrite

向UART设备写入指定长度的数据。函数原型如下所示:

int32_t UartWrite(DevHandle handle, uint8_t *data, uint32_t size);

其中,handle表示UART设备句柄,data表示待写入数据的指针,size表示待写入数据的长度。

UartWrite返回值为HDF_SUCCESS表示UART写数据成功,返回值为负数表示UART写数据失败。

UartRead

从UART设备中读取指定长度的数据,函数原型如下所示:

int32_t UartRead(DevHandle handle, uint8_t *data, uint32_t size);

其中,参数handle表示UART设备句柄,data表示接收读取数据的指针,size表示待读取数据的长度。UartRead返回值为非负数表示UART读取到的数据长度,返回值为负数,表示UART读取数据失败。

UartClose

UART通信完成之后,需要销毁UART设备句柄,函数原型如下所示:

void UartClose(DevHandle handle);

其中,参数handle表示UART设备句柄。

6.4.2 编写应用测试APP

使用UART的一般流程如下所示:

wKgZPGfiHHKAYqsvAABirai0hPA094.png

接下来编写应用测试文件uart_test.c,完整代码如下所示:

#include "stdio.h"

#include "stdlib.h"

#include "unistd.h"

#include "hdf_base.h"

#include "hdf_io_service.h"

#include "hilog/log.h"

#include "uart_if.h" // 假设这个头文件包含了所有UART相关函数的声明和宏定义

#define STRING_MAXSIZE 100

#define HDF_SUCCESS 0

// 假设这些宏在uart_if.h中定义

#ifndef PRINT_ERROR

#define PRINT_ERROR(...) fprintf(stderr, __VA_ARGS__)

#endif

#ifndef PRINT_INFO

#define PRINT_INFO(...) printf(__VA_ARGS__)

#endif

int main(int argc, char* argv[])

{

DevHandle handle = NULL;

struct UartAttribute attribute;

int32_t ret = 0;

uint8_t wbuff[STRING_MAXSIZE] = "HelloWorld";

uint8_t rbuff[STRING_MAXSIZE] = {0}; // 初始化接收缓冲区为0

uint32_t m_uart_port = atoi(argv[1]); // UART端口的标识符

uint32_t m_uart_baudrate = 115200; // UART的波特率

// 初始化UART属性

attribute.dataBits = UART_ATTR_DATABIT_8; // UART传输数据位宽,一次传输8个bit

attribute.parity = UART_ATTR_PARITY_NONE; // UART传输数据无校检

attribute.stopBits = UART_ATTR_STOPBIT_1; // UART传输数据停止位为1位

attribute.rts = UART_ATTR_RTS_DIS; // UART禁用RTS

attribute.cts = UART_ATTR_CTS_DIS; // UART禁用CTS

attribute.fifoRxEn = UART_ATTR_RX_FIFO_EN; // UART使能RX FIFO

attribute.fifoTxEn = UART_ATTR_TX_FIFO_EN; // UART使能TX FIFO

// 打开UART设备

handle = UartOpen(m_uart_port);

if (handle == NULL) {

PRINT_ERROR("UartOpen: open uart port %u failed!\n", m_uart_port);

return -1;

}

PRINT_INFO("UartOpen successful and uart port = %u\n", m_uart_port);

// 设置UART波特率

ret = UartSetBaud(handle, m_uart_baudrate);

if (ret != HDF_SUCCESS) {

PRINT_ERROR("UartSetBaud: set baud failed, ret %d\n", ret);

goto ERR;

}

PRINT_INFO("UartSetBaud successful and uart baudrate = %u\n", m_uart_baudrate);

// 设置UART设备属性

ret = UartSetAttribute(handle, &attribute);

if (ret != HDF_SUCCESS) {

PRINT_ERROR("UartSetAttribute: set attribute failed, ret %d\n", ret);

goto ERR;

}

PRINT_INFO("UartSetAttribute successful\n");

// 获取UART设备属性(可选)

ret = UartGetAttribute(handle, &attribute);

if (ret != HDF_SUCCESS) {

PRINT_ERROR("UartGetAttribute: get attribute failed, ret %d\n", ret);

goto ERR;

}

PRINT_INFO("UartGetAttribute successful\n");

// 设置UART传输模式为阻塞模式

ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK);

if (ret != HDF_SUCCESS) {

PRINT_ERROR("UartSetTransMode: set trans mode failed, ret %d\n", ret);

goto ERR;

}

PRINT_INFO("UartSetTransMode successful\n");

// 向UART设备写入数据

ret = UartWrite(handle, wbuff, (uint32_t)strlen((char *)wbuff));

if (ret != HDF_SUCCESS) {

PRINT_ERROR("UartWrite: write data failed, ret %d\n", ret);

goto ERR;

}

PRINT_INFO("UartWrite successful and wbuff = %s\n", wbuff);

// 从UART设备读取数据

do{

ret = UartRead(handle, rbuff, STRING_MAXSIZE);

if (ret < 0) {

PRINT_ERROR("UartRead: read data failed, ret %d\n", ret);

goto ERR;

}

sleep(1);

} while (!ret);

rbuff[ret] = '\0'; // 确保字符串以null结尾(如果读取的是文本数据)

PRINT_INFO("UartRead successful and rbuff = %s\n", rbuff);

ERR:

// 关闭UART设备句柄(确保在handle非空时关闭)

if (handle != NULL) {

UartClose(handle);

}

return ret;

}

接下来编写应用APP的GN文件BUILD.gn,代码内容如下所示:

HDF_FRAMEWORKS = "//drivers/hdf_core/framework"

HDF_ADAPTER = "//drivers/hdf_core/adapter"

import("//build/ohos.gni")

import("$HDF_ADAPTER/uhdf2/uhdf.gni")

print("demos: compile uart_test")

ohos_executable("uart_test"){

sources = ["uart_test.c"]

include_dirs = [

"$HDF_FRAMEWORKS/include",

"$HDF_FRAMEWORKS/include/core",

"$HDF_FRAMEWORKS/include/osal",

"$HDF_FRAMEWORKS/include/platform",

"$HDF_FRAMEWORKS/include/utils",

"$HDF_ADAPTER/uhdf2/ipc/include",

"$HDF_ADAPTER/uhdf2/osal/include",

"//base/hiviewdfx/hilog/interfaces/native/innerkits/include",

"//third_party/bounds_checking_function/include",

]

external_deps = [

"c_utils:utils",

"hdf_core:libhdf_platform",

"hdf_core:libhdf_utils",

"hilog:libhilog",

]

cflags = [

"-Wall",

"-Wextra",

"-Werror",

"-Wno-format",

"-Wno-format-extra-args",

]

part_name = "demos"

install_enable = true

}

6.5 编译源码

重新编译Openharmony4.1源码,如下所示:

./build.sh --product-name rk3568 --ccache

或者单独编译部件

./build.sh --product-name rk3568 --build-target demos --ccache

编译之后,在源码out/rk3568/topeet目录下生成编译产物,如下图所示:

wKgZPGfiHHKAUAcBAACq8tnvd_4501.png

6.6 UART测试

将编译好的镜像全部进行烧写,镜像在源码根目录out/rk3568/packages/phone/images/目录下。

wKgZPGfiHHOAGh1gAAFnPCRoqWw670.png

烧写完成之后,连接串口工具,本小节将要测试串口9,对应的设备节点是/dev/HDF_PLATFORM_UART_9。

作者使用usb转TTL(需要自行准备)来进行测试,如下图所示:

wKgZO2fiHHKAcWYrAAD-74tTnVs242.png

串口9在开发板底板的背面,如下图所示,USB转TTL的RXD要使用导线连接到开发板串口9的UART9_TX_M1,USB转TTL的TXD要使用导线连接到开发板串口9的UART9_RX_M1,USB转TTL的地接到GND。

wKgZPGfiHHOAG4bIAAGDLEo4pI0660.png

电脑上打开串口助手,选择串口4对应的串口号和波特率,注意:默认波特率为115200!

打开串口,如下图所示:

wKgZPGfiHHWAST10AAGWnpvze5c571.png

输入以下命令运行测试程序发送数据和接收数据,发送的数据为112233445678,数据信息可以自定义。

uart_test 9

wKgZPGfiHHOAUYpsAACjlUDZBP0056.png

串口软件接收到字符串“HelloWorld”

wKgZO2fiHHOAERN5AADtV3DHUcA509.png

然后在串口软件发送数据“112233445678”,如下图所示:

wKgZO2fiHHOASak2AADyTgjdUuU249.png

串口终端收到发送的字符串,如下图所示:

wKgZO2fiHHOAOwRRAADoXkc6OQo907.png

至此,串口实验完结。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 开发板
    +关注

    关注

    25

    文章

    5257

    浏览量

    99691
  • OpenHarmony
    +关注

    关注

    25

    文章

    3781

    浏览量

    17278
  • RK3568
    +关注

    关注

    4

    文章

    549

    浏览量

    5643
  • 迅为电子
    +关注

    关注

    0

    文章

    47

    浏览量

    105
收藏 人收藏

    相关推荐

    RK3568开发板驱动指南Linux中通用SPI设备驱动

    RK3568开发板驱动指南Linux中通用SPI设备驱动
    的头像 发表于 01-23 11:02 2153次阅读
    <b class='flag-5'>迅</b><b class='flag-5'>为</b><b class='flag-5'>RK3568</b><b class='flag-5'>开发板</b><b class='flag-5'>驱动</b>指南Linux中通用SPI设备<b class='flag-5'>驱动</b>

    北京RK3568开发板OpenHarmony系统南向驱动开发内核HDF驱动框架架构

    北京RK3568开发板OpenHarmony系统
    的头像 发表于 03-11 14:13 772次阅读
    <b class='flag-5'>北京</b><b class='flag-5'>迅</b><b class='flag-5'>为</b><b class='flag-5'>RK3568</b><b class='flag-5'>开发板</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>系统</b><b class='flag-5'>南向</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>内核<b class='flag-5'>HDF</b><b class='flag-5'>驱动</b>框架架构

    鸿蒙OpenHarmony南向/北向快速开发教程-RK3568开发板

    大家期待已久的RK3568开发板终于迎来了鸿蒙4.1系统的强势支持!想知道如何实现快速
    发表于 07-23 10:44

    RK3568开发板OpenHarmony配置HDF驱动控制LED-新增 topeet子系统

    程序目录 ├── led_driver.c:内核 LED HDF 驱动程序 └── Makefile:内核 LED HDF 驱动编译脚本 更多内容可以关注:
    发表于 01-13 15:59

    RK3568开发板OpenHarmonyHDF驱动控制LED-编写内核 LED HDF 驱动程序

    接下来编译 LED 驱动,该驱动用于在基于华为设备框架(HDF)的系统中控制 LED 灯的开关,完整代码如下所示: 更多内容可以关注:
    发表于 01-17 15:13

    RK3568开发板OpenHarmonyHDF驱动控制LED-添加内核编译

    编译内核时将该 HDF 驱动编译到镜像中,接下来编写驱动编译脚本 Makefile,代码如下所示: 加入编译体系,填加模块目录到 drivers/hdf_core/adapter/kh
    发表于 01-22 10:35

    RK3568开发板鸿蒙OpenHarmony系统固件烧写步骤

    1、RK3568开发板鸿蒙OpenHarmony系统
    发表于 08-26 17:45

    【教程上新】基于iTOP-RK3568开发板的OpenCV开发手册

    【教程上新】基于iTOP-RK3568开发板的OpenCV开发手册
    的头像 发表于 02-08 15:22 1295次阅读
    【教程上新】基于<b class='flag-5'>迅</b><b class='flag-5'>为</b><b class='flag-5'>iTOP-RK3568</b><b class='flag-5'>开发板</b>的OpenCV<b class='flag-5'>开发</b>手册

    北京itop-RK3568开发板驱动开发指南

    iTOP-RK3568开发板驱动开发指南》更新,本次更新内容对应的是驱动(第六期_平台总线_全新升级)视频,后续资料会不断更新,不断完善,
    发表于 08-29 16:32 39次下载

    RK3568开发板驱动开发指南-输入子系统

    RK3568开发板驱动开发指南-输入子系统
    的头像 发表于 02-23 15:11 1141次阅读
    <b class='flag-5'>迅</b><b class='flag-5'>为</b><b class='flag-5'>RK3568</b><b class='flag-5'>开发板</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>指南-输入子<b class='flag-5'>系统</b>

    北京RK3568开发板嵌入式学习之Linux驱动全新更新-CAN+

    北京RK3568开发板嵌入式学习之Linux驱动全新更新-CAN+
    的头像 发表于 09-04 15:29 767次阅读
    <b class='flag-5'>北京</b><b class='flag-5'>迅</b><b class='flag-5'>为</b><b class='flag-5'>RK3568</b><b class='flag-5'>开发板</b>嵌入式学习之Linux<b class='flag-5'>驱动</b>全新更新-CAN+

    iTOP-RK3568/RK3588开发板获麒麟软件适配认证

    iTOP-RK3568/RK3588开发板获麒麟软件适配认证
    的头像 发表于 10-18 14:56 857次阅读
    <b class='flag-5'>迅</b><b class='flag-5'>为</b><b class='flag-5'>iTOP-RK3568</b>/<b class='flag-5'>RK</b>3588<b class='flag-5'>开发板</b>获麒麟软件适配认证

    北京iTOP-RK3568OpenHarmony系统南向驱动开发GPIO基础知识

    北京iTOP-RK3568OpenHarmony系统南向
    的头像 发表于 03-06 11:23 287次阅读
    【<b class='flag-5'>北京</b><b class='flag-5'>迅</b><b class='flag-5'>为</b>】<b class='flag-5'>iTOP-RK3568OpenHarmony</b><b class='flag-5'>系统</b><b class='flag-5'>南向</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>GPIO基础知识

    北京iTOP-RK3568开发板OpenHarmony系统南向驱动开发-HDF驱动配置LED

    北京iTOP-RK3568开发板OpenHarmony
    的头像 发表于 03-14 14:41 250次阅读
    <b class='flag-5'>北京</b><b class='flag-5'>迅</b><b class='flag-5'>为</b><b class='flag-5'>iTOP-RK3568</b><b class='flag-5'>开发板</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>系统</b><b class='flag-5'>南向</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b><b class='flag-5'>实</b><b class='flag-5'>操</b>-<b class='flag-5'>HDF</b><b class='flag-5'>驱动</b><b class='flag-5'>配置</b>LED

    北京iTOP-RK3568开发板OpenHarmony系统南向驱动开发-第4章 UART基础知识

    北京iTOP-RK3568开发板OpenHarmony
    的头像 发表于 03-17 15:50 207次阅读
    【<b class='flag-5'>北京</b><b class='flag-5'>迅</b><b class='flag-5'>为</b>】<b class='flag-5'>iTOP-RK3568</b><b class='flag-5'>开发板</b><b class='flag-5'>OpenHarmony</b><b class='flag-5'>系统</b><b class='flag-5'>南向</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>-第4章 <b class='flag-5'>UART</b>基础知识