0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

從串口驅動到Linux驅動模型

璟琰乀 ? 來源:嵌入式大雜燴 ? 作者:Linkerist ? 2020-11-04 14:50 ? 次閱讀

本文通過對Linux下串口驅動的分析。由最上層的C庫。到操作系統(tǒng)系統(tǒng)調用層的封裝。再到tty子系統(tǒng)的核心。再到一系列線路規(guī)程。再到最底層的硬件操作。

對Linux中的tty子系統(tǒng)進行簡要的說明。從理論到實踐。以便讀者能對OS原理有更深入的了解和更具體的掌握。

在具體分析之前。我們必須對串口。驅動。和Linux操作系統(tǒng)有一定的了解。這一階段我們有三個問題需要解決:

1.什么是Linux操作系統(tǒng)。

2.什么是Linux設備驅動。

3.關于串口的種種。

要了解這些概念。如下我介紹了一點這方面的知識。不過遺憾的是對一些概念有著不可避免的向前引用。

這個過程中我會盡量忽略次要因素。以在本次調研中最主要目的為主線。如果讀者您對這些概念已經有很深入的理解??梢灾苯娱喿x后面的代碼分析:

1、什么是Linux操作系統(tǒng) ?Linux是一套免費使用和自由傳播的類Unix操作系統(tǒng),是一個基于POSIX和UNIX的多用戶、多任務、支持多線程和多CPU的操作系統(tǒng)。

它能運行主要的UNIX工具軟件、應用程序和網絡協(xié)議。它支持32位和64位硬件。Linux繼承了Unix以網絡為核心的設計思想,是一個性能穩(wěn)定的多用戶網絡操作系統(tǒng)。

Linux操作系統(tǒng)誕生于1991 年10 月5 日(這是第一次正式向外公布時間)。Linux存在著許多不同的Linux版本,但它們都使用了Linux內核。

Linux具備驚人的可移植性??砂惭b在各種計算機硬件設備中,比如手機、平板電腦、路由器、視頻游戲控制臺、臺式計算機、大型機和超級計算機。

嚴格來講,Linux這個詞本身只表示Linux內核,但實際上人們已經習慣了用Linux來形容整個基于Linux內核,并且使用GNU 工程各種工具和數(shù)據(jù)庫的操作系統(tǒng)。

在這幾個簡要的段落中。有不少新的名詞被引入了進來。下面我對幾個重要的概念進行描述。

A、關于類UNIX系統(tǒng)

類Unix系統(tǒng)(英文:Unix-like)指各種傳統(tǒng)的Unix系統(tǒng)(比如FreeBSD、OpenBSD、SUN公司的Solaris)以及各種與傳統(tǒng)Unix類似的系統(tǒng)(例如Minix、Linux、QNX等)。

它們雖然有的是自由軟件,有的是商業(yè)軟件,但都相當程度地繼承了原始UNIX的特性,有許多相似處,并且都在一定程度上遵守POSIX規(guī)范。

這個在一些經典的操作系統(tǒng)教科書中已經作了說明。我們僅需知道。它和我們熟知的Windows系列操作系統(tǒng)一樣。都是一種現(xiàn)代操作系統(tǒng)。對底層的計算機資源進行抽象。對上層用戶提供調用接口。完成計算機應該完成的功能。

B、關于可移植性

可移植性指與軟件從某一環(huán)境轉移到另一環(huán)境下的難易程度。為獲得較高的可移植性,在設計過程中常采用通用的程序設計語言和運行支撐環(huán)境。盡量不用與系統(tǒng)的底層相關性強的語言。

可移植性是軟件質量之一,良好的可移植性可以提高軟件的生命周期。代碼的可移植性主題是軟件;可移植性是軟件產品的一種能力屬性,其行為表現(xiàn)為一種程度,而表現(xiàn)出來的程度與環(huán)境密切相關。

一個操作系統(tǒng)的可移植性往往表現(xiàn)在它能在運行在不同的體系結構上。感性的理解就是可以支持的設備有很多。比如前文所說的,Linux可以運行在大型服務器上。各種平板電腦上。

前段時間有黑客成功的把Linux移植到一個佳能照相機上。并且在這個照相機上運行了一些主流的軟件??梢哉f。只要有足夠可以利用的硬件資源。就可以把Linux移植到這個硬件平臺上去。這個資源的最低要求往往很低。這可以與對硬件資源要求很高的Windows有一個鮮明的對比。舉個例子就是。當Windows 10的升級提示從你計算機的右下角彈出時。

你可以不假思索的點擊‘馬上升級’嗎?我想大多數(shù)人對這個問題的答案是否定的。為什么?因為大多數(shù)情況下。升級之后就會變得更卡。延遲更大。一些無用而龐大的軟件瘋狂的占用你有限的計算機資源。而如果你選擇的是Linux。你幾乎可以任意的在計算機上安裝軟件。運行程序(如果你的內存不是太小。且硬盤交換分區(qū)足夠的話)。

Linux核心已經將有限的硬件資源發(fā)揮到了極致。開源軟件良好的模塊化設計在各個層次上充分利用了程序的局部性原理。(當然這是在損失了一定易用性的前提下的。)。不好意思我扯遠了。這些不是本文的重點。。

由于筆者沒有土豪到有很多計算機。所以選擇了一款比較便宜的ARM9開發(fā)板作為開發(fā)平臺。它的CPU是三星公司生產的S3C2440。核心是ARM920T。

C、關于Linux的基本思想

Linux的基本思想有兩點:

第一. 一切都是文件。系統(tǒng)中的所有都歸結為一個文件,包括命令、硬件和軟件設備、操作系統(tǒng)、進程等等對于操作系統(tǒng)內核而言,都被視為擁有各自特性或類型的文件。至于說Linux是基于Unix的,很大程度上也是因為這兩者的基本思想十分相近

第二. 每個軟件都有確定的用途。。

D、關于Linux的特點

完全免費

Linux是一款免費的操作系統(tǒng),用戶可以通過網絡或其他途徑免費獲得,并可以任意修改其源代碼。這是其他的操作系統(tǒng)所做不到的。

正是由于這一點,來自全世界的無數(shù)程序員參與了Linux的修改、編寫工作,程序員可以根據(jù)自己的興趣和靈感對其進行改變,這讓Linux吸收了無數(shù)程序員的精華,不斷壯大。

完全兼容POSIX1.0標準

這使得可以在Linux下通過相應的模擬器運行常見的DOS、Windows的程序。這為用戶從Windows轉到Linux奠定了基礎。

許多用戶在考慮使用Linux時,就想到以前在Windows下常見的程序是否能正常運行,這一點就消除了他們的疑慮。

多用戶、多任務

Linux支持多用戶,各個用戶對于自己的文件設備有自己特殊的權利,保證了各用戶之間互不影響。多任務則是現(xiàn)在電腦最主要的一個特點,Linux可以使多個程序同時并獨立地運行。

良好的界面

Linux同時具有字符界面和圖形界面。在字符界面用戶可以通過鍵盤輸入相應的指令來進行操作。它同時也提供了類似Windows圖形界面的X-Window系統(tǒng),用戶可以使用鼠標對其進行操作。在X-Window環(huán)境中就和在Windows中相似,可以說是一個Linux版的Windows。

支持多種平臺

