瑞芯微RK3568芯片是一款定位中高端的通用型SOC,采用22nm制程工藝,搭載一顆四核Cortex-A55處理器和Mali G52 2EE 圖形處理器。RK3568 支持4K 解碼和 1080P 編碼,支持SATA/PCIE/USB3.0 外圍接口。RK3568內(nèi)置獨(dú)立NPU,可用于輕量級(jí)人工智能應(yīng)用。RK3568 支持安卓 11 和 linux 系統(tǒng),主要面向物聯(lián)網(wǎng)網(wǎng)關(guān)、NVR 存儲(chǔ)、工控平板、工業(yè)檢測(cè)、工控盒、卡拉 OK、云終端、車載中控等行業(yè)。
?

【本文摘自】【北京迅為】iTOP-RK3568OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)
【相關(guān)視頻】OpenHarmony學(xué)習(xí)開發(fā)系列教程(第1期 北向基礎(chǔ)篇一)
OpenHarmony學(xué)習(xí)開發(fā)系列教程(第2期 南向基礎(chǔ)篇一)
第6章 實(shí)操-HDF驅(qū)動(dòng)配置UART
6.1 修改HCS配置
對(duì)于不同的平臺(tái),需要在對(duì)應(yīng)的平臺(tái)目錄修改對(duì)應(yīng)的hcs文件,接下來示例為在rk3568下新增uart4 uart9 uart7的修改方法。
修改vendor/hihope/rk3568/hdf_config/khdf/device_info/device_info.hcs文件,device_info.hcs中添加以下內(nèi)容:
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";
}
在配置過程中要注意以下幾點(diǎn):
1 device3,device4,device5是自定義的,可以根據(jù)實(shí)際情況修改
2 policy表示服務(wù)策略,取值為0時(shí),表示不發(fā)布服務(wù),取值為1時(shí)表示向內(nèi)核態(tài)發(fā)布服務(wù),取值為2時(shí)表示向內(nèi)核用戶態(tài)發(fā)布服務(wù)
3 moduleName的值要與驅(qū)動(dòng)實(shí)現(xiàn)的HdfDriverEntry結(jié)構(gòu)體中的moduleName相同。
4 deviceMatchAttr的值表示驅(qū)動(dòng)的私有配置信息
5 serviceName表示服務(wù)名稱,服務(wù)加載成功之后會(huì)在開發(fā)板的/dev/目錄下生成節(jié)點(diǎn)。例如HDF_PLATFORM_UART_9后面跟著的數(shù)據(jù)9是UartOpen()的端口號(hào)
6.2 配置rk3568_uart_config.hcs
修改vendor/hihope/rk3568/hdf_config/khdf/platform/rk3568_uart_config.hcs文件,添加如下內(nèi)容,如下所示:
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";
}
在上面的配置中需要注意以下幾點(diǎn):
1 device_uart_0x0004中的后綴“0x0004”是串口編號(hào)。
2 num 與driver_name值“ttyS”組成驅(qū)動(dòng)設(shè)備名,例如ttyS4。UartOpen函數(shù)參數(shù)port,則表示上述uart設(shè)備排列序號(hào),比如num=4 的UartOpen函數(shù)port=4。
3 match_attr的名稱必須是rockchip_rk3568_uart_x,和device_info.hcs中要寫一樣。
6.3 Openharmony UART平臺(tái)驅(qū)動(dòng)
在drivers/hdf_core/adapter/khdf/linux/platform/uart/uart_adapter.c 中編寫了對(duì)接Linux UART驅(qū)動(dòng)的相關(guān)代碼,這部分不需要大家進(jìn)行修改,感興趣的話可以自己研究下uart_adapter.c文件。
6.4 UART應(yīng)用開發(fā)
6.4.1 UART驅(qū)動(dòng)API接口介紹
UART驅(qū)動(dòng)API接口如下所示,具體的API詳見drivers/hdf_core/framework/include/platform/uart_if.h文件。

