【FFH】OpenHarmony设备开发(三)- 小熊派Nano3.1系统复现串口 原创 精华
@[toc]
前言
当前小熊派Nano官方给的源码是OpenHarmony1.0,而OpenHarmony2.x和3.x都有对轻量化系统增加了新的特性,因此想尝试一下为Nano板烧录OpenHarmony3.1的系统(虽然都没用上新特性emm),并复现串口收发demo.
OpenHarmony2.x和3.x新增特性:
- 新增轻量级内核能力增强,包括文件系统增强、内核调试工具增强支持、内核模块支持可配置、三方芯片适配支持、支持ARM9架构等。
- 轻量级图形能力增强支持,包括支持多语言字体对齐、支持显示控件轮廓、支持点阵字体、供统一多后端框架支持多芯片平台等。
- DFX能力增强支持,包括HiLog功能增强、HiEvent功能增强,提供轻量级系统信息dump工具、提供重启维侧框架等。
- AI能力增强支持,包括新增linux内核适配支持、AI引擎支持基于共享内存的数据传输。
- 新增轻量级分布式能力增强,支持从轻量级系统启动标准系统上的Ability。
- 软总线能力增强支持,提供认证通道传输能力,用于设备绑定。
- 轻量级全球化能力增强支持,新增31种语言支持。
- 轻量系统上新增权限属性字段及其写入接口,上层应用可通过该字段实现相关业务。
- HiStreamer轻量级支持可定制的媒体管线框架、Linux版本init支持热插拔、OS轻内核&驱动启动优化、快速启动能力支持。
烧录准备
烧录前提是我们有3.1的源码以及编译后的可烧录文件.由于ubuntu上的下载烧录工作过于繁杂,本次主要借助DevEco Device Tool工具进行下载以及烧录适用于Hi3861芯片的3.1轻量系统源码.
工具介绍
HUAWEI DevEco Device Tool是OpenHarmony面向智能设备开发者提供的一站式集成开发环境,支持OpenHarmony的组件按需定制,支持代码编辑、编译、烧录和调试等功能,支持C/C++语言,以插件的形式部署在Visual Studio Code上。
DevEco Device Tool官方文档:
https://device.harmonyos.com/cn/docs/documentation/guide/service_introduction-0000001050166905
具体操作
主页->新建工程->选择OpenHarmony源码->OpenHarmony样例->WLAN连接类产品->确认
烧录样例
本次将在3.1系统上复现Nano官方1.0系统里带的串口UART样例.
分析样例
首先分析官方给出的串口样例(因为在不同系统中的线程创建步骤相同,因此省略线程创建),官方给出的串口样例主要操作是初始化串口,发送数据,接收数据
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "wifiiot_errno.h"
#include "wifiiot_gpio.h"
#include "wifiiot_gpio_ex.h"
#include "wifiiot_uart.h"
#define UART_TASK_STACK_SIZE 1024 * 8
#define UART_TASK_PRIO 25
#define UART_BUFF_SIZE 1000
static const char *data = "Hello, BearPi!\r\n";
static void UART_Task(void)
{
uint8_t uart_buff[UART_BUFF_SIZE] = {0};
uint8_t *uart_buff_ptr = uart_buff;
uint32_t ret;
//串口属性
WifiIotUartAttribute uart_attr = {
//传输比特率: 9600
.baudRate = 9600,
//数据长度: 8bits
.dataBits = 8,
.stopBits = 1,
.parity = 0,
};
//Initialize uart driver
ret = UartInit(WIFI_IOT_UART_IDX_1, &uart_attr, NULL);
if (ret != WIFI_IOT_SUCCESS)
{
printf("Failed to init uart! Err code = %d\n", ret);
return;
}
printf("UART Test Start\n");
while (1)
{
printf("=======================================\r\n");
printf("*************UART_example**************\r\n");
printf("=======================================\r\n");
//通过串口1发送数据
UartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)data, strlen(data));
//通过串口1接收数据
UartRead(WIFI_IOT_UART_IDX_1, uart_buff_ptr, UART_BUFF_SIZE);
printf("Uart1 read data:%s", uart_buff_ptr);
usleep(1000000);
}
}
对比头文件
我们首先关注引用头文件,小熊派官方demo引用的头文件分别是"wifiiot_errno.h"
"wifiiot_gpio.h"
"wifiiot_gpio_ex.h"
"wifiiot_uart.h"
,这几个头文件都保存在//base/iot_hardware/interfaces/kits/wifiiot_lite
路径下
3.1轻量系统中相关的头文件则保存在了//base/iot_hardware/peripheral/interfaces/kits
不同版本的系统的头文件名称会有略微不同,提供的API接口名称也会有所不同,但是通过一个个比对还是可以发现,虽然API接口名称不同,但最终的操作函数还是相同的,实现的目的还是相同的.
对比API接口
下面对比一下UART的init接口,1.0系统提供的是UartInit(WifiIotUartIdx id, const WifiIotUartAttribute *param, const WifiIotUartExtraAttr *extraAttr);
而3.1系统提供的是IoTUartInit(unsigned int id, const IotUartAttribute *param);
能发现这两个函数最终指向的操作函数hi_uart_init
都是相同的,如下图对比:
通过比较两个版本的API接口,可以发现以下的API接口是对应关系:
1.0系统的API接口 | 3.1系统的API接口 |
---|---|
UartInit | IoTUartInit |
UartRead | IoTUartRead |
UartWrite | IoTUartWrite |
WifiIotUartAttribute | IotUartAttribute |
PS:3.1系统中没有WifiIotUartIdx
列举,我们从1.1系统中的列举(如下)可以得知,我们所要用到的串口序号为1.因此我们在接下来的编写代码中,直接用1作为串口序号使用.
typedef enum {
/** Physical port 0 */
WIFI_IOT_UART_IDX_0,
/** Physical port 1 */
WIFI_IOT_UART_IDX_1,
/** Physical port 2 */
WIFI_IOT_UART_IDX_2,
/** Maximum value */
WIFI_IOT_UART_IDX_MAX
}WifiIotUartIdx;
编写代码
在该路径applications/sample/wifi-iot/app
下创建源代码文件夹,并在里面创建一个.c源文件和BUILD.gn.
.c源文件:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_uart.h"
static const char *data = "Hello, BearPi Nano!!!!!\r\n";
static void UART_Task(void)
{
uint8_t uart_buff[1000] = {0};
uint8_t *uart_buff_ptr = uart_buff;
uint32_t ret;
IotUartAttribute uart_attr = {
// baud_rate: 9600
.baudRate = 9600,
// data_bits: 8bits
.dataBits = 8,
.stopBits = 1,
.parity = 0,
};
// Initialize uart driver
ret = IoTUartInit(1, &uart_attr);
if (ret != 0)
{
printf("Failed to init uart! Err code = %d\n", ret);
return;
}
printf("UART Test Start\n");
while (1)
{
printf("=======================================\r\n");
printf("*************UART_example**************\r\n");
printf("=======================================\r\n");
//通过串口1发送数据
IoTUartWrite(1, (unsigned char *)data, strlen(data));
(void)memset_s(uart_buff_ptr, sizeof(uart_buff_ptr), 0, sizeof(uart_buff_ptr));
//通过串口1接收数据
IoTUartRead(1, uart_buff_ptr, 1000);
printf("Uart1 read data:%s", uart_buff_ptr);
usleep(1000000);
}
}
static void UART_ExampleEntry(void)
{
osThreadAttr_t attr;
attr.name = "UART_Task";
attr.attr_bits = 0U;
attr.cb_mem = NULL;
attr.cb_size = 0U;
attr.stack_mem = NULL;
attr.stack_size = 1024 * 8;
attr.priority = 25;
if (osThreadNew((osThreadFunc_t)UART_Task, NULL, &attr) == NULL)
{
printf("[ADCExample] Falied to create UART_Task!\n");
}
}
SYS_RUN(UART_ExampleEntry);
BUILD.gn编译脚本:
static_library("uart_example") {
sources = [
"uart.c"
]
include_dirs = [
"//utils/native/lite/include",
"//kernel/liteos_m/components/cmsis/2.0",
"//base/iot_hardware/interfaces/kits/wifiiot_lite",
"//ohos_bundles/@ohos/iot_controller/interfaces/kits",
]
}
最后修改app路径下的BUILD.gn,添加编译UART案例
编译,烧录
随后就是老一套,连接Nano板,编译,烧录.具体操作可以参考 https://ost.51cto.com/posts/14773
效果
将Nano的RX和TX短接,便可实现自己的收发数据,打开终端查看效果
现在OpenHarmony已经到3.x,如果教程还使用1.x的代码确认会出现很多问题,也感谢楼主提供思路
虽然平时没感觉,但一晃OpenHarmony也更新到3.0的,也希望厂商们努力跟上吧
3.0已经过了
作者能独立复现已经很厉害了