Linux可以運行在多種硬件平臺上,如具有x86、680x0、SPARC、Alpha等處理器的平臺。此外Linux還是一種嵌入式操作系統(tǒng),可以運行在掌上電腦、機頂盒或游戲機上。2001年1月份發(fā)布的Linux 2.4版內核已經能夠完全支持Intel 64位芯片架構。同時Linux也支持多處理器技術。多個處理器同時工作,使系統(tǒng)性能大大提高。

文件類型

普通文件(regular file):就是一般存取的文件,由ls-al顯示出來的屬性中,第一個屬性為 [-],例如 [-rwxrwxrwx]。另外,依照文件的內容,又大致可以分為:

1、純文本文件(ASCII):這是Unix系統(tǒng)中最多的一種文件類型,之所以稱為純文本文件,是因為內容可以直接讀到的數(shù)據(jù),例如數(shù)字、字母等等。設置文件幾乎都屬于這種文件類型。舉例來說,使用命令“cat ~/.bashrc”就可以看到該文件的內容(cat是將文件內容讀出來)。

2、二進制文件(binary):系統(tǒng)其實僅認識且可以執(zhí)行二進制文件(binary file)。Linux中的可執(zhí)行文件(腳本,文本方式的批處理文件不算)就是這種格式的。舉例來說,命令cat就是一個二進制文件。

3、數(shù)據(jù)格式的文件(data):有些程序在運行過程中,會讀取某些特定格式的文件,那些特定格式的文件可以稱為數(shù)據(jù)文件(data file)。舉例來說,Linux在用戶登入時,都會將登錄數(shù)據(jù)記錄在 /var/log/wtmp文件內,該文件是一個數(shù)據(jù)文件,它能通過last命令讀出來。但使用cat時,會讀出亂碼。因為它是屬于一種特殊格式的文件。

4、目錄文件(directory):就是目錄,第一個屬性為[d],例如 [drwxrwxrwx]。

連接文件(link):類似Windows下面的快捷方式。第一個屬性為 [l],例如 [lrwxrwxrwx]。

5、設備與設備文件(device):與系統(tǒng)外設及存儲等相關的一些文件,通常都集中在 /dev目錄。通常又分為兩種:

塊設備文件:就是存儲數(shù)據(jù)以供系統(tǒng)存取的接口設備,簡單而言就是硬盤。例如一號硬盤的代碼是 /dev/hda1等文件。第一個屬性為 [b]。

字符設備文件:即串行端口的接口設備,例如鍵盤、鼠標等等。第一個屬性為 [c]。

6、套接字(sockets):這類文件通常用在網絡數(shù)據(jù)連接。可以啟動一個程序來監(jiān)聽客戶端的要求,客戶端就可以通過套接字來進行數(shù)據(jù)通信。第一個屬性為 [s],最常在 /var/run目錄中看到這種文件類型。

7、管道(FIFO,pipe):FIFO也是一種特殊的文件類型,它主要的目的是,解決多個程序同時存取一個文件所造成的錯誤。FIFO是first-in-first-out(先進先出)的縮寫。第一個屬性為 [p]

文件結構

/:根目錄,所有的目錄、文件、設備都在/之下,/就是Linux文件系統(tǒng)的組織者,也是最上級的領導者。

/bin:bin 就是二進制(binary)英文縮寫。在一般的系統(tǒng)當中,都可以在這個目錄下找到linux常用的命令。系統(tǒng)所需要的那些命令位于此目錄。

/boot:Linux的內核及引導系統(tǒng)程序所需要的文件目錄,比如 vmlinuz initrd.img 文件都位于這個目錄中。在一般情況下,GRUB或LILO系統(tǒng)引導管理器也位于這個目錄。

/cdrom:這個目錄在剛剛安裝系統(tǒng)的時候是空的??梢詫⒐怛屛募到y(tǒng)掛在這個目錄下。例如:mount /dev/cdrom /cdrom

/dev:dev 是設備(device)的英文縮寫。這個目錄對所有的用戶都十分重要。因為在這個目錄中包含了所有l(wèi)inux系統(tǒng)中使用的外部設備。但是這里并不是放的外部設備的驅動程序。這一點和常用的windows,dos操作系統(tǒng)不一樣。它實際上是一個訪問這些外部設備的端口??梢苑浅7奖愕厝ピL問這些外部設備,和訪問一個文件,一個目錄沒有任何區(qū)別。

/etc:etc這個目錄是linux系統(tǒng)中最重要的目錄之一。在這個目錄下存放了系統(tǒng)管理時要用到的各種配置文件和子目錄。要用到的網絡配置文件,文件系統(tǒng),x系統(tǒng)配置文件,設備配置信息,設置用戶信息等都在這個目錄下。

/home:如果建立一個用戶,用戶名是“xx”,那么在/home目錄下就有一個對應的/home/xx路徑,用來存放用戶的主目錄。

/lib:lib是庫(library)英文縮寫。這個目錄是用來存放系統(tǒng)動態(tài)連接共享庫的。幾乎所有的應用程序都會用到這個目錄下的共享庫。因此,千萬不要輕易對這個目錄進行什么操作,一旦發(fā)生問題,系統(tǒng)就不能工作了。

/lost+found:在ext2或ext3文件系統(tǒng)中,當系統(tǒng)意外崩潰或機器意外關機,而產生一些文件碎片放在這里。當系統(tǒng)啟動的過程中fsck工具會檢查這里,并修復已經損壞的文件系統(tǒng)。有時系統(tǒng)發(fā)生問題,有很多的文件被移到這個目錄中,可能會用手工的方式來修復,或移到文件到原來的位置上。

/mnt:這個目錄一般是用于存放掛載儲存設備的掛載目錄的,比如有cdrom等目錄??梢詤⒖?etc/fstab的定義。

/media:有些linux的發(fā)行版使用這個目錄來掛載那些usb接口的移動硬盤(包括U盤)、CD/DVD驅動器等等。

/opt:這里主要存放那些可選的程序。

/proc:可以在這個目錄下獲取系統(tǒng)信息。這些信息是在內存中,由系統(tǒng)自己產生的。

/root:Linux超級權限用戶root的家目錄。

/sbin:這個目錄是用來存放系統(tǒng)管理員的系統(tǒng)管理程序。大多是涉及系統(tǒng)管理的命令的存放,是超級權限用戶root的可執(zhí)行命令存放地,普通用戶無權限執(zhí)行這個目錄下的命令,這個目錄和/usr/sbin; /usr/X11R6/sbin或/usr/local/sbin目錄是相似的,凡是目錄sbin中包含的都是root權限才能執(zhí)行的。

/selinux :對SElinux的一些配置文件目錄,SElinux可以讓linux更加安全。

/srv 服務啟動后,所需訪問的數(shù)據(jù)目錄,舉個例子來說,www服務啟動讀取的網頁數(shù)據(jù)就可以放在/srv/www中

/tmp:臨時文件目錄,用來存放不同程序執(zhí)行時產生的臨時文件。有時用戶運行程序的時候,會產生臨時文件。/tmp就用來存放臨時文件的。/var/tmp目錄和這個目錄相似。

/usr:這是linux系統(tǒng)中占用硬盤空間最大的目錄。用戶的很多應用程序和文件都存放在這個目錄下。在這個目錄下,可以找到那些不適合放在/bin或/etc目錄下的額外的工具

/usr/local:這里主要存放那些手動安裝的軟件,即不是通過“新立得”或apt-get安裝的軟件。它和/usr目錄具有相類似的目錄結構。讓軟件包管理器來管理/usr目錄,而把自定義的腳本(scripts)放到/usr/local目錄下面、。