UartOpen
在使用UART進(jìn)行通信時(shí),首先要調(diào)用UartOpen獲取UART設(shè)備句柄,該函數(shù)會(huì)返回指定端口號(hào)的UART設(shè)備句柄。函數(shù)原型如下所示:
DevHandle UartOpen(uint32_t port);
其中,參數(shù)port是UART設(shè)備號(hào)。UartOpen返回值為NULL表示獲取UART設(shè)備句柄失敗,正常情況下返回UART設(shè)備句柄。
假設(shè)系統(tǒng)重的UART端口號(hào)為4,獲取該UART設(shè)備句柄的示例如下所示
DevHandle handle = NULL; // UART設(shè)備句柄
uint32_t port = 4; // UART設(shè)備端口號(hào)
handle = UartOpen(port);
if (handle == NULL) {
HDF_LOGE("UartOpen: open uart_%u failed!\n", port);
return;
}
UartSetBaud
在通信之前,需要設(shè)置UART的波特率,函數(shù)原型如下所示:
int32_t UartSetBaud(DevHandle handle, uint32_t baudRate);
其中,參數(shù)handle表示UART設(shè)備句柄,baudRate表示待設(shè)置的波特率值。UartSetBaud返回值為HDF_SUCCESS表示波特率設(shè)置成功,返回值為負(fù)數(shù)表示UART設(shè)置波特率失敗。
UartGetBaud
設(shè)置UART的波特率后,可以通過獲取波特率接口來查看UART當(dāng)前的波特率。函數(shù)原型如下所示:
int32_t UartGetBaud(DevHandle handle, uint32_t *baudRate);
其中,參數(shù)handle表示UART設(shè)備句柄,baudRate表示待設(shè)置的波特率值。UartSetBaud返回值為HDF_SUCCESS表示獲取波特率成功,返回值為負(fù)數(shù)表示UART獲取波特率失敗。
UartSetAttribute
在通信之前,需要設(shè)置UART的設(shè)備屬性。函數(shù)原型如下所示:
int32_t UartSetAttribute(DevHandle handle, struct UartAttribute *attribute);
其中,handle表示UARt設(shè)備句柄,attribute表示待設(shè)置的設(shè)備屬性。UartSetAttribute返回值為HDF_SUCCESS表示UART設(shè)置屬性成功,返回值為負(fù)數(shù)表示UART設(shè)置設(shè)備屬性失敗。
UartGetAttribute
設(shè)置UART的設(shè)備屬性后,可以通過獲取設(shè)備屬性接口來查看UART當(dāng)前的設(shè)備屬性。函數(shù)原型如下所示:
int32_t UartGetAttribute(DevHandle handle, struct UartAttribute *attribute);
其中,handle表示UART設(shè)備句柄,attribute表示接收UART設(shè)備屬性的指針。UartGetAttribute返回值為HDF_SUCCESS表示UART獲取屬性成功,返回值為負(fù)數(shù)表示UART獲取設(shè)備屬性失敗。
UartSetTransMode
在通信之前,需要設(shè)置UART的傳輸模式。函數(shù)原型如下所示:
int32_t UartSetTransMode(DevHandle handle, enum UartTransMode mode);
其中,handle表示UART設(shè)備句柄,mode表示待設(shè)置的傳輸模式。UartSetTransMode返回值為HDF_SUCCESS表示UART設(shè)置傳輸模式成功,返回值返回負(fù)數(shù)表示UART設(shè)置傳輸模式失敗。
UartWrite
向UART設(shè)備寫入指定長度的數(shù)據(jù)。函數(shù)原型如下所示:
int32_t UartWrite(DevHandle handle, uint8_t *data, uint32_t size);
其中,handle表示UART設(shè)備句柄,data表示待寫入數(shù)據(jù)的指針,size表示待寫入數(shù)據(jù)的長度。
UartWrite返回值為HDF_SUCCESS表示UART寫數(shù)據(jù)成功,返回值為負(fù)數(shù)表示UART寫數(shù)據(jù)失敗。
UartRead
從UART設(shè)備中讀取指定長度的數(shù)據(jù),函數(shù)原型如下所示:
int32_t UartRead(DevHandle handle, uint8_t *data, uint32_t size);
其中,參數(shù)handle表示UART設(shè)備句柄,data表示接收讀取數(shù)據(jù)的指針,size表示待讀取數(shù)據(jù)的長度。UartRead返回值為非負(fù)數(shù)表示UART讀取到的數(shù)據(jù)長度,返回值為負(fù)數(shù),表示UART讀取數(shù)據(jù)失敗。
UartClose
UART通信完成之后,需要銷毀UART設(shè)備句柄,函數(shù)原型如下所示:
void UartClose(DevHandle handle);
其中,參數(shù)handle表示UART設(shè)備句柄。
6.4.2 編寫應(yīng)用測(cè)試APP
使用UART的一般流程如下所示:

