OpenHarmony設(shè)備開發(fā)(三)- 小熊派Nano3.1系統(tǒng)復(fù)現(xiàn)串口
??想了解更多關(guān)于開源的內(nèi)容,請訪問:??
前言
當(dāng)前小熊派Nano官方給的源碼是OpenHarmony1.0,而OpenHarmony2.x和3.x都有對輕量化系統(tǒng)增加了新的特性,因此想嘗試一下為Nano板燒錄OpenHarmony3.1的系統(tǒng)(雖然都沒用上新特性emm),并復(fù)現(xiàn)串口收發(fā)demo.
OpenHarmony2.x和3.x新增特性:
- 新增輕量級內(nèi)核能力增強,包括文件系統(tǒng)增強、內(nèi)核調(diào)試工具增強支持、內(nèi)核模塊支持可配置、三方芯片適配支持、支持ARM9架構(gòu)等。
- 輕量級圖形能力增強支持,包括支持多語言字體對齊、支持顯示控件輪廓、支持點陣字體、供統(tǒng)一多后端框架支持多芯片平臺等。
- DFX能力增強支持,包括HiLog功能增強、HiEvent功能增強,提供輕量級系統(tǒng)信息dump工具、提供重啟維側(cè)框架等。
- AI能力增強支持,包括新增linux內(nèi)核適配支持、AI引擎支持基于共享內(nèi)存的數(shù)據(jù)傳輸。
- 新增輕量級分布式能力增強,支持從輕量級系統(tǒng)啟動標(biāo)準(zhǔn)系統(tǒng)上的Ability。
- 軟總線能力增強支持,提供認(rèn)證通道傳輸能力,用于設(shè)備綁定。
- 輕量級全球化能力增強支持,新增31種語言支持。
- 輕量系統(tǒng)上新增權(quán)限屬性字段及其寫入接口,上層應(yīng)用可通過該字段實現(xiàn)相關(guān)業(yè)務(wù)。
- HiStreamer輕量級支持可定制的媒體管線框架、Linux版本init支持熱插拔、OS輕內(nèi)核&驅(qū)動啟動優(yōu)化、快速啟動能力支持。
燒錄準(zhǔn)備
燒錄前提是我們有3.1的源碼以及編譯后的可燒錄文件.由于ubuntu上的下載燒錄工作過于繁雜,本次主要借助DevEco Device Tool工具進(jìn)行下載以及燒錄適用于Hi3861芯片的3.1輕量系統(tǒng)源碼。
工具介紹
HUAWEI DevEco Device Tool是OpenHarmony面向智能設(shè)備開發(fā)者提供的一站式集成開發(fā)環(huán)境,支持OpenHarmony的組件按需定制,支持代碼編輯、編譯、燒錄和調(diào)試等功能,支持C/C++語言,以插件的形式部署在Visual Studio Code上。
DevEco Device Tool官方文檔:
https://device.harmonyos.com/cn/docs/documentation/guide/service_introduction-0000001050166905。
具體操作
主頁->新建工程->選擇OpenHarmony源碼->OpenHarmony樣例->WLAN連接類產(chǎn)品->確認(rèn)。
燒錄樣例
本次將在3.1系統(tǒng)上復(fù)現(xiàn)Nano官方1.0系統(tǒng)里帶的串口UART樣例。
分析樣例
首先分析官方給出的串口樣例(因為在不同系統(tǒng)中的線程創(chuàng)建步驟相同,因此省略線程創(chuàng)建),官方給出的串口樣例主要操作是初始化串口,發(fā)送數(shù)據(jù),接收數(shù)據(jù)。
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,
//數(shù)據(jù)長度: 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發(fā)送數(shù)據(jù)
UartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)data, strlen(data));
//通過串口1接收數(shù)據(jù)
UartRead(WIFI_IOT_UART_IDX_1, uart_buff_ptr, UART_BUFF_SIZE);
printf("Uart1 read data:%s", uart_buff_ptr);
usleep(1000000);
}
}
對比頭文件
我們首先關(guān)注引用頭文件,小熊派官方demo引用的頭文件分別是"wifiiot_errno.h" "wifiiot_gpio.h" "wifiiot_gpio_ex.h" "wifiiot_uart.h",這幾個頭文件都保存在//base/iot_hardware/interfaces/kits/wifiiot_lite路徑下。
3.1輕量系統(tǒng)中相關(guān)的頭文件則保存在了//base/iot_hardware/peripheral/interfaces/kits。
不同版本的系統(tǒng)的頭文件名稱會有略微不同,提供的API接口名稱也會有所不同,但是通過一個個比對還是可以發(fā)現(xiàn),雖然API接口名稱不同,但最終的操作函數(shù)還是相同的,實現(xiàn)的目的還是相同的。
對比API接口
下面對比一下UART的init接口,1.0系統(tǒng)提供的是UartInit(WifiIotUartIdx id, const WifiIotUartAttribute *param, const WifiIotUartExtraAttr *extraAttr);而3.1系統(tǒng)提供的是IoTUartInit(unsigned int id, const IotUartAttribute *param)。
能發(fā)現(xiàn)這兩個函數(shù)最終指向的操作函數(shù)hi_uart_init都是相同的,如下圖對比:
通過比較兩個版本的API接口,可以發(fā)現(xiàn)以下的API接口是對應(yīng)關(guān)系:
1.0系統(tǒng)的API接口 | 3.1系統(tǒng)的API接口 |
UartInit | IoTUartInit |
UartRead | IoTUartRead |
UartWrite | IoTUartWrite |
WifiIotUartAttribute | IotUartAttribute |
PS:3.1系統(tǒng)中沒有WifiIotUartIdx列舉,我們從1.1系統(tǒng)中的列舉(如下)可以得知,我們所要用到的串口序號為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下創(chuàng)建源代碼文件夾,并在里面創(chuàng)建一個.c源文件和BUILD.gn。
.c源文件:
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發(fā)送數(shù)據(jù)
IoTUartWrite(1, (unsigned char *)data, strlen(data));
(void)memset_s(uart_buff_ptr, sizeof(uart_buff_ptr), 0, sizeof(uart_buff_ptr));
//通過串口1接收數(shù)據(jù)
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 = [
"http://utils/native/lite/include",
"http://kernel/liteos_m/components/cmsis/2.0",
"http://base/iot_hardware/interfaces/kits/wifiiot_lite",
"http://ohos_bundles/@ohos/iot_controller/interfaces/kits",
]
}
最后修改app路徑下的BUILD.gn,添加編譯UART案例。
編譯,燒錄
隨后就是老一套,連接Nano板,編譯,燒錄.具體操作可以參考 https://ost.51cto.com/posts/14773。
效果
將Nano的RX和TX短接,便可實現(xiàn)自己的收發(fā)數(shù)據(jù),打開終端查看效果。