/usr/share :系統(tǒng)共用的東西存放地,比如/usr/share/fonts 是字體目錄,/usr/share/doc和/usr/share/man幫助文件。

/var:這個目錄的內容是經常變動的,看名字就知道,可以理解為vary的縮寫,/var下有/var/log 這是用來存放系統(tǒng)日志的目錄。/var/ www目錄是定義Apache服務器站點存放目錄;/var/lib 用來存放一些庫文件,比如MySQL的,以及MySQL數(shù)據(jù)庫的的存放地。

如上。相信讀者已經對Linux操作系統(tǒng)有了一個概觀。對于一些具體命令。筆者決定需要用到的時候再做說明。現(xiàn)在我們來看看第二個概念:

2、什么是Linux設備驅動設備驅動最通俗的解釋就是驅使硬件設備行動。驅動與底層硬件直接打交道,按照硬件設備的具體工作方式,讀寫設備的寄存器,完成設備的輪詢、中斷處理、DMA通信,進行物理內存向虛擬內存的映射等,最終讓通信設備能收發(fā)數(shù)據(jù),讓顯示設備能顯示文字和畫面,讓存儲設備能記錄文件和數(shù)據(jù)。

Linux設備驅動是對底層硬件資源的抽象。對上層的操作系統(tǒng)其他服務提供一個良好的接口。讓其他服務可以把一個特定的硬件。或是一種機制當做一個文件使用。使用通用的系統(tǒng)調用進行調用。

3、關于串口的種種眾所周知。我們現(xiàn)在的計算機上面有很多接口。如USB。網口。并口等。串口總線是其中的一個。串行接口簡稱串口,也稱串行通信接口或串行通訊接口(通常指COM接口),是采用串行通信方式的擴展接口。

串行接口 (Serial Interface) 是指數(shù)據(jù)一位一位地順序傳送,其特點是通信線路簡單,只要一對傳輸線就可以實現(xiàn)雙向通信(可以直接利用電話線作為傳輸線),從而大大降低了成本,特別適用于遠距離通信,但傳送速度較慢。一條信息的各位數(shù)據(jù)被逐位按順序傳送的通訊方式稱為串行通訊。

串行通訊的特點是:數(shù)據(jù)位的傳送,按位順序進行,最少只需一根傳輸線即可完成;成本低但傳送速度慢。串行通訊的距離可以從幾米到幾千米;根據(jù)信息的傳送方向,串行通訊可以進一步分為單工、半雙工和全雙工三種。

串口通信的兩種最基本的方式:同步串行通信方式和異步串行通信方式。

同步串行是指SPI(SerialPeripheral interface)的縮寫,顧名思義就是串行外圍設備接口。SPI總線系統(tǒng)是一種同步串行外設接口,它可以使MCU與各種外圍設備以串行方式進行通信以交換信息,TRM450是SPI接口。

異步串行是指UART(UniversalAsynchronous Receiver/Transmitter),通用異步接收/發(fā)送。UART是一個并行輸入成為串行輸出的芯片,通常集成在主板上。UART包含TTL電平的串口和RS232電平的串口。

TTL電平是3.3V的,而RS232是負邏輯電平,它定義+5~+12V為低電平,而-12~-5V為高電平,MDS2710、MDS SD4、EL805等是RS232接口,EL806有TTL接口。

串行接口按電氣標準及協(xié)議來分包括RS-232-C、RS-422、RS485等。

RS-232

也稱標準串口,最常用的一種串行通訊接口。它是在1970年由美國電子工業(yè)協(xié)會(EIA)聯(lián)合貝爾系統(tǒng)、調制解調器廠家及計算機終端生產廠家共同制定的用于串行通訊的標準。

它的全名是“數(shù)據(jù)終端設備(DTE)和數(shù)據(jù)通訊設備(DCE)之間串行二進制數(shù)據(jù)交換接口技術標準”。傳統(tǒng)的RS-232-C接口標準有22根線,采用標準25芯D型插頭座(DB25),后來使用簡化為9芯D型插座(DB9),現(xiàn)在應用中25芯插頭座已很少采用。

RS-232采取不平衡傳輸方式,即所謂單端通訊。由于其發(fā)送電平與接收電平的差僅為2V至3V左右,所以其共模抑制能力差,再加上雙絞線上的分布電容,其傳送距離最大為約15米,最高速率為20kb/s。RS-232是為點對點(即只用一對收、發(fā)設備)通訊而設計的,其驅動器負載為3~7kΩ。所以RS-232適合本地設備之間的通信。

RS-422

標準全稱是“平衡電壓數(shù)字接口電路的電氣特性”,它定義了接口電路的特性。典型的RS-422是四線接口。實際上還有一根信號地線,共5根線。其DB9連接器引腳定義。由于接收器采用高輸入阻抗和發(fā)送驅動器比RS232更強的驅動能力,故允許在相同傳輸線上連接多個接收節(jié)點,最多可接10個節(jié)點。

即一個主設備(Master),其余為從設備(Slave),從設備之間不能通信,所以RS-422支持點對多的雙向通信。接收器輸入阻抗為4k,故發(fā)端最大負載能力是10×4k+100Ω(終接電阻)。

RS-422四線接口由于采用單獨的發(fā)送和接收通道,因此不必控制數(shù)據(jù)方向,各裝置之間任何必須的信號交換均可以按軟件方式(XON/XOFF握手)或硬件方式(一對單獨的雙絞線)實現(xiàn)。

RS-422的最大傳輸距離為1219米,最大傳輸速率為10Mb/s。其平衡雙絞線的長度與傳輸速率成反比,在100kb/s速率以下,才可能達到最大傳輸距離。只有在很短的距離下才能獲得最高速率傳輸。一般100米長的雙絞線上所能獲得的最大傳輸速率僅為1Mb/s。

RS-485

是從RS-422基礎上發(fā)展而來的,所以RS-485許多電氣規(guī)定與RS-422相仿。如都采用平衡傳輸方式、都需要在傳輸線上接終接電阻等。RS-485可以采用二線與四線方式,二線制可實現(xiàn)真正的多點雙向通信,而采用四線連接時,與RS-422一樣只能實現(xiàn)點對多的通信,即只能有一個主(Master)設備,其余為從設備,但它比RS-422有改進,無論四線還是二線連接方式總線上可多接到32個設備。

RS-485與RS-422的不同還在于其共模輸出電壓是不同的,RS-485是-7V至+12V之間,而RS-422在-7V至+7V之間,RS-485接收器最小輸入阻抗為12kΩ、RS-422是4kΩ;由于RS-485滿足所有RS-422的規(guī)范,所以RS-485的驅動器可以在RS-422網絡中應用。

RS-485與RS-422一樣,其最大傳輸距離約為1219米,最大傳輸速率為10Mb/s。平衡雙絞線的長度與傳輸速率成反比,在100kb/s速率以下,才可能使用規(guī)定最長的電纜長度。只有在很短的距離下才能獲得最高速率傳輸。一般100米長雙絞線最大傳輸速率僅為1Mb/s。

筆者采用的RS-232串口通信協(xié)議。下面對其通信接線方法做簡要說明。目前較為常用的串口有9針串口(DB9)和25針串口(DB25),通信距離較近時(《12m),可以用電纜線直接連接標準RS232端口(RS422,RS485較遠),若距離較遠,需附加調制解調器(MODEM)或其他相關設備。最為簡單且常用的是三線制接法,即地、接收數(shù)據(jù)和發(fā)送數(shù)據(jù)三腳相連,這是最為基本的接法,且直接用RS232相連。