接下來編寫應(yīng)用測(cè)試文件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" // 假設(shè)這個(gè)頭文件包含了所有UART相關(guān)函數(shù)的聲明和宏定義
#define STRING_MAXSIZE 100
#define HDF_SUCCESS 0
// 假設(shè)這些宏在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}; // 初始化接收緩沖區(qū)為0
uint32_t m_uart_port = atoi(argv[1]); // UART端口的標(biāo)識(shí)符
uint32_t m_uart_baudrate = 115200; // UART的波特率
// 初始化UART屬性
attribute.dataBits = UART_ATTR_DATABIT_8; // UART傳輸數(shù)據(jù)位寬,一次傳輸8個(gè)bit
attribute.parity = UART_ATTR_PARITY_NONE; // UART傳輸數(shù)據(jù)無校檢
attribute.stopBits = UART_ATTR_STOPBIT_1; // UART傳輸數(shù)據(jù)停止位為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設(shè)備
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);
// 設(shè)置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);
// 設(shè)置UART設(shè)備屬性
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設(shè)備屬性(可選)
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");
// 設(shè)置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設(shè)備寫入數(shù)據(jù)
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設(shè)備讀取數(shù)據(jù)
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結(jié)尾(如果讀取的是文本數(shù)據(jù))
PRINT_INFO("UartRead successful and rbuff = %s\n", rbuff);
ERR:
// 關(guān)閉UART設(shè)備句柄(確保在handle非空時(shí)關(guān)閉)
if (handle != NULL) {
UartClose(handle);
}
return ret;
}
接下來編寫應(yīng)用APP的GN文件BUILD.gn,代碼內(nèi)容如下所示:
HDF_FRAMEWORKS = "http://drivers/hdf_core/framework"
HDF_ADAPTER = "http://drivers/hdf_core/adapter"
import("http://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",
"http://base/hiviewdfx/hilog/interfaces/native/innerkits/include",
"http://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
或者單獨(dú)編譯部件
./build.sh --product-name rk3568 --build-target demos --ccache
編譯之后,在源碼out/rk3568/topeet目錄下生成編譯產(chǎn)物,如下圖所示:

6.6 UART測(cè)試
將編譯好的鏡像全部進(jìn)行燒寫,鏡像在源碼根目錄out/rk3568/packages/phone/images/目錄下。

燒寫完成之后,連接串口工具,本小節(jié)將要測(cè)試串口9,對(duì)應(yīng)的設(shè)備節(jié)點(diǎn)是/dev/HDF_PLATFORM_UART_9。
作者使用usb轉(zhuǎn)TTL(需要自行準(zhǔn)備)來進(jìn)行測(cè)試,如下圖所示:

串口9在開發(fā)板底板的背面,如下圖所示,USB轉(zhuǎn)TTL的RXD要使用導(dǎo)線連接到開發(fā)板串口9的UART9_TX_M1,USB轉(zhuǎn)TTL的TXD要使用導(dǎo)線連接到開發(fā)板串口9的UART9_RX_M1,USB轉(zhuǎn)TTL的地接到GND。

在電腦上打開串口助手,選擇串口4對(duì)應(yīng)的串口號(hào)和波特率,注意:默認(rèn)波特率為115200!
打開串口,如下圖所示:

輸入以下命令運(yùn)行測(cè)試程序發(fā)送數(shù)據(jù)和接收數(shù)據(jù),發(fā)送的數(shù)據(jù)為112233445678,數(shù)據(jù)信息可以自定義。
uart_test 9

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

然后在串口軟件發(fā)送數(shù)據(jù)“112233445678”,如下圖所示:

串口終端收到發(fā)送的字符串,如下圖所示:

至此,串口實(shí)驗(yàn)完結(jié)。
-
開發(fā)板
+關(guān)注
關(guān)注
25文章
5389瀏覽量
100878 -
OpenHarmony
+關(guān)注
關(guān)注
26文章
3804瀏覽量
17849 -
RK3568
+關(guān)注
關(guān)注
5文章
562瀏覽量
5920 -
迅為電子
+關(guān)注
關(guān)注
0文章
50瀏覽量
127
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
迅為RK3568開發(fā)板驅(qū)動(dòng)指南Linux中通用SPI設(shè)備驅(qū)動(dòng)

北京迅為RK3568開發(fā)板OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)內(nèi)核HDF驅(qū)動(dòng)框架架構(gòu)

鴻蒙OpenHarmony南向/北向快速開發(fā)教程-迅為RK3568開發(fā)板
迅為RK3568開發(fā)板篇OpenHarmony配置HDF驅(qū)動(dòng)控制LED-新增 topeet子系統(tǒng)
迅為RK3568開發(fā)板篇OpenHarmony實(shí)操HDF驅(qū)動(dòng)控制LED-編寫內(nèi)核 LED HDF 驅(qū)動(dòng)程序
迅為RK3568開發(fā)板篇OpenHarmony實(shí)操HDF驅(qū)動(dòng)控制LED-添加內(nèi)核編譯
迅為RK3568開發(fā)板鴻蒙OpenHarmony系統(tǒng)固件燒寫步驟
【北京迅為】itop-RK3568開發(fā)板驅(qū)動(dòng)開發(fā)指南
北京迅為RK3568開發(fā)板嵌入式學(xué)習(xí)之Linux驅(qū)動(dòng)全新更新-CAN+

【北京迅為】iTOP-RK3568OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)GPIO基礎(chǔ)知識(shí)

北京迅為iTOP-RK3568開發(fā)板OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)實(shí)操-HDF驅(qū)動(dòng)配置LED

【北京迅為】iTOP-RK3568開發(fā)板OpenHarmony系統(tǒng)南向驅(qū)動(dòng)開發(fā)-第4章 UART基礎(chǔ)知識(shí)

評(píng)論