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