上面是對微機標準串行口而言的,還有許多非標準設備,不做說明。

好了。到此為止我們已經解決了一開始的三個問題。讓我們進入實際的代碼。實際的硬件來進行分析。

在一個硬件平臺上。硬件是可用的。我們必須要燒寫適當?shù)能涹w到平臺的RAM中。這樣CPU才能跳轉到最先的指令。然后慢慢加載各種資源。才能完成系統(tǒng)的自舉。

一般我們采用BootLoader進行硬件的初始化。并引導至操作系統(tǒng)核心。

筆者采用的BootLoader是u-Boot-1.1.16。Uboot是一個眾所周知的開源軟件。讀者僅需了解它起到了BootLoader的作用即可。這里不多做解釋。僅對串口的連接和程序的下載作簡要說明:

將UBOOT目錄下的u-boot.bin下載到開發(fā)平臺上。在Windows打開設備管理器。選擇端口。從而找到正確的com口號。在此之前確保開發(fā)板的串口與筆記本的USB口連接。(因為現(xiàn)在筆記本都沒有并口了。所以只能采用USB轉串口線。搭配開發(fā)板上的電平轉換芯片來完成串口連接目的。)

然后我們再使用一個工具。即SecureCRT。找到對應的com號。完成快速鏈接。波特率選擇115200。取消流控。

如果一切順利。在筆記本上就可以看到串口的類似下面的輸出。這就是傳說中的串口控制臺。。

這個串口的指令功能是由Uboot本身完成的。并不是linux下的串口驅動。

引入此圖旨在讓讀者感性的認識到串口控制臺的功能是什么。

下面正式開始對串口打開。發(fā)送。接收函數(shù)的分析。這里向前引用一個函數(shù)。就是linux內核中幾種2440芯片通用的串口發(fā)送函數(shù)s3c24xx_serial_start_tx。函數(shù)聲明為static voids3c24xx_serial_start_tx(struct uart_port *port):函數(shù)定義在。/linux/driver/tty/serial/samsung.c中。

好了。我們從這個目錄結構開始。說明大概的tty子系統(tǒng)驅動模型。

首先。最前面的linux是內核代碼的根目錄。如圖所示。

至此。我們面臨一個問題。linux內核是什么。

Linux內核是什么?Linux是一種開源電腦操作系統(tǒng)內核。它是一個用C語言寫成,符合POSIX標準的類Unix操作系統(tǒng)。

Linux最早是由芬蘭黑客Linus Torvalds為嘗試在英特爾x86架構上提供自由免費的類Unix操作系統(tǒng)而開發(fā)的。該計劃開始于1991年,在計劃的早期有一些Minix 黑客提供了協(xié)助,而今天全球無數(shù)程序員正在為該計劃無償提供幫助。

Linux是一個一體化內核(monolithickernel)系統(tǒng)?!皟群恕敝傅氖且粋€提供硬件抽象層、磁盤及文件系統(tǒng)控制、多任務等功能的系統(tǒng)軟件。一個內核不是一套完整的操作系統(tǒng)。

一套基于Linux內核的完整操作系統(tǒng)叫作Linux操作系統(tǒng),或是GNU/Linux。設備驅動程序可以完全訪問硬件。Linux內的設備驅動程序可以方便地以模塊化(modularize)的形式設置,并在系統(tǒng)運行期間可直接裝載或卸載。

操作系統(tǒng)是一個用來和硬件打交道并為用戶程序提供一個有限服務集的低級支撐軟件。一個計算機系統(tǒng)是一個硬件和軟件的共生體,它們互相依賴,不可分割。計算機的硬件,含有外圍設備、處理器、內存、硬盤和其他的電子設備組成計算機的發(fā)動機。但是沒有軟件來操作和控制它,自身是不能工作的。

完成這個控制工作的軟件就稱為操作系統(tǒng),在Linux的術語中被稱為“內核”,也可以稱為“核心”。Linux內核的主要模塊(或組件)分以下幾個部分:存儲管理、CPU和進程管理、文件系統(tǒng)、設備管理和驅動、網絡通信,以及系統(tǒng)的初始化(引導)、系統(tǒng)調用等。

系統(tǒng)調用接口

SCI 層提供了某些機制執(zhí)行從用戶空間到內核的函數(shù)調用。正如前面討論的一樣,這個接口依賴于體系結構,甚至在相同的處理器家族內也是如此。SCI 實際上是一個非常有用的函數(shù)調用多路復用和多路分解服務。在 。/linux/kernel 中您可以找到 SCI 的實現(xiàn),并在 。/linux/arch 中找到依賴于體系結構的部分。

進程管理

進程管理的重點是進程的執(zhí)行。在內核中,這些進程稱為線程,代表了單獨的處理器虛擬化(線程代碼、數(shù)據(jù)、堆棧和 CPU寄存器)。在用戶空間,通常使用進程這個術語,不過 Linux 實現(xiàn)并沒有區(qū)分這兩個概念(進程和線程)。

內核通過 SCI 提供了一個應用程序編程接口(API)來創(chuàng)建一個新進程(fork、exec 或 Portable Operating System Interface [POSⅨ] 函數(shù)),停止進程(kill、exit),并在它們之間進行通信和同步(signal 或者 POSⅨ機制)。

進程管理還包括處理活動進程之間共享 CPU的需求。內核實現(xiàn)了一種新型的調度算法,不管有多少個線程在競爭 CPU,這種算法都可以在固定時間內進行操作。這種算法就稱為 O⑴調度程序,這個名字就表示它調度多個線程所使用的時間和調度一個線程所使用的時間是相同的。

O⑴調度程序也可以支持多處理器(稱為對稱多處理器或 SMP)。您可以在 。/linux/kernel 中找到進程管理的源代碼,在 。/linux/arch 中可以找到依賴于體系結構的源代碼。

內存管理

內核所管理的另外一個重要資源是內存。為了提高效率,如果由硬管理虛擬內存,內存是按照所謂的內存頁方式進行管理的(對于大部分體系結構來說都是 4KB)。Linux 包括了管理可用內存的方式,以及物理和虛擬映射所使用的硬件機制。

不過內存管理要管理的可不止 4KB緩沖區(qū)。Linux 提供了對 4KB緩沖區(qū)的抽象,例如 slab 分配器。這種內存管理模式使用 4KB緩沖區(qū)為基數(shù),然后從中分配結構,并跟蹤內存頁使用情況,比如哪些內存頁是滿的,哪些頁面沒有完全使用,哪些頁面為空。這樣就允許該模式根據(jù)系統(tǒng)需要來動態(tài)調整內存使用。

為了支持多個用戶使用內存,有時會出現(xiàn)可用內存被消耗光的情況。由于這個原因,頁面可以移出內存并放入磁盤中。這個過程稱為交換,因為頁面會被從內存交換到硬盤上。內存管理的源代碼可以在 。/linux/mm 中找到。

虛擬文件系統(tǒng)

虛擬文件系統(tǒng)(VFS)是 Linux 內核中非常有用的一個方面,因為它為文件系統(tǒng)提供了一個通用的接口抽象。VFS 在 SCI 和內核所支持的文件系統(tǒng)之間提供了一個交換層。

VFS 在用戶和文件系統(tǒng)之間提供了一個交換層

