#openharmony # #uart# #RK3568 DAYU200# #源码:官方release 4.0#


一、驱动适配

首先查看厂商是否声明了节点:

在 vendor/hihope/rk3568/hdf_config/khdf/device_info/device_info.hcs 中确认设备节点:

OpenHarmony使用UART串口收发数据_RK3568

在 vendor/hihope/rk3568/hdf_config/khdf/platform/rk3568_uart_config.hcs  

OpenHarmony使用UART串口收发数据_DAYU200_02

在 drivers/hdf_core/adapter/khdf/linux/platform/uart/uart_adapter.c 编写了对接linux驱动的代码

OpenHarmony使用UART串口收发数据_OpenHarmony_03

对设备节点做好定义之后,就可以写串口读写代码了。


二、串口读写

1、uart代码

参考官方文档:https://docs.openharmony.cn/pages/v4.1/zh-cn/device-dev/driver/driver-platform-uart-des.md

uart_test.c文件:

#include <stdio.h>
#include <stdlib.h>    //goto函数
#include <stdint.h>    //unint8_t
#include <unistd.h>    //sleep()  //s

//#include "hdf_log.h"    //路径:    "//drivers/hdf_core/interfaces/inner_api/utils",
#include "uart_if.h"    //路径:    "//drivers/hdf_core/framework/include/platform",

// static int32_t UartTestSample(void)
// {

// }

int main(){
    printf("uart_test begin\r\n");

    printf("---------------------------\n");

    int32_t ret;
    uint32_t port;
    uint32_t baud;
    DevHandle handle = NULL;
    uint8_t wbuff[5] = { 1, 2, 3, 4, 5 };
    uint8_t rbuff[5] = { 0 };
    struct UartAttribute attribute;

    attribute.dataBits = UART_ATTR_DATABIT_7;                  // UART传输数据位宽,一次传输7个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

    port = 3;                                                  // UART设备端口号,要填写实际平台上的端口号

    handle = UartOpen(port);                                   // 获取UART设备句柄
    if (handle == NULL) {
        printf("UartOpen(port) failed \r\n");
        return HDF_FAILURE;
    }

    ret = UartSetBaud(handle, 9600);                           // 设置UART波特率为9600
    if (ret != 0) {
        printf("UartSetBaud: set baud failed, ret %d\n", ret);
        goto ERR;
    }
    printf("UartOpen successful and uart port = %d\n",port);

    ret = UartGetBaud(handle, &baud);                          // 获取UART波特率
    if (ret != 0) {
        printf("UartGetBaud: get baud failed, ret %d\n", ret);
        goto ERR;
    }
    printf("UartSetBaud successful and uart baudrate = %d\n", baud);

    ret = UartSetAttribute(handle, &attribute);                // 设置UART设备属性
    if (ret != 0) {
        printf("UartSetAttribute: set attribute failed, ret %d\n", ret);
        goto ERR;
    }
    printf("UartSetAttribute successful\n");

    ret = UartGetAttribute(handle, &attribute);                // 获取UART设备属性
    if (ret != 0) {
        printf("UartGetAttribute: get attribute failed, ret %d\n", ret);
        goto ERR;
    }
    printf("UartGetAttribute successful\n");


    ret = UartSetTransMode(handle, UART_MODE_RD_BLOCK);     // 设置UART传输模式为非阻塞模式
    if (ret != 0) {
        printf("UartSetTransMode: set trans mode failed, ret %d\n", ret);
        goto ERR;
    }
    printf("UartSetTransMode successful\n");

    ret = UartWrite(handle, wbuff, 5);                         // 向UART设备写入5字节的数据
    if (ret != 0) {
        printf("UartWrite: write data failed, ret %d\n", ret);
        goto ERR;
    }
    //printf("UartWrite successful and wbuff:  %u\n",wbuff);       //这里输出的为整型,所以引用符号应为d
    //printf(wbuff);
     for(int i=0;i<5;i++){
        printf("write:%hhu\r\n",wbuff[i]);
     }

    // ret = UartRead(handle, rbuff, 5);                          // 从UART设备读取5字节的数据
    // if (ret < 0) {
    //     printf("UartRead: read data failed, ret %d\n", ret);
    //     goto ERR;
    // }
    // //printf("UartRead successful and rbuff:   %u\n",rbuff);
    // //printf(rbuff);
    //  for(int i=0;i<5;i++){
    //     printf("%u",rbuff[i]);
    //  }
    
    int j=1;
     while(1){
        ret=UartRead(handle, rbuff, 5);
        if(ret<0){
            printf("read fail\r\n");
            goto ERR;
        }
        if(ret==-1||ret==0){
            continue;    //如果没读到,那就跳出循环再读
        }
        printf("readlen=:%d\n",ret);
        for(int i=0;i<ret;i++){
            printf("read:%02x\r\n",rbuff[i]); //按十六进制输出
        }
        j++;
        printf("\n");
        usleep(10*1000); //sleep 10ms
        if(j>3)break;
     }


    printf(" function tests end\r\n");
ERR:
    UartClose(handle);                                         // 销毁UART设备句柄
    return ret;

    printf("---------------------------\n");

}

BUILD.gn   

import("//build/ohos.gni")
import("//drivers/hdf_core/adapter/uhdf2/uhdf.gni")

