技術(shù)文章:基于Linux的tty架構(gòu)及UART驅(qū)動(dòng)詳解
本文由技術(shù)大拿:蒙工 投稿!
桂電畢業(yè)的資深嵌入式專家。
一、模塊硬件學(xué)習(xí)
1.1. Uart介紹
通用異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter),通常稱為UART,是一種異步收發(fā)傳輸器,是電腦硬件的一部分。它將要傳輸?shù)馁Y料在串行通信與并行通信之間加以轉(zhuǎn)換。
作為把并行輸入信號(hào)轉(zhuǎn)成串行輸出信號(hào)的芯片,UART 通常被集成于其他通訊接口的連上。
UART 是一種通用串行數(shù)據(jù)總線,用于異步通信。該總線雙向通信,可以實(shí)現(xiàn)全雙工傳輸和接收。在嵌入式設(shè)備中,UART 用于主機(jī)與輔助設(shè)備通信,如汽車音與外接AP 之間的通信,與PC 機(jī)通信包括與監(jiān)控調(diào)試器和其它器件,如EEPOM通信。
1.1.1. 通信協(xié)議
UART作為異步串口通信協(xié)議的一種,工作原理是將傳輸數(shù)據(jù)的每個(gè)字符一位接一位地傳輸。其中各位的意義如下:
起始位:先發(fā)出一個(gè)邏輯”0”的信號(hào),表示傳輸字符的開始。
數(shù)據(jù)位:緊接著起始位之后。數(shù)據(jù)位的個(gè)數(shù)可以是5、6、7、8等,構(gòu)成一個(gè)字符。通常采用ASCII碼。從最低位開始傳送,靠時(shí)鐘定位。
奇偶校驗(yàn)位:數(shù)據(jù)位加上這一位后,使得“1”的位數(shù)應(yīng)為偶數(shù)(偶校驗(yàn))或奇數(shù)(奇校驗(yàn)),以此來校驗(yàn)數(shù)據(jù)傳送的正確性。
停止位:它是一個(gè)字符數(shù)據(jù)的結(jié)束標(biāo)志?梢允1位、1.5位、2位的高電平。
由于數(shù)據(jù)是在傳輸線上定時(shí)的,并且每一個(gè)設(shè)備有其自己的時(shí)鐘,很可能在通信中兩臺(tái)設(shè)備間出現(xiàn)了小小的不同步。因此停止位不僅僅是表示傳輸?shù)慕Y(jié)束,并且提供計(jì)算機(jī)校正時(shí)鐘同步的機(jī)會(huì)。適用于停止位的位數(shù)越多,不同時(shí)鐘同步的容忍程度越大,但是數(shù)據(jù)傳輸率同時(shí)也越慢。
空閑位:處于邏輯“1”狀態(tài),表示當(dāng)前線路上沒有數(shù)據(jù)傳送。
Uart傳輸數(shù)據(jù)如圖2-1所示:
1.1.2. 波特率
波特率是衡量資料傳送速率的指標(biāo)。表示每秒鐘傳送的符號(hào)數(shù)(symbol)。一個(gè)符號(hào)代表的信息量(比特?cái)?shù))與符號(hào)的階數(shù)有關(guān)。例如傳輸使用256階符號(hào),每8bit代表一個(gè)符號(hào),數(shù)據(jù)傳送速率為120字符/秒,則波特率就是120 baud,比特率是120*8=960bit/s。這兩者的概念很容易搞錯(cuò)。
UART 的接收和發(fā)送是按照相同的波特率進(jìn)行收發(fā)的。波特率發(fā)生器產(chǎn)生的時(shí)鐘頻率不是波特率時(shí)鐘頻率,而是波特率時(shí)鐘頻率的16倍,目的是為在接收時(shí)進(jìn)行精確的采樣,以提取出異步的串行數(shù)據(jù)。根據(jù)給定的晶振時(shí)鐘和要求的波特率,可以算出波特率分頻計(jì)數(shù)值。
1.1.3. 工作原理
發(fā)送數(shù)據(jù)過程:空閑狀態(tài),線路處于高電位;當(dāng)收到發(fā)送數(shù)據(jù)指令后,拉低線路一個(gè)數(shù)據(jù)位的時(shí)間T,接著數(shù)據(jù)位按低位到高位依次發(fā)送,數(shù)據(jù)發(fā)送完畢后,接著發(fā)送奇偶檢驗(yàn)位和停止位(停止位為高電位),一幀數(shù)據(jù)發(fā)送結(jié)束。
接收數(shù)據(jù)過程: 空閑狀態(tài),線路處于高電位;當(dāng)檢測(cè)到線路的下降沿(線路電位由高電位變?yōu)榈碗娢唬⿻r(shí)說明線路有數(shù)據(jù)傳輸,按照約定的波特率從低位到高位接收數(shù)據(jù),數(shù)據(jù)接收完畢后,接著接收并比較奇偶檢驗(yàn)位是否正確,如果正確則通知?jiǎng)t通知后續(xù)設(shè)備準(zhǔn)備接收數(shù)據(jù)或存入緩存。
由于UART是異步傳輸,沒有傳輸同步時(shí)鐘。為了能保證數(shù)據(jù)傳輸?shù)恼_性,UART采用16倍數(shù)據(jù)波特率的時(shí)鐘進(jìn)行采樣。每個(gè)數(shù)據(jù)有16個(gè)時(shí)鐘采樣,取中間的采樣值,以保證采樣不會(huì)滑碼或誤碼。
一般UART一幀的數(shù)據(jù)位為8,這樣即使每一個(gè)數(shù)據(jù)有一個(gè)時(shí)鐘的誤差,接收端也能正確地采樣到數(shù)據(jù)。
UART的接收數(shù)據(jù)時(shí)序?yàn)椋寒?dāng)檢測(cè)到數(shù)據(jù)下降沿時(shí),表明線路上有數(shù)據(jù)進(jìn)行傳輸,這時(shí)計(jì)數(shù)器CNT開始計(jì)數(shù),當(dāng)計(jì)數(shù)器,當(dāng)計(jì)數(shù)器為8時(shí),采樣的值為“0”表示開始位;當(dāng)計(jì)數(shù)器為24=161+8時(shí),采樣的值為bit0數(shù)據(jù);當(dāng)計(jì)數(shù)器的值為40=162+8時(shí),采樣的值為bit1數(shù)據(jù);依次類推,進(jìn)行后面6個(gè)數(shù)據(jù)的采樣。如果需要進(jìn)行奇偶校驗(yàn)位,則當(dāng)計(jì)數(shù)器的值為152=169+8時(shí),采樣的值為奇偶位;當(dāng)計(jì)數(shù)器的值為168=1610+8時(shí),采樣的值為“1”表示停止位,一幀數(shù)據(jù)收發(fā)完成。
1.1.4. RS232與RS485
UART:通常說的UART指的是一種串行通信協(xié)議,規(guī)定了數(shù)據(jù)幀格式,波特率等。RS232和RS485:是兩種不同的電氣協(xié)議,也就是說,是對(duì)電氣特性以及物理特性的規(guī)定,作用于數(shù)據(jù)的傳輸通路上,它并不含對(duì)數(shù)據(jù)的處理方式。
對(duì)應(yīng)的物理器件有RS232或者RS485驅(qū)動(dòng)芯片,將CPU經(jīng)過UART傳送過來的電壓信號(hào)驅(qū)動(dòng)成RS232或者RS485電平邏輯。
RS232使用3-15V有效電平,而UART,因?yàn)閷?duì)電氣特性沒有規(guī)定,所以直接使用CPU使用的電平,即TTL電平(在0-3.3V之間)。
更具體的,電氣的特性也決定了線路的連接方式,比如RS232,規(guī)定用電平表示數(shù)據(jù),因此線路就是單線路的,兩根線能達(dá)到全雙工的目的;RS485使用差分電平表示數(shù)據(jù),因此必須用兩根線才能達(dá)到傳輸數(shù)據(jù)的基本要求,要實(shí)現(xiàn)全雙工,必須使用4根線。
RS232和RS485的區(qū)別(1)抗干擾性
RS485 接口是采用平衡驅(qū)動(dòng)器和差分接收器的組合,具有抑制共模干擾的能力,抗噪聲干擾性強(qiáng)。RS232接口使用一根信號(hào)線和一根信號(hào)返回線而構(gòu)成供地的傳輸形式,這種共地傳輸容易產(chǎn)生共模干擾,所以抗噪聲干擾性弱。(2)傳輸距離RS485 接口的最大傳輸距離標(biāo)準(zhǔn)值為1200 米(9600bps 時(shí)),實(shí)際上可達(dá)3000米。RS232 傳輸距離有限,最大傳輸距離標(biāo)準(zhǔn)值為50米,實(shí)際上也只能用15米左右。(3)通信能力RS485接口在總線上最多可以連接128個(gè)收發(fā)器,即具有多站能力,而這樣的用戶可以利用單一的RS485接口方便的建立起設(shè)備網(wǎng)絡(luò)。RS232只允許一對(duì)一通信。(4)傳輸速率RS232傳輸速率較低,在異步傳輸時(shí),波特率為20Kbps.RS485的數(shù)據(jù)最高傳輸速率為10Mbps.(5) 信號(hào)線RS485全雙工:uart-tx 1根線,變成 RS485- A/B 2根線;uart-rx 1根線,變成 RS485- x/y 2根線,RS485半雙工: 將全雙工的 A/B; X/Y 合并起來,分時(shí)復(fù)用。RS232只允許一對(duì)一通信(6)電氣電平值邏輯“1”以兩線間的電壓差為+(2-6)V表示;邏輯“0”以兩線間的電壓差為-(2-6)V表示。在RS232中任何一條信號(hào)的電壓均為負(fù)邏輯關(guān)系。即:邏輯“1”-5-15V;邏輯“0”,+5~+15V,噪聲容限為2V。即要求接收器能識(shí)別低至+3V的信號(hào)作為邏輯“0”,高到-3V的信號(hào)的信號(hào)作為邏輯“1”。RS232接口的信號(hào)電平值較高,易損壞接口電路的芯片,又因?yàn)榕cTTL電平不兼容故使用電平轉(zhuǎn)換電路方能與TTL電路連接。RS485接口信號(hào)電平比RS232降低了,就不易損壞接口電路的芯片,且該電平與TTL電平兼容,方便與TTL電路連接。1.1.5. 流控
數(shù)據(jù)在兩個(gè)串口傳輸時(shí),常常會(huì)出現(xiàn)丟失數(shù)據(jù)的現(xiàn)象,或者兩臺(tái)計(jì)算機(jī)的處理速度不同,如臺(tái)式機(jī)與單片機(jī)之間的通訊,接收端數(shù)據(jù)緩沖區(qū)以滿,此時(shí)繼續(xù)發(fā)送的數(shù)據(jù)就會(huì)丟失,流控制能解決這個(gè)問題,當(dāng)接收端數(shù)據(jù)處理不過來時(shí),就發(fā)出“不再接收”的信號(hào),發(fā)送端就停止發(fā)送,直到收到“可以繼續(xù)發(fā)送”的信號(hào)再發(fā)送數(shù)據(jù)。
因此流控制可以控制數(shù)據(jù)傳輸?shù)倪M(jìn)程,防止數(shù)據(jù)丟失。PC機(jī)中常用的兩種流控為:硬件流控(包括RTS/CTS、DTR/CTS等)和軟件流控制XON/XOFF(繼續(xù)/停止)。
1.1.5.1. 硬件流控
硬件流控制常用的有RTS/CTS流控制和DTR/DSR流控制兩種。
DTR–數(shù)據(jù)終端就緒(Data Terminal Ready)低有效,當(dāng)為低時(shí),表示本設(shè)備自身準(zhǔn)備就緒。此信號(hào)輸出對(duì)端設(shè)備,使用對(duì)端設(shè)備決定能否與本設(shè)備通信。
DSR-數(shù)據(jù)裝置就緒(Data Set Ready)低有效,此信號(hào)由本設(shè)備相連接的對(duì)端設(shè)備提供,當(dāng)為低時(shí),本設(shè)備才能與設(shè)備端進(jìn)行通信。
RTS - 請(qǐng)求發(fā)送(數(shù)據(jù))(Request To Send)低有效,此信號(hào)由本設(shè)備在需要發(fā)送數(shù)據(jù)給對(duì)端設(shè)備時(shí)設(shè)置。當(dāng)為低時(shí),表示本設(shè)備有數(shù)據(jù)需要向?qū)Χ嗽O(shè)備發(fā)送。對(duì)端設(shè)備能否接收到本方的發(fā)送數(shù)據(jù),則通過CTS信號(hào)來應(yīng)答。
CTS - 接收發(fā)送(請(qǐng)求)(Clear To Send)低有效,對(duì)端設(shè)備能否接收本方所發(fā)送的數(shù)據(jù),由CTS決定。若CTS為低,則表示對(duì)端的以準(zhǔn)備好,可以接收本端發(fā)送數(shù)據(jù)。
以RTS/CTS流控制分析,分析主機(jī)發(fā)送/接收流程:
物理連接
主機(jī)的RTS(輸出信號(hào)),連接到從機(jī)的CTS(輸入信號(hào))。主機(jī)是CTS(輸入信號(hào)),連接到從機(jī)的RTS(輸入信號(hào))。
1.主機(jī)的發(fā)送過程:主機(jī)查詢主機(jī)的CTS腳信號(hào),此信號(hào)連接到從機(jī)的RTS信號(hào),受從機(jī)控制。如果主機(jī)CTS信號(hào)有效(為低),表示從機(jī)的接收FIFO未滿,從機(jī)可以接收,此時(shí)主機(jī)可以向從機(jī)發(fā)送數(shù)據(jù),并且在發(fā)送過程中要一直查詢CTS信號(hào)是否為有效狀態(tài)。主機(jī)查詢到CTS無效時(shí),則中止發(fā)送。主機(jī)的CTS信號(hào)什么時(shí)候會(huì)無效呢?從機(jī)在接收到主機(jī)發(fā)送的數(shù)據(jù)時(shí),從機(jī)的接收模塊的FIFO如果滿了,則會(huì)使從機(jī)RTS無效,也即主機(jī)的CTS信號(hào)無效。主機(jī)查詢到CTS無效時(shí),主機(jī)發(fā)送中止。
2.主機(jī)接收模式:如果主機(jī)接收FIFO未滿,那么使主機(jī)RTS信號(hào)有效(為低),即從機(jī)的CTS信號(hào)有效。此時(shí)如果從機(jī)要發(fā)送,發(fā)送前會(huì)查詢從機(jī)的CTS信號(hào),如果有效,則開始發(fā)送。并且在發(fā)送過程中要一直查詢從機(jī)CTS信號(hào)的有效狀態(tài),如果無效則終止發(fā)送。是否有效由主機(jī)的RTS信號(hào)決定。如果主機(jī)FIFO滿了,則使主機(jī)的RTS信號(hào)無效,也即從機(jī)CTS信號(hào)無效,主機(jī)接收中止。
1.1.5.2. 軟件流控
由于電纜的限制,在普通的控制通訊中一般不采用硬件流控制,而是使用軟件流控制。
一般通過XON/XOFF來實(shí)現(xiàn)軟件流控制。常用方法是:當(dāng)接收端的輸入緩沖區(qū)內(nèi)數(shù)據(jù)量超過設(shè)定的高位時(shí),就向數(shù)據(jù)發(fā)送端發(fā)送XOFF字符后就立即停止發(fā)送數(shù)據(jù)。
當(dāng)接收端的輸入緩沖區(qū)內(nèi)數(shù)據(jù)量低于設(shè)定的低位時(shí),就向數(shù)據(jù)發(fā)送端發(fā)送XON字符(十進(jìn)制的17或Control-Q),發(fā)送端收到XON字符后就立即開始發(fā)送數(shù)據(jù)。
一般可從設(shè)備配套源程序中找到發(fā)送端收到XON字符后就立即發(fā)送數(shù)據(jù)。一般可以從設(shè)備配套源程序中找到發(fā)送的是什么字節(jié)。
應(yīng)注意,若傳輸?shù)氖嵌M(jìn)制的數(shù)據(jù),標(biāo)志字符也可能在數(shù)據(jù)流中出現(xiàn)而引起誤操作,這是軟件流控的缺陷,而硬件流控不會(huì)出現(xiàn)這樣的問題。
二、Linux serial框架
在Linux系統(tǒng)中,終端是一種字符型設(shè)備,它有多種類型,通常使用tty(Teletype)來簡(jiǎn)稱各種類型的終端設(shè)備。
對(duì)于嵌入式系統(tǒng)而言,最普遍采用的是Uart(Universal Asynchronous Receiver/Transmitter),串行端口,日常生活中簡(jiǎn)稱端口
2.1. TTY驅(qū)動(dòng)程序框架2.1.1. TTY概念2.1.1.1. 串口終端(/dev/ttyS*)
串口終端是使用計(jì)算機(jī)串口連接的終端設(shè)備。Linux把每個(gè)串行端口都看做是一個(gè)字符設(shè)備。這些串行端口所對(duì)應(yīng)的設(shè)備名稱是/dev/ttySAC*;
2.1.1.2. 控制臺(tái)終端(/dev/console)
在Linux系統(tǒng)中,計(jì)算機(jī)的輸出設(shè)備通常被稱為控制臺(tái)終端,這里特指printk信息輸出到設(shè)備。/dev/console是一個(gè)虛擬的設(shè)備,它需要映射到真正的tty上,比如通過內(nèi)核啟動(dòng)參數(shù)“console=ttySCA0”就把console映射到了串口0
2.1.1.3. 虛擬終端(/dev/tty*)
當(dāng)用戶登錄時(shí),使用的是虛擬終端。使用Ctcl+Alt[F1 - F6]組合鍵時(shí),我們就可以切換到tty1、tty2、tty3等上面去。tty*就稱為虛擬終端,而tty0則是當(dāng)前所使用虛擬終端的一個(gè)別名。
2.1.2. TTY架構(gòu)分析
整個(gè) tty架構(gòu)大概的樣子如圖3.1所示,簡(jiǎn)單來分的話可以說成兩層,一層是下層我們的串口驅(qū)動(dòng)層,它直接與硬件相接觸,我們需要填充一個(gè) struct uart_ops 的結(jié)構(gòu)體,另一層是上層 tty 層,包括 tty 核心以及線路規(guī)程,它們各自都有一個(gè) Ops 結(jié)構(gòu),用戶空通過間是 tty 注冊(cè)的字符設(shè)備節(jié)點(diǎn)來訪問。
圖3.1tty架構(gòu)圖
如圖3.2所示,tty設(shè)備發(fā)送數(shù)據(jù)的流程為:tty核心從一個(gè)用戶獲取將要發(fā)送給一個(gè)tty設(shè)備的數(shù)據(jù),tty核心將數(shù)據(jù)傳遞給tty線路規(guī)程驅(qū)動(dòng),接著數(shù)據(jù)被傳到tty驅(qū)動(dòng),tty驅(qū)動(dòng)將數(shù)據(jù)轉(zhuǎn)換為可以發(fā)給硬件的格式。
接收數(shù)據(jù)的流程為:從tty硬件接收到的數(shù)據(jù)向上交給tty驅(qū)動(dòng),接著進(jìn)入tty線路規(guī)程驅(qū)動(dòng),再進(jìn)入tty核心,在這里它被一個(gè)用戶獲取。
圖3.2 tty設(shè)備發(fā)送、接收數(shù)據(jù)流程2.2. 關(guān)鍵數(shù)據(jù)結(jié)構(gòu)2.2.1. Struct uart_driver
uart_driver 包含了串口設(shè)備名,串口驅(qū)動(dòng)名,主次設(shè)備號(hào),串口控制臺(tái)(可選))等信息,還封裝了tty_driver(底層串口驅(qū)動(dòng)無需關(guān)心tty_driver)
struct uart_driver {
struct module *owner; 擁有該uart_driver的模塊,一般為THIS_M(jìn)ODULE
const char *driver_name; 驅(qū)動(dòng)串口名,串口設(shè)備名以驅(qū)動(dòng)名為基礎(chǔ)
const char *dev_name; 串口設(shè)備名
int major; 主設(shè)備號(hào)
int minor; 次設(shè)備號(hào)
int nr; 該uart_driver支持的串口數(shù)
struct console *cons; 其對(duì)應(yīng)的console,若該uart_driver支持serial console,
*否則為NULL
* these are private; the low level driver should not
* touch these; they should be initialised to NULL
struct uart_state *state; 下層,窗口驅(qū)動(dòng)層
struct tty_driver *tty_driver; tty相關(guān)
2.2.2. struct console
實(shí)現(xiàn)控制臺(tái)打印功能必須要注冊(cè)的結(jié)構(gòu)體
struct console {
char name[16];
void(*write)(struct console *,const char *, unsigined);
int (*read)(struct console *, char *, unsigned);
struct tty_driver *(struct console *,int*);
void (*unblank)(void);
int (*setup)(struct console *, char *);
int (*early_setup)(void);
short flags;
short index; 用來指定該console使用哪一個(gè)uart port (對(duì)應(yīng)的uart_port中的line),如果為-1,kernel會(huì)自動(dòng)選擇第一個(gè)uart port
int cflag;
void *data;
struct console *next;
};
發(fā)表評(píng)論
請(qǐng)輸入評(píng)論內(nèi)容...
請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字
最新活動(dòng)更多
-
10月31日立即下載>> 【限時(shí)免費(fèi)下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
-
即日-11.13立即報(bào)名>>> 【在線會(huì)議】多物理場(chǎng)仿真助跑新能源汽車
-
11月28日立即報(bào)名>>> 2024工程師系列—工業(yè)電子技術(shù)在線會(huì)議
-
12月19日立即報(bào)名>> 【線下會(huì)議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會(huì)
-
即日-12.26火熱報(bào)名中>> OFweek2024中國(guó)智造CIO在線峰會(huì)
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍(lán)皮書》
推薦專題
- 1 【一周車話】沒有方向盤和踏板的車,你敢坐嗎?
- 2 特斯拉發(fā)布無人駕駛車,還未迎來“Chatgpt時(shí)刻”
- 3 特斯拉股價(jià)大跌15%:Robotaxi離落地還差一個(gè)蘿卜快跑
- 4 馬斯克給的“驚喜”夠嗎?
- 5 大模型“新星”開啟變現(xiàn)競(jìng)速
- 6 海信給AI電視打樣,12大AI智能體全面升級(jí)大屏體驗(yàn)
- 7 打完“價(jià)格戰(zhàn)”,大模型還要比什么?
- 8 馬斯克致敬“國(guó)產(chǎn)蘿卜”?
- 9 神經(jīng)網(wǎng)絡(luò),誰(shuí)是盈利最強(qiáng)企業(yè)?
- 10 比蘋果偉大100倍!真正改寫人類歷史的智能產(chǎn)品降臨
- 高級(jí)軟件工程師 廣東省/深圳市
- 自動(dòng)化高級(jí)工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級(jí)銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市