在 VFS 上面,是對諸如 open、close、read 和 write 之類的函數(shù)的一個通用 API 抽象。在 VFS 下面是文件系統(tǒng)抽象,它定義了上層函數(shù)的實現(xiàn)方式。它們是給定文件系統(tǒng)(超過 50 個)的插件。文件系統(tǒng)的源代碼可以在 。/linux/fs 中找到。

文件系統(tǒng)層之下是緩沖區(qū)緩存,它為文件系統(tǒng)層提供了一個通用函數(shù)集(與具體文件系統(tǒng)無關)。這個緩存層通過將數(shù)據(jù)保留一段時間(或者隨即預先讀取數(shù)據(jù)以便在需要是就可用)優(yōu)化了對物理設備的訪問。緩沖區(qū)緩存之下是設備驅動程序,它實現(xiàn)了特定物理設備的接口。

好了。相信讀者已經對linuxkernel 有了一個概觀。下面我們繼續(xù)分析這個路徑背后代表的模型結構。(。/linux/driver/tty/serial/samsung.c)

driver是驅動程序的目錄。如圖所示:

前文對linux設備驅動程序有了一個大概的描述。下面我們具體看一下linux下的驅動。

縱覽linux/drivers目錄,大概還有35個以上的子目錄,每個子目錄基本上就代表了一種設備驅動,有atm、block、char、misc、input、net、usb、sound、video等。這里只描述在嵌入式系統(tǒng)里面用得最為廣泛的3種設備。

1.字符設備(char device)

字符設備是Linux最簡單的設備,可以像文件一樣訪問。初始化字符設備時,它的設備驅動程序向Linux登記,并在字符設備向量表中增加一個device_struct數(shù)據(jù)結構條目,這個設備的主設備標識符用做這個向量表的索引

一個設備的主設備標識符是固定的。chrdevs向量表中的每一個條目,一個device_struct數(shù)據(jù)結構,包括兩個元素:一個登記設備驅動程序名稱的指針和一個指向一組文件操作的指針。可以參考的代碼是include/linux/ major.h。

一般來說像鼠標、串口、鍵盤等設備都屬于字符設備。

2.塊設備(block device)

塊設備是文件系統(tǒng)的物質基礎,它也可以像文件一樣被訪問。Linux用blkdevs向量表維護已經登記的塊設備文件。它像chrdevs向量表一樣,使用設備的主設備號作為索引。它的條目也是device_struct數(shù)據(jù)結構。與字符設備不同的是,塊設備分為SCSI類和IDE類。

向Linux內核登記并向核心提供文件操作。一種塊設備類的設備驅動程序向這種類提供和類相關的接口。可以參考的代碼是fs/devices.c。

每一個塊設備驅動程序必須提供普通的文件操作接口和對于buffer cache的接口。每一個塊設備驅動程序填充blk_dev向量表中的blk_dev_struct數(shù)據(jù)結構。此向量表的索引是設備的主設備號。其中blk_dev_struct數(shù)據(jù)結構包括一個請求例程的地址和一個指針,指向一個request數(shù)據(jù)結構的列表,每一個都表達buffer cache向設備讀/寫一塊數(shù)據(jù)的一個請求。

可以參考的源代碼是drivers/block/ll_rw_blk.c和include/linux/blkdev.h。

當buffer cache從一個已登記的設備讀/寫一塊數(shù)據(jù),或者希望讀、寫一塊數(shù)據(jù)到其他位置時,就在blk_dev_struct中增加一個request數(shù)據(jù)結構。每個request數(shù)據(jù)結構都有一個指向一個或多個buffer_head數(shù)據(jù)結構的指針,每一個都是讀/寫一塊數(shù)據(jù)的請求。

如果buffer_head數(shù)據(jù)結構被鎖定(buffer_cache),可能會有一個進程在等待這個緩沖區(qū)的阻塞進程完成。每一個request數(shù)據(jù)結構都是從all_request表中分配的。如果request增加到空的request列表中,就調用驅動程序的request函數(shù)處理這個request隊列,否則驅動程序只是簡單地處理request隊列中的每一個請求。

塊設備驅動程序和字符設備驅動程序的主要區(qū)別是:在對字符設備發(fā)出讀、寫請求時,實際的硬件I/O一般緊接著就發(fā)生了,塊設備則不然,它利用一塊系統(tǒng)內存作為緩沖區(qū),當用戶進程對設備請求能滿足用戶的要求時,就返回請求的數(shù)據(jù),如果不能就調用請求函數(shù)來進行實際的I/O操作。塊設備是主要針對磁盤等慢速設備的,以免耗費過多的CPU時間來等待。

塊設備主要有硬盤、光盤驅動器等??梢圆榭次募?proc/devices獲得。

3.網絡設備(net device)

網絡設備在系統(tǒng)中的作用類似于一個已掛載的塊設備。塊設備將自己注冊到blk_dev數(shù)據(jù)及其他內核結構中,然后通過自己的request函數(shù)在發(fā)生請求時傳輸和接收數(shù)據(jù)塊,同樣網絡設備也必須在特定的數(shù)據(jù)結構中注冊自己,以便與外界交換數(shù)據(jù)包時被調用。網絡設備在Linux里做專門的處理。Linux的網絡系統(tǒng)主要是基于BSD UNIX的Socket機制。在系統(tǒng)和驅動程序之間定義有專門的數(shù)據(jù)結構(sk_buff)進行數(shù)據(jù)的傳遞。系統(tǒng)里支持對發(fā)送數(shù)據(jù)和接收數(shù)據(jù)的緩存,提供流量控制機制,提供對多協(xié)議的支持。

4.雜項設備(misc device)

雜項設備也是在嵌入式系統(tǒng)中用得比較多的一種設備驅動,在第11章里面介紹的sub LCD和弦芯片的驅動等都是采用 misc device 的驅動方式實現(xiàn)的。在 Linux 內核的includelinux目錄下有Miscdevice.h文件,要把自己定義的misc device從設備定義在這里。其實是因為這些字符設備不符合預先確定的字符設備范疇,所有這些設備采用主編號10,一起歸于misc device,其實misc_register就是用主標號10調用register_chrdev()的。

這是driver目錄下的分類。我們主要調研的串口驅動。屬于TTY子系統(tǒng)。所以我們cd到tty目錄下。ls顯示里面的文件。如圖所示:

下面對linux內核tty設備做一點簡要說明。

tty一詞源于Teletypes,或Teletypewriters,它是最早出現(xiàn)的一種終端設備,類似電傳打字機,由Teletype公司生產。最初tty是指連接到Unix系統(tǒng)上的物理或者虛擬終端。終端是一種字符型設備,通常使用tty來統(tǒng)稱各種類型的終端設備。隨著時間的推移,當通過串行口能夠建立起終端連接后,這個名字也用來指任何的串口設備。

它還有多種類,例如串口(ttySn、ttySACn、ttyOn)、USB到串口的轉換器(ttyUSBn),還有需要特殊處理才能正常工作的調制解調器(比如傳統(tǒng)的WinModem類設備)等。tty虛擬設備支持虛擬控制臺,它能通過鍵盤及網絡連接或者通過xterm會話登錄到計算機上。

其實起初終端和控制臺都不是個人電腦的概念,而是多人共用的小型中型大型計算機上的概念。終端為主機提供了人機接口,每個人都通過終端使用主機的資源。終端有字符終端和圖形終端兩種。一臺主機可以連很多終端??刂婆_是一種特殊的人機接口, 是人控制主機的第一人機接口。

