OpenHarmony平臺(tái)驅(qū)動(dòng)案例--UART
想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):
一、程序介紹
本程序是基于OpenHarmony標(biāo)準(zhǔn)系統(tǒng)編寫的平臺(tái)驅(qū)動(dòng)案例:UART
詳細(xì)資料請(qǐng)參考官網(wǎng):
二、基礎(chǔ)知識(shí)
1、UART簡(jiǎn)介
UART指異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter),是通用串行數(shù)據(jù)總線,用于異步通信。該總線雙向通信,可以實(shí)現(xiàn)全雙工傳輸。
兩個(gè)UART設(shè)備的連接示意圖如下,UART與其他模塊一般用2線(圖1)或4線(圖2)相連,它們分別是:
- TX:發(fā)送數(shù)據(jù)端,和對(duì)端的RX相連。
- RX:接收數(shù)據(jù)端,和對(duì)端的TX相連。
- RTS:發(fā)送請(qǐng)求信號(hào),用于指示本設(shè)備是否準(zhǔn)備好,可接受數(shù)據(jù),和對(duì)端CTS相連。
- CTS:允許發(fā)送信號(hào),用于判斷是否可以向?qū)Χ税l(fā)送數(shù)據(jù),和對(duì)端RTS相連。
UART的2線相連:
UART的4線相連:
UART通信之前,收發(fā)雙方需要約定好一些參數(shù):波特率、數(shù)據(jù)格式(起始位、數(shù)據(jù)位、校驗(yàn)位、停止位)等。通信過(guò)程中,UART通過(guò)TX發(fā)送給對(duì)端數(shù)據(jù),通過(guò)RX接收對(duì)端發(fā)送的數(shù)據(jù)。當(dāng)UART接收緩存達(dá)到預(yù)定的門限值時(shí),RTS變?yōu)椴豢砂l(fā)送數(shù)據(jù),對(duì)端的CTS檢測(cè)到不可發(fā)送數(shù)據(jù),則停止發(fā)送數(shù)據(jù)。
2、UART驅(qū)動(dòng)開(kāi)發(fā)
(1)UART驅(qū)動(dòng)開(kāi)發(fā)接口
為了保證上層在調(diào)用UART接口時(shí)能夠正確的操作UART控制器,核心層在//drivers/hdf_core/framework/support/platform/include/uart/uart_core.h中定義了以下鉤子函數(shù),驅(qū)動(dòng)適配者需要在適配層實(shí)現(xiàn)這些函數(shù)的具體功能,并與鉤子函數(shù)掛接,從而完成適配層與核心層的交互。
UartHostMethod定義:
UartHostMethod結(jié)構(gòu)體成員的回調(diào)函數(shù)功能說(shuō)明:
(2)UART驅(qū)動(dòng)開(kāi)發(fā)步驟
UART模塊適配HDF框架包含以下四個(gè)步驟:
- 實(shí)例化驅(qū)動(dòng)入口。
- 配置屬性文件。
- 實(shí)例化UART控制器對(duì)象。
- 驅(qū)動(dòng)調(diào)試。
我們以///drivers/hdf_core/adapter/khdf/linux/platform/uart/uart_adapter.c為例(該UART驅(qū)動(dòng)是建立于Linux UART子系統(tǒng)基礎(chǔ)上創(chuàng)建)。
驅(qū)動(dòng)實(shí)例化驅(qū)動(dòng)入口
驅(qū)動(dòng)入口必須為HdfDriverEntry(在hdf_device_desc.h中定義)類型的全局變量,且moduleName要和device_info.hcs中保持一致。HDF框架會(huì)將所有加載的驅(qū)動(dòng)的HdfDriverEntry對(duì)象首地址匯總,形成一個(gè)類似數(shù)組的段地址空間,方便上層調(diào)用。 一般在加載驅(qū)動(dòng)時(shí)HDF會(huì)先調(diào)用Bind函數(shù),再調(diào)用Init函數(shù)加載該驅(qū)動(dòng)。當(dāng)Init調(diào)用異常時(shí),HDF框架會(huì)調(diào)用Release釋放驅(qū)動(dòng)資源并退出。
UART驅(qū)動(dòng)入口開(kāi)發(fā)參考:
配置屬性文件
完成驅(qū)動(dòng)入口注冊(cè)之后,需要在device_info.hcs文件中添加deviceNode信息,deviceNode信息與驅(qū)動(dòng)入口注冊(cè)相關(guān)。本例以兩個(gè)UART控制器為例,如有多個(gè)器件信息,則需要在device_info.hcs文件增加對(duì)應(yīng)的deviceNode信息。器件屬性值與核心層UartDev成員的默認(rèn)值或限制范圍有密切關(guān)系,比如Uart設(shè)備號(hào),需要在uart_config.hcs文件中增加對(duì)應(yīng)的器件屬性。
本次案例以rk3568為案例(即文件//vendor/lockzhiner/rk3568/hdf_config/khdf/device_info/device_info.hcs),添加deviceNode描述,具體修改如下:
uart_config.hcs 配置參考//vendor/lockzhiner/rk3568/hdf_config/khdf/platform/rk3568_uart_config.hcs,具體修改如下:
(3)實(shí)例化UART控制器對(duì)象
完成驅(qū)動(dòng)入口注冊(cè)之后,下一步就是以核心層UartDev對(duì)象的初始化為核心,包括驅(qū)動(dòng)適配者自定義結(jié)構(gòu)體(傳遞參數(shù)和數(shù)據(jù)),實(shí)例化UartDev成員UartHostMethod(讓用戶可以通過(guò)接口來(lái)調(diào)用驅(qū)動(dòng)底層函數(shù)),實(shí)現(xiàn)HdfDriverEntry成員函數(shù)(Bind、Init、Release)。
(4)驅(qū)動(dòng)調(diào)試
建議先在Linux下修改確認(rèn),再移植到OpenHarmony。
3、UART應(yīng)用開(kāi)發(fā)
UART模塊應(yīng)用比較廣泛,主要用于實(shí)現(xiàn)設(shè)備之間的低速串行通信,例如輸出打印信息,當(dāng)然也可以外接各種模塊,如GPS、藍(lán)牙等。
(1)接口說(shuō)明
UART模塊提供的主要接口如表1所示,具體API詳見(jiàn)//drivers/hdf_core/framework/include/platform/uart_if.h。
UART驅(qū)動(dòng)API接口功能介紹如下所示:
UartOpen
在使用UART進(jìn)行通信時(shí),首先要調(diào)用UartOpen獲取UART設(shè)備句柄,該函數(shù)會(huì)返回指定端口號(hào)的UART設(shè)備句柄。
UartOpen參數(shù)定義如下:
UartOpen返回值定義如下:
假設(shè)系統(tǒng)中的UART端口號(hào)為1,獲取該UART設(shè)備句柄的示例如下:
UartSetBaud
在通信之前,需要設(shè)置UART的波特率。
UartSetBaud參數(shù)定義如下:
UartSetBaud返回值定義如下:
UartGetBaud
設(shè)置UART的波特率后,可以通過(guò)獲取波特率接口來(lái)查看UART當(dāng)前的波特率。
UartGetBaud參數(shù)定義如下:
UartGetBaud返回值定義如下:
UartSetAttribute
在通信之前,需要設(shè)置UART的設(shè)備屬性。
UartSetAttribute參數(shù)定義如下:
UartGetAttribute返回值定義如下:
UartGetAttribute
設(shè)置UART的設(shè)備屬性后,可以通過(guò)獲取設(shè)備屬性接口來(lái)查看UART當(dāng)前的設(shè)備屬性。
UartGetAttribute參數(shù)定義如下:
UartGetAttribute返回值定義如下:
UartSetTransMode
在通信之前,需要設(shè)置UART的傳輸模式。
UartSetTransMode參數(shù)定義如下:
UartSetTransMode返回值定義如下:
UartWrite
向UART設(shè)備寫入指定長(zhǎng)度的數(shù)據(jù)。
UartWrite參數(shù)定義如下:
UartWrite返回值定義如下:
UartRead
從UART設(shè)備中讀取指定長(zhǎng)度的數(shù)據(jù)。
UartRead參數(shù)定義如下:
UartRead返回值定義如下:
UartClose
UART通信完成之后,需要銷毀UART設(shè)備句柄。
UartClose參數(shù)定義如下:
(2)開(kāi)發(fā)流程
使用UART的一般流程如下圖所示:
三、程序解析
1、準(zhǔn)備工作
查看《凌蒙派-RK3568開(kāi)發(fā)板_排針說(shuō)明表_》(即Git倉(cāng)庫(kù)的//docs/board/凌蒙派-RK3568開(kāi)發(fā)板_排針說(shuō)明表_v1.0.xlsx),具體如下:
2、Linux內(nèi)核解析
(1)創(chuàng)建Linux內(nèi)核Git
請(qǐng)參考《OpenHarmony如何為內(nèi)核打patch》(即Git倉(cāng)庫(kù)的//docs/OpenHarmony如何為內(nèi)核打patch.docx)。
(2)修改設(shè)備樹(shù)PWM7配置
修改//arch/arm64/boot/dts/rockchip/rk3568-lockzhiner-x0.dtsi(即該目錄是指已打Patch后的Linux內(nèi)核,不是OpenHarmony主目錄),具體如下所示:
(3)創(chuàng)建內(nèi)核patch
請(qǐng)參考《OpenHarmony如何為內(nèi)核打patch》(即Git倉(cāng)庫(kù)的//docs/OpenHarmony如何為內(nèi)核打patch.docx)。
(4)替換OpenHarmony的內(nèi)核patch
將制作出的kernel.patch替換到//kernel/linux/patches/linux-5.10/rk3568_patch/kernel.patch即可。
3、OpenHarmony配置樹(shù)配置
(1)device_info.hcs
//vendor/lockzhiner/rk3568/hdf_config/khdf/device_info/device_info.hcs已定義好,具體如下:
注意:
- device2是我們新增的設(shè)備節(jié)點(diǎn),給uart5使用。
- policy必須為2,表示對(duì)內(nèi)核態(tài)和用戶態(tài)提供服務(wù)。否則,應(yīng)用程序無(wú)法調(diào)用。
- HDF_PLATFORM_UART_2,后面跟著的數(shù)據(jù)“2”,是UartOpen()的端口號(hào)。
- HDF_PLATFORM_UART_2,后面跟著的數(shù)據(jù)“2”,必須是遞增的。
(2)rk3568_uart_config.hcs
//vendor/lockzhiner/rk3568/hdf_config/khdf/platform/rk3568_uart_config.hcs,具體內(nèi)容如下:
注意:
- device_uart_0x0002是新增的,為uart5準(zhǔn)備的。
- match_attr的名稱必須是rockchip_rk3568_uart_2。
4、OpenHarmony UART平臺(tái)驅(qū)動(dòng)
在//drivers/hdf_core/adapter/khdf/linux/platform/uart/uart_adapter.c已編寫對(duì)接Linux PWM驅(qū)動(dòng)的相關(guān)代碼,具體內(nèi)容如下:
該部分代碼不細(xì)述,感興趣的讀者可以去詳讀。
5、應(yīng)用程序
(1)uart_test.c
uart相關(guān)頭文件如下所示:
主函數(shù)定義UART接口調(diào)用,具體如下:
(2)BUILD.gn
編寫應(yīng)用程序的BUILD.gn,具體內(nèi)容如下:
(3)參與應(yīng)用程序編譯
編輯//vendor/lockzhiner/rk3568/samples/BUILD.gn,開(kāi)啟編譯選項(xiàng)。具體如下:
四、程序編譯
建議使用docker編譯方法,運(yùn)行如下:
五、運(yùn)行結(jié)果
運(yùn)行如下:
注意:
- rbuff獲取的時(shí)候可能為空。因?yàn)楸敬伟咐腔诜亲枞?,電腦端發(fā)送的串口可能沒(méi)有獲取到數(shù)據(jù)。
建議: - 讀者可以嘗試使用堵塞方式,再測(cè)試看看。