print("samples: compile rk3568_uart_test")
ohos_executable("A2_gcwuart") {
  sources = [ "src/uart_test.c" ]
  include_dirs = [
    "//drivers/hdf_core/framework/include/platform",
    "//third_party/bounds_checking_function/include",
  ]

  deps = []

  external_deps = [
    "c_utils:utils",
    "hdf_core:libhdf_utils",
    "hdf_core:libhdf_platform",
  ]

  cflags = [
    "-Wall",
    "-Wextra",
    "-Werror",
    "-Wno-format",
    "-Wno-format-extra-args",
  ]

  part_name = "A2_uart"
  install_enable = true
}

bundle.json

{
    "name": "@ohos/A2_uart",
    "description": "gcw uart test",
    "version": "3.1",
    "license": "Apache License 2.0",
    "publishAs": "code-segment",
    "segment": {
        "destPath": "gcw/A2_uart"
    },
    "dirs": {},
    "scripts": {},
    "component": {
        "name": "A2_uart",
        "subsystem": "gcw",
        "syscap": [],
        "features": [],
        "adapted_system_type": ["standard"],
        "rom": "100KB",
        "ram": "100KB",
        "deps": {
            "components": [
                "c_utils",
                "hdf_core"
            ],
            "third_party": []
        },
        "build": {
            "sub_component": [
                "//gcw/A2_uart:A2_gcwuart"
            ],
            "inner_kits": [],
            "test": []
        }
    }
}

OpenHarmony编译按照产品-子系统-部件-模块展开,这里我们创建了A2_uart部件,这里要将其加入到编译体系中:

在build/subsystem_config.json文件中声明子系统,加入构建:  

"gcw": {
    "path": "gcw",
    "name": "gcw"
  },

在vendor/hihope/rk3568/config.json 中声明gcw子系统的各个部件,加入编译。

{
      "subsystem": "gcw",
      "components": [
        {
          "component": "A1_helloworld",
          "features": []
        },
        {
          "component": "B1_helloworld",
          "features": []
        },
        {
          "component": "A2_uart",
          "features": []
        },
        {
          "component": "A3_gpio",
          "features": []
        }
      ]
    },


2、文件编译

编译日志文件位置: find /root/code/release_4_0/rk3568/out/rk3568/build.log

取消远程编译

./compile_cancel.sh

开始远程编译(全量编译)

./compile.sh ./build.py -p rk3568

快速编译(在不更改gn文件时可用

./compile.sh ./build.py -p rk3568 --fast-rebuild

组件编译

./compile.sh ./build.sh --product-name rk3568 --build-target A2_uart

注:./compile.sh 启用后台主机编译

编译部件、模块之前须全编译一次。

更多命令参考:https://blog.51cto.com/harmonyos/6049040

编译过程参考:https://blog.51cto.com/harmonyos/6521493

3、镜像文件下载

压缩镜像文件

tar -cvzf gcw_images.tar.gz images/

上传镜像文件:

./upload.sh code/release_4_0/rk3568/out/rk3568/packages/phone/gcw_images.tar.gz

下载镜像文件:

/root/code/url.txt

取消自动息屏:

hdc shell power-shell setmode 602

注:

在phone目录下压缩整个images。tar -cvzf images.tar.gz images/ 为压缩后的文件名

这样操作的话,3G的镜像文件最后被压缩为400M,还能很快下载完成。

4、镜像文件

镜像文件位置:/root/code/release_4_0/rk3568/out/rk3568/packages/phone/images

镜像地址和功能信息:

地址

名字

文件名

大小

功能

0x0000_0000

Loader

MiniLoaderAll.bin

455,104 

加载操作系统内核

0x0000_0000

Parameter

parameter.txt

655 

镜像配置信息

0x0000_2000

Uboot

uboot.img

4,194,304 

引导启动程序

0x0000_4000

misc

---

---

系统配置信息

0x0000_6000

resource

resource.img

3,794,944 

系统资源文件

0x0000_9000

Boot_linux

boot_linux.img

67,108,864 

linux内核启动程序

0x0003_9000

ramdisk

ramdisk.img

2,267,249 

内存磁盘暂存启动

0x0003_B000

System

system.img

1,610,608,640 

ohos系统

0x0043_B000

Vendor

vendor.img

268,431,360 

厂商软件和驱动

0x0063_B000

sys-prod

sys_prod.img

268,431,360 

系统文件区

0x0065_4000

chip-prod

chip_prod.img

52,428,800 

芯片配置文件

0x0066_D000

updater

updater.img

10,307,800 

系统更新区

0x0067_D000

Userdata

userdata.img

1,468,006,400 

用户数据

5、小结

可以看到,编译后生成的可执行文件在:code/release_4_0/rk3568/out/rk3568/packages/phone/system/bin 中

OpenHarmony使用UART串口收发数据_OpenHarmony_04


三、设备连接

1、UT-8851连接方式

OpenHarmony使用UART串口收发数据_UART_05

OpenHarmony使用UART串口收发数据_OpenHarmony_06


2、DAYU200连接方式

OpenHarmony使用UART串口收发数据_UART_07

将连接器USB一端连接电脑,另一端三根线连接至开发板【UART_RX_M1、UART_TX_M1、GND】。


三、程序执行

1、打开hdc调试

打开终端软件,这里直接用DEVECO,输入hdc targets list,会显示连接的设备:

OpenHarmony使用UART串口收发数据_OpenHarmony_08

然后查看system目录可以看到烧录的uart可执行文件。

2、执行程序

OpenHarmony使用UART串口收发数据_UART_09

OpenHarmony使用UART串口收发数据_OpenHarmony_10

可以看到,能够收发数据。数据错误是因为输出显示格式问题。


四、总结

注意编译构建,依赖的部件、模块需要声明,编译命令要正确使用。