Linux串列埠分析,基於新唐NUC970系列(上)

2021-08-17 17:46:50 字數 2869 閱讀 8220

參考

《unix環境高階程式設計》

《arm linux裝置驅動開發詳解》

首先由於板子的485口不通,所以嘗試去了解一下linux對整個串列埠驅動的安排。雖然花了一周的時間

但是對linux串列埠整個的理解還是比較膚淺,由於內容比較多,所以做乙個記錄。

首先從應用層角度看,串列埠作為字元裝置之一,也需要通過虛擬檔案系統向應用層提供open、write、read等

系統呼叫。另外串列埠作為終端的一種,在應用層同樣使用linux提供的termios介面,這個介面由posix.1規定。

termios的配置過於複雜,無力完整**。只嘗試對串列埠的初始化、開啟、讀和寫作一分析。

在分析之前,首先介紹一下linux串列埠的一些設計思路,串列埠驅動程式開發的前提是,tty framework,

這個框架對上向應用層提供統一的介面;對下提供編寫終端驅動程式的統一框架,從而簡化驅動編寫。系統呼叫

對應file_operation結構體。另外為了提高驅動軟體的可重用性和跨平台特性,驅動設計又由匯流排、裝置和驅動

三部分組成,匯流排將裝置和驅動繫結。在系統每註冊乙個裝置的時候,會尋找與之匹配的驅動;在系統每註冊乙個

驅動的時候會尋找與之匹配的裝置,匹配完成後呼叫probe函式。串列埠驅動將作為乙個模組編譯如核心。

下面的分析將參考上面文獻中的部落格,從四個方面分析串列埠驅動,即串列埠初始化、串列埠開啟、讀串列埠、寫串列埠。

1、串列埠初始化。

串列埠驅動作為乙個模組,就必須有模組初始化函式。

對於普通串列埠,這裡面主要是三個事情,乙個是註冊串列埠驅動,乙個是註冊平台驅動,還有乙個是埠初始化,其中埠

初始化主要是將uart_port的ops和串列埠驅動檔案中的nuc970serial_ports繫結。

uart_register_driver的功能是1、分配乙個tty_driver,normal; 2、從串列埠層獲取串列埠的基本資訊(包括裝置號、裝置名等);

3、分配乙個state ;4、分配並初始化乙個port;5、將tty_driver和uart_ops這個結構體關聯起來;6、註冊tty_driver,實際

上它最終註冊了乙個字元裝置。7:put_tty_driver呼叫kref_put,將tty_driver中的資訊儲存起來供後面的程式使用。

platform_driver_register的功能是註冊driver並誘發probe,這個probe會呼叫到串列埠中的probe函式。

這個probe函式的工作就是從platform_device pdev中獲取到當前埠的資訊,主要是io基址,記憶體基址、中斷號

等,並賦給uart port,然後通過uart_add_one_port註冊。uart_add_one_port用於建立uart_port和uart_driver之間的聯絡。

總的來說串列埠初始化工作就是將串列埠驅動檔案nuc970_serial.c中的函式和其它層(tty層、串列埠核心層)建立聯絡,

為後面串列埠開啟、串列埠讀寫打下基礎。

2、串列埠開啟

在註冊串列埠驅動的時候,實際上註冊了乙個字元裝置,在註冊字元裝置的時候需要為系統提供file_operations。

tty_open部分如下圖,我們可以看到tty_open呼叫了tty->ops->open,最終呼叫uart_ops的uart_open;

因為tty從tty_open_current_tty得到,tty_open_current_tty是最終通過kref_get獲得在串列埠初始化

的時候呼叫kref_put引入的tty_driver,從而建立和uart_ops的聯絡。(這裡跳來跳去比較煩,在不知道tty詳細的設計

思路的時候也只能這樣了...)

而uart_open呼叫了uart_startup;uart_startup呼叫uart_port_startup,然後呼叫startup;這個ops的型別是

uart_ops,它的ops已經在上述串列埠初始化中和nuc970serial_ops繫結。因此實際上tty_open最終呼叫了

串列埠驅動檔案中的nuc970serial_startup。值得注意的是tty_open中tty_init_dev還呼叫了初始化線路規程的程式。

nuc970serial_startup的**如下

分別是重置fifo、清除等待中斷、註冊中斷處理程式、初始化uart控制器,

包括出發接收緩衝區閾值設定、資料位設定、超時設定、中斷使能和波特率設定。

新唐N76E003 GPRS 串列埠亂碼故障排除手記

目錄 設計目的 讀取imei號碼出現亂碼故障 嘗試解決方法 懷疑1 微控制器引數配置錯誤 懷疑2 gprs與n76e003介面電平相容問題 懷疑3 電磁相容 射頻干擾問題 暫時處置方法 最終解決方法 修改串列埠傳送函式 原有的串列埠傳送函式 微控制器採用n76e003,gprs模組採用air208,...

Linux串列埠驅動分析read

串列埠read函式分析 當應用程式呼叫read系統呼叫時,會呼叫tty fops中的tty read 接下來分析tty read函式 其中最重要的就是ld ops read tty,file,buf,count 也就是呼叫線路規程中read函式 static ssize t tty read str...

linux下基於QT的串列埠程式

qt5發布之前,qt實現串列埠通訊一般是採用第三方類庫qextserialport。qt5發布後自帶了qtserialport 能夠支援串列埠通訊。一 qt5.0以下版本 1.在工程中引入4個檔案。qextserialbase.cpp和qextserialbase.h 以及posix qextser...