而主機對于控制臺的信任度高于其他終端。對此還可以結合內核啟動代碼中init進程打開/dev/console和執(zhí)行兩次sys_dup(0),以及標準輸入、標準輸出、標準出錯,還有就是進程fork后的標準輸入輸出的復制情況來一起理解。而個人計算機只有控制臺,沒有終端。當然愿意的話,可以在串口上連一兩臺字符啞終端。

但是linux按POSIX標準把個人計算機當成小型機來用,在控制臺上通過getty軟件虛擬了六個字符啞終端(或者叫虛擬控制臺終端tty1-tty6)(數(shù)量可以在/etc/inittab里自己調整)和一個圖型終端, 在虛擬圖形終端中又可以通過軟件(如rxvt)再虛擬無限多個偽終端(pts/0等)。

但這全是虛擬的,雖然用起來一樣,但實際上沒有物理實體。所以在個人計算機上,只有一個實際的控制臺,沒有終端,所有終端都是在控制臺上用軟件模擬的。要把個人計算機當主機再通過串口或網卡外連真正的物理終端也可以,論成本,呵呵。誰會怎么做呢。

終端按照其自身能力分類,可以分為:

1、啞終端(瘦客戶端)

早期的計算機終端是通過串行RS-232通信的,它只能解釋有限數(shù)量的控制碼(CR,LF等),但沒有能力處理執(zhí)行特殊的轉義序列功能(如清行、清屏或控制光標的位置)。簡單來說就是處理能力有限的終端機,他們一般基本上只具有和機械電傳打字機類似的有限功能。這種類型的終端稱為啞終端。

現(xiàn)在仍然在現(xiàn)代類Unix系統(tǒng)上得到支持,通過設置環(huán)境變量TERM=dumb。啞終端有時用來指任何類型的通過RS-232連接的傳統(tǒng)計算機終端,不對數(shù)據(jù)進行本地處理或本地執(zhí)行用戶程序的串行通信終端。啞終端有時也指功能有限,只有單色文本處理能力或直接傳輸每一個鍵入的字符而不等待主機輪詢的公共計算機終端。

2、智能終端(胖客戶端)

智能終端就是有能力處理轉義序列,也就是說處理能力較強的終端機。

Linux系統(tǒng)的終端設備一般有以下幾種:

1、 控制臺

系統(tǒng)控制臺/dev/console

/dev/console是系統(tǒng)控制臺,是與操作系統(tǒng)交互的設備。系統(tǒng)所產生的信息會發(fā)送到該設備上。平時我們看到的PC只有一個屏幕和鍵盤,它其實就是控制臺。目前只有在單用戶模式下,才允許用戶登錄控制臺/dev/console。(可以在單用戶模式下輸入tty命令進行確認)。

console有緩沖的概念,為內核提供打印輸出。內核把要打印的內容裝入緩沖區(qū)__log_buff,然后由console來決定打印到哪里(比如是tty0還是ttySn等)。console指向激活的終端。歷史上,console指主機本身的屏幕和鍵盤,而tty指用電纜鏈接的其它位置的控制臺。

某些情況下console和tty0是一致的,就是當前所使用的是虛擬終端,也是激活虛擬終端。所以有些資料中稱/dev/console是到/dev/tty0的符號鏈接,但是這樣說現(xiàn)在看來是不對的:根據(jù)內核文檔,在2.1.71之前,/dev/console根據(jù)不同系統(tǒng)設定,符號鏈接到/dev/tty0或者其他tty*上,在2.1.71版本之后則完全由內核代碼內部控制它的映射。

如果一個終端設備要實現(xiàn)console功能,必須向內核注冊一個struct console結構,一般的串口驅動中都會有。如果設備要實現(xiàn)tty功能,必須要內核的tty子系統(tǒng)注冊一個struct tty_driver結構,注冊函數(shù)在drivers/tty/tty_io.c中。一個設備可以同時實現(xiàn)console和tty_driver,一般串口都這么做。

當前控制臺:/dev/tty

這是應用程序中的概念,如果當前進程有控制終端(Controlling Terminal),那么/dev/tty就是當前進程控制臺的設備文件。對于你登錄的shell,/dev/tty就是你使用的控制臺,設備號是(5,0)。不過它并不指任何物理意義上的控制臺,/dev/tty會映射到當前設備(使用命令“tty”可以查看它具體對應哪個實際物理控制臺設備)。輸出到/dev/tty的內容只會顯示在當前工作終端上(無論是登錄在ttyn中還是pty中)。

你如果在控制臺界面下(即字符界面下)那么dev/tty就是映射到dev/tty1-6之間的一個(取決于你當前的控制臺號),但是如果你現(xiàn)在是在圖形界面(Xwindows),那么你會發(fā)現(xiàn)現(xiàn)在的/dev/tty映射到的是/dev/pts的偽終端上。/dev/tty有些類似于到實際所使用終端設備的一個聯(lián)接。

你可以輸入命令“tty“,將顯示當前映射終端如:/dev/tty1或者/dev/pts/0等。也可以使用命令“ps -ax”來查看其他進程與哪個控制終端相連。

在當前終端中輸入 echo “tekkaman” 》 /dev/tty ,都會直接顯示在當前的終端中。

虛擬控制臺 /dev/ttyn

/dev/ttyn是進程虛擬控制臺,他們共享同一個真實的物理控制臺。如果在進程里打開一個這樣的文件且該文件不是其他進程的控制臺時,那該文件就是這個進程的控制臺。

進程printf數(shù)據(jù)會輸出到這里。在PC上,用戶可以使用alt+Fn切換控制臺,現(xiàn)在不知道怎么回事我用Ctrl + Alt + Fn才能切換。這沒具體看過為啥??赡苁荓inux沒有繼承UNIX這方面的傳統(tǒng)罷了??雌饋砀杏X存在多個屏幕,這種虛擬控制臺對應tty1~n,其中:

/dev/tty1等代表第一個虛擬控制臺

例如當使用ALT+F2進行切換時,系統(tǒng)的虛擬控制臺為/dev/tty2 ,當前控制臺(/dev/tty)則指向/dev/tty2

在UNIX系統(tǒng)中,計算機顯示器通常被稱為控制臺(Console)。它仿真了類型為Linux的一種終端,并且有一些設備特殊文件與之相關聯(lián):tty0、tty1、tty2等。當你在控制臺上登錄時,使用的是tty1。使用Alt+[F1—F6]組合鍵時,我們就可以切換到tty2、tty3等上面去。

讀者可以登錄到不同的虛擬控制臺上去,因而可以讓系統(tǒng)同時有幾個不同的會話存在。

而比較特殊的是/dev/tty0,他代表當前虛擬控制臺,其實就是當前所使用虛擬控制臺的一個別名。因此不管當前正在使用哪個虛擬控制臺(注意:這里是虛擬控制臺,不包括偽終端),系統(tǒng)信息都會重定位到/dev/tty0上。

只有系統(tǒng)或超級用戶root可以向/dev/tty0進行寫操作。tty0是系統(tǒng)自動打開的,但不用于用戶登錄。在Framebuffer設備沒有啟用的系統(tǒng)中,可以使用/dev/tty0訪問顯卡。

2、 偽終端pty(pseudo-tty)

偽終端(Pseudo Terminal)是終端的發(fā)展,為滿足現(xiàn)在需求(比如網絡登陸、xwindow窗口的管理)。它是成對出現(xiàn)的邏輯終端設備(即master和slave設備, 對master的操作會反映到slave上)。它多用于模擬終端程序,是遠程登陸(telnet、ssh、xterm等)后創(chuàng)建的控制臺設備。

歷史上,有兩套偽終端軟件接口:

BSD接口:較簡單,master為/dev/pty [p-za-e] [0-9a-f];slave為 /dev/tty [p-za-e] [0-9a-f] ,它們都是配對的出現(xiàn)的。例如/dev/ptyp3和/dev/ttyp3。但由于在編程時要找到一個合適的終端需要逐個嘗試,所以逐漸被放棄。

Unix 98接口:使用一個/dev/ptmx作為master設備,在每次打開操作時會得到一個master設備fd,并在/dev/pts/目錄下得到一個slave設備(如 /dev/pts/3和/dev/ptmx),這樣就避免了逐個嘗試的麻煩。

由于可能有好幾千個用戶登陸,所以/dev/pts/* 是動態(tài)生成的,不象其他設備文件是構建系統(tǒng)時就已經產生的硬盤節(jié)點(如果未使用devfs、udev、mdev等) 。第一個用戶登陸,設備文件為/dev/pts/0,第二個為/dev/pts/1,以此類推。它們并不與實際物理設備直接相關?,F(xiàn)在大多數(shù)系統(tǒng)是通過此接口實現(xiàn)pty。

我們在X Window下打開的終端或使用telnet或ssh等方式登錄Linux主機,此時均通過pty設備。例如,如果某人在網上使用telnet程序連接到你的計算機上,則telnet程序就可能會打開/dev/ptmx設備獲取一個fd。此時一個getty程序就應該運行在對應的/dev/pts/* 上。當telnet從遠端獲取了一個字符時,該字符就會通過ptmx、pts/* 傳遞給 getty程序,而getty程序就會通過pts/* 、ptmx和telnet程序往網絡上返回“l(fā)ogin:”字符串信息。這樣,登錄程序與telnet程序就通過“偽終端”進行通信。

telnet《---》/dev/ptmx(master)《---》pts/*(slave)《---》getty

如果一個程序把 pts/* 看作是一個串行端口設備,則它對該端口的讀/寫操作會反映在該邏輯終端設備對的另一個/dev/ptmx上,而/dev/ptmx則是另一個程序用于讀寫操作的邏輯設備。

這樣,兩個程序就可以通過這種邏輯設備進行互相交流,這很象是邏輯設備對之間的管道操作。對于pts/* ,任何設計成使用一個串行端口設備的程序都可以使用該邏輯設備。但對于使用/dev/ptmx的程序,則需要專門設計來使用/dev/ptmx邏輯設備。通過使用適當?shù)能浖?,就可以把兩個甚至多個偽終端設備連接到同一個物理串行端口上。

3、 串口終端(/dev/ttySn)

串行端口終端(Serial PortTerminal)是使用計算機串行端口連接的終端設備。計算機把每個串行端口都看作是一個字符設備。有段時間串行端口設備通常被稱為終端設備,那時它的最大用途就是用來連接終端,所以這些串行端口所對應的設備名稱是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev /ttyS1)等,設備號分別是(4,0)、(4,1)等(對應于win系統(tǒng)下的COM1、COM2等)。若要向一個端口發(fā)送數(shù)據(jù),可以在命令行上把標準輸出重定向到這些特殊文件名上即可。

我們可以在命令行提示符下鍵入:echotekkaman》 /dev/ttyS1會把“tekkaman”發(fā)送到連接在ttyS1(COM2)端口的設備上。

在2.6以后的內核后、一些三星的芯片將串口終端設備節(jié)點命名為ttySACn。TI的Omap系列芯片從2.6.37開始芯片自帶的UART設備開始使用專有的的omap-uart驅動,故設備節(jié)點命名為ttyOn,以區(qū)別于使用8250驅動時的設備名“ttySn”。這其中包括筆者用到的這個S3C2440。所以我們在Uboot啟動參數(shù)中要設置console = ttySAC0才可以。這一句的意思其實就是把ttySAC0當做我們的控制臺終端。

4、 其它類型終端

還針對很多不同的字符設備存在有很多其它種類的終端設備特殊文件,例如針對ISDN設備的/dev/ttyIn終端設備等。

好了。到此為止。相信讀者已經對tty設備有了一個概觀。

因為我們和開發(fā)板的人機交互的接口是Windows下的串口控制臺。這就是上面所說的控制臺終端。但是我們用了console = ttySAC0.即把串口終端當做控制臺終端。所以我們要研究具體的代碼需要cd到serial子目錄下。即串口終端目錄。ls顯示serial下的文件結點。如圖所示:

我們主要關心的是兩類文件。一類是與體系結構和板載資源無關的通用串口操作文件。(samsung.c)一類是與體系結構相關的硬件操作文件。(s3c2440.c s3c2410.c s5pv210.c等),我們?yōu)榱说玫骄唧w的調用鏈。在具體的發(fā)送函數(shù)中加入回溯。如圖所示。

我們得到的函數(shù)調用鏈是這樣的(以發(fā)送函數(shù)。即文件的寫操作為例。

write-》

sys_write-》

vfs_write-》

redirected_tty_write-》

tty_write-》

n_tty_write-》

uart_write-》

uart_start-》

s3c24xx_serial_start_tx

從具體代碼上來看。這些函數(shù)基本上都是通過結構體中的函數(shù)指針調用。我們可以把這個調用鏈分為三個部分。即tty子系統(tǒng)核心。tty鏈路規(guī)程。tty驅動

tty核心。是對整個tty設備的抽象。對用戶提供統(tǒng)一的接口。包括sys_write-》vfs_write

tty線路規(guī)程。是對傳輸數(shù)據(jù)的格式化。在tty_ldisc_N_TTY變量中描述。包括redirected_tty_write-》tty_write-》n_tty_write-》

tty驅動。是面向tty設備的硬件驅動。這里面真正的對硬件進行操作。包括uart_write-》uart_start-》s3c24xx_serial_start_tx

這是從具體函數(shù)的角度來看的調用鏈。下面為了從數(shù)據(jù)結構的角度來分析調用鏈。介紹linux內核中針對于這一個串口硬件的主要數(shù)據(jù)結構。對于具體的字段我們用到的時候再解釋。

uart_driver。

就是uart驅動程序結構。封裝了tty_driver,使得底層的UART驅動無需關心tty_driver具體定義如下。

uart_port

uart_port用于描述一個UART端口(直接對應于一個串口)的I/O端口或者IO內存地址等信息。

uart_ops定義了針對UART的一系列操作。注意這里不要把uart_ops結構和uart_ops變量混淆。uart_ops結構是我們這里的數(shù)據(jù)結構。而uart_ops變量則是一個tty_operations的變量。

在serial_core.c中定義了tty_operations的實例。即uart_ops變量,包含uart_open();uart_close();uart_send_xchar()等成員函數(shù),這些函數(shù)借助uart_ops結構體中的成員函數(shù)來完成具體的操作:

uart_ops變量是tty_operations型的一個變量。如下圖所示:

uart_state是uart的狀態(tài)結構。

uart_info是uart的信息結構。在這個體系結構下定義為s3c24xx_uart_info:

所以很顯然。用數(shù)據(jù)結構來描述函數(shù)調用鏈就是

uart_driver -》

uart_state-》

uart_port-》

uart_ops-》

特定的函數(shù)指針。

初始化過程比較復雜。不贅述。從函數(shù)指針的調用流程為主線。忽略一些入?yún)z查和內核中的信號量代碼。大致的初始化流程如下圖所示:

打開設備和初始化流程類似。如圖所示:

同理數(shù)據(jù)的發(fā)送和接收如圖所示:

這里我們需要注意的是。使能發(fā)送并沒有真正的發(fā)送過程。而只是使能發(fā)送中斷

這一句:enable_irq(ourport-》tx_irq);

這是因為ARM9處理器上有一個循環(huán)緩沖。用戶從write系統(tǒng)調用傳下來的數(shù)據(jù)就會寫入這個UTXH0寄存器。發(fā)送完事之后處理器會產生一個內部中斷。我們通過這個內部中斷就可以實現(xiàn)流控過程、我們打開芯片手冊可以看到如下字樣(拿ARM11舉例也一樣,。這是ARM11的):

如下才是發(fā)送中斷的ISR(Interrupt Service Routine)中斷服務例程。一個irqreturn_t類型的handler。

這個wr_regb(port, S3C2410_UTXH, port-》x_char);就是往特定寄存器寫的過程。

至此我們的分析已經結束。相信讀者對于Linux下的tty子系統(tǒng)已經有一個概觀了。下面是這個uart驅動的總圖。結合數(shù)據(jù)結構的調用鏈。Linux內核完成了驅動模型和特定硬件的分離:

串口驅動數(shù)據(jù)結構總圖:

-END-

直接來源 | 嵌入式大雜燴

作者:Linkerist

責任編輯:haq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 驅動
    +關注

    關注

    12

    文章

    1812

    瀏覽量

    85047
  • Linux
    +關注

    關注

    87

    文章

    11171

    瀏覽量

    208471
  • 操作系統(tǒng)

    關注

    37

    文章

    6606

    瀏覽量

    123023
收藏 人收藏

    評論

    相關推薦

    CP210X串口驅動

    電子發(fā)燒友網站提供《CP210X串口驅動.zip》資料免費下載
    發(fā)表于 10-17 13:40 ?0次下載

    LSP 2.10 DaVinci Linux驅動程序

    電子發(fā)燒友網站提供《LSP 2.10 DaVinci Linux驅動程序.pdf》資料免費下載
    發(fā)表于 10-09 09:30 ?0次下載
    LSP 2.10 DaVinci <b class='flag-5'>Linux</b><b class='flag-5'>驅動</b>程序

    驅動到空調、機器人應用,剖析格力的電機布局

    。比如,在空調中,電機是核心的零部件,因此受到格力電器等公司的廣泛重視,并將其作為核心技術儲備進行研發(fā)和布局。 ? 不過,隨著企業(yè)生態(tài)擴充和鏈式布局,目前格力電器的電機布局應該貫穿驅動到應用整個鏈條,形成了完
    的頭像 發(fā)表于 10-09 00:10 ?3747次閱讀

    串口驅動分析之serial driver

    前兩節(jié)我們介紹串口驅動的框架和tty core部分。這節(jié)我們介紹和硬件緊密相關的串口驅動部分。
    的頭像 發(fā)表于 09-04 14:23 ?227次閱讀
    <b class='flag-5'>串口</b><b class='flag-5'>驅動</b>分析之serial driver

    linux系統(tǒng)的設備驅動一般分幾類

    Linux系統(tǒng)的設備驅動是操作系統(tǒng)與硬件設備之間的橋梁,負責實現(xiàn)操作系統(tǒng)與硬件設備之間的通信和控制。Linux系統(tǒng)的設備驅動可以分為以下幾類: 字符設備
    的頭像 發(fā)表于 08-30 15:13 ?285次閱讀

    Linux設備驅動程序分類有哪些

    Linux設備驅動程序是操作系統(tǒng)與硬件設備之間的橋梁,負責實現(xiàn)硬件設備與操作系統(tǒng)之間的通信和控制。Linux設備驅動程序的分類繁多,可以根據(jù)不同的標準進行分類。 按硬件類型分類
    的頭像 發(fā)表于 08-30 15:11 ?320次閱讀

    linux驅動程序如何加載進內核

    ,需要了解Linux內核的基本概念和API。以下是一些關鍵概念: 1.1 內核模塊:Linux內核模塊是一種動態(tài)加載和卸載的代碼,可以在不重新啟動系統(tǒng)的情況下加載和卸載。驅動程序通常以內核模塊的形式實現(xiàn)。 1.2 設備
    的頭像 發(fā)表于 08-30 15:02 ?287次閱讀

    linux驅動程序主要有哪些功能

    Linux驅動程序是操作系統(tǒng)與硬件設備之間進行通信的橋梁,負責實現(xiàn)硬件設備與操作系統(tǒng)之間的數(shù)據(jù)交換和控制。Linux驅動程序的主要功能包括以下幾個方面: 設備識別與初始化
    的頭像 發(fā)表于 08-30 14:47 ?226次閱讀

    linux驅動程序的編譯方法是什么

    的源代碼中,并隨內核一起編譯。這種方法適用于驅動程序已經非常穩(wěn)定,且不打算頻繁修改的情況。具體步驟如下: 下載并安裝Linux內核源代碼 :Linux官方網站或可靠的源下載所需的內核
    的頭像 發(fā)表于 08-30 14:46 ?250次閱讀

    linux驅動程序運行在什么空間

    Linux 驅動程序是操作系統(tǒng)的一部分,負責管理硬件設備與操作系統(tǒng)之間的交互。驅動程序運行在內核空間(Kernel Space),這是操作系統(tǒng)的核心部分,與用戶空間(User Space)相對。內核
    的頭像 發(fā)表于 08-30 14:37 ?230次閱讀

    Linux 驅動開發(fā)與應用開發(fā),你知道多少?

    一、Linux驅動開發(fā)與應用開發(fā)的區(qū)別開發(fā)層次不同:Linux驅動開發(fā)主要是針對硬件設備進行編程,處于操作系統(tǒng)內核層,直接與硬件交互,為上層應用提供設備訪問的接口。
    的頭像 發(fā)表于 08-30 12:16 ?361次閱讀
    <b class='flag-5'>Linux</b> <b class='flag-5'>驅動</b>開發(fā)與應用開發(fā),你知道多少?

    STC串口驅動調試程序

    STC的串口驅動調試程序。
    發(fā)表于 07-08 14:23 ?2次下載

    臺達串口DVP系列驅動如何使用?

    詳細介紹如何使用臺達串口DVP系列驅動
    發(fā)表于 12-29 11:06 ?1次下載

    linux驅動程序的主要流程和功能

    驅動程序是用于控制和管理硬件設備的軟件模塊,它主要負責與設備進行交互,通過操作設備的寄存器和接口,實現(xiàn)對硬件的控制和訪問。在Linux系統(tǒng)中,驅動程序是實現(xiàn)與硬件設備交互的一個關鍵部分。本文將詳細
    的頭像 發(fā)表于 12-08 14:56 ?2054次閱讀

    linux安裝網卡驅動教程

    Linux系統(tǒng)中安裝網卡驅動是一個比較基礎的操作,下面我將為你詳細講解如何安裝網卡驅動。 第一步,檢查網卡型號和驅動支持情況:首先,你需要確定你的網卡型號,并查看該網卡型號在
    的頭像 發(fā)表于 11-17 11:11 ?3684次閱讀