Linux TTY 串口 struct termios結構體參數

在 struct tty_driver 中的 init_termios 變量是一個 struct termios. 這個變量被用來提供一個健全的線路設置集合, 如果這個端口在被用戶初始化前使用. 驅動初始化這個變量使用一個標準的數值集, 它拷貝自 tty_std_termios 變量. tty_std_termos 在 tty 核心被定義爲:

struct termios tty_std_termios = {
 .c_iflag = ICRNL | IXON,
 .c_oflag = OPOST | ONLCR,
 .c_cflag = B38400 | CS8 | CREAD | HUPCL,
 .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK |
 ECHOCTL | ECHOKE | IEXTEN,
 .c_cc = INIT_C_CC
};

這個 struct termios 結構用來持有所有的當前線路設置, 給這個 tty 設備的一個特定端口. 這些線路設置控制當前波特率, 數據大小, 數據流控設置, 以及許多其他值. 這個結構的不同成員是:

tcflag_t c_iflag; 輸入模式標誌
tcflag_t c_oflag; 輸出模式標誌
tcflag_t c_cflag; 控制模式標誌
tcflag_t c_lflag; 本地模式標誌
cc_t c_line; 線路規程類型
cc_t c_cc[NCCS]; 一個控制字符數組

Linux 爲我們提供了專門的設置修改參數的接口如下:

NAME
       termios,  tcgetattr,  tcsetattr,  tcsendbreak, tcdrain, tcflush, tcflow, cfmakeraw, cfgetospeed, cfgetispeed, cfsetispeed, cfsetospeed, cfsetspeed - get and set terminal attributes, line con‐
       trol, get and set baud rate

SYNOPSIS
       #include <termios.h>
       #include <unistd.h>

       int tcgetattr(int fd, struct termios *termios_p);

       int tcsetattr(int fd, int optional_actions,
                     const struct termios *termios_p);

       int tcsendbreak(int fd, int duration);

       int tcdrain(int fd);

       int tcflush(int fd, int queue_selector);

       int tcflow(int fd, int action);

       void cfmakeraw(struct termios *termios_p);

       speed_t cfgetispeed(const struct termios *termios_p);

       speed_t cfgetospeed(const struct termios *termios_p);

       int cfsetispeed(struct termios *termios_p, speed_t speed);

       int cfsetospeed(struct termios *termios_p, speed_t speed);

       int cfsetspeed(struct termios *termios_p, speed_t speed);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       cfsetspeed(), cfmakeraw(): _BSD_SOURCE

描述
termios功能描述了提供的通用終端接口,用於控制異步通信端口。

termios struct:
此處描述的許多功能都有一個termios_p參數,該參數是指向termios結構的指針。此結構至少包含以下成員:

 		   tcflag_t c_iflag;      /* input modes */
           tcflag_t c_oflag;      /* output modes */
           tcflag_t c_cflag;      /* control modes */
           tcflag_t c_lflag;      /* local modes */
           cc_t     c_cc[NCCS];   /* special characters */

c_iflag flag constants:

   IGNBRK忽略輸入的BREAK條件。
   BRKINT如果設置了IGNBRK,則將忽略BREAK。如果未設置但設置了BRKINT,則BREAK會導致刷新輸入和輸出隊列,並且如果終端是控制終端,則
          最後一個前臺進程組,它將導致SIGINT發送到該前臺進程組。如果既未設置IGNBRK也未設置BRKINT,則BREAK讀取爲空字節('\ 0'),
          除了設置了PARMRK時,在這種情況下,它的讀取順序爲\ 377 \ 0 \ 0。

   IGNPAR忽略成幀錯誤和奇偶校驗錯誤。

   PARMRK如果未設置IGNPAR,請在字符前添加\ 377 \ 0奇偶校驗錯誤或成幀錯誤。如果既未設置IGNPAR也未設置PARMRK,則讀取具有奇偶校驗錯誤或成幀錯誤的字符
          爲\ 0。

   INPCK啓用輸入奇偶校驗。

   ISTRIP剝去第八位。

   INLCR在輸入上將NL轉換爲CR。

   IGNCR忽略輸入的回車。

   ICRNL在輸入中將回車轉換爲換行符(除非設置了IGNCR)​​。

   IUCLC(不在POSIX中)在輸入時將大寫字符映射爲小寫。

   IXON在輸出上啓用XON / XOFF流控制。

   IXANY(XSI)鍵入任何字符將重新啓動停止的輸出。 (默認是僅允許使用START字符來重新開始輸出。)

   IXOFF在輸入上啓用XON / XOFF流控制。

   IMAXBEL
          (不在POSIX中)當輸入隊列已滿時響鈴。 Linux不會實現此位,並且就像始終將其設置一樣。

   IUTF8(從Linux 2.6.4開始)
          (不在POSIX中)輸入爲UTF8;這樣可以在烹飪模式下正確執行字符擦除。

c_oflag flag constants defined in POSIX.1:

   OPOST 啓用實現定義的輸出處理,除非另有說明,否則其餘的c_oflag標誌常量在POSIX.1-2001中定義。

   OLCUC(不在POSIX中)在輸出時將小寫字符映射爲大寫。

   ONLCR(XSI)在輸出上將NL映射到CR-NL。

   OCRNL在輸出上將CR映射到NL。

   ONOCR在第0列不輸出CR。

   ONLRET不輸出CR。

   OFILL發送填充字符有一個延遲,而不是使用定時延遲。

   OFDEL(不在POSIX中)填充字符爲ASCII DEL(0177)。如果未設置,則填充字符爲ASCII NUL('\ 0')。 (未在Linux上實現。)

   NLDLY換行延遲掩碼。值是NL0和NL1。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]

   CRDLY回車延遲延遲蒙版。值爲CR0,CR1,CR2或CR3。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]

   TABDLY水平製表符延遲掩碼。值爲TAB0,TAB1,TAB2,TAB3(或XTABS)。 TAB3的值(即XTABS)將製表符擴展爲空格(製表符每八列停止一次)。 [要求
          _BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]

   BSDLY退格延遲掩碼。值爲BS0或BS1。 (從未實現。)[需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]

   VTDLY垂直製表符延遲掩碼。值爲VT0或VT1。

   FFDLY進紙延遲面罩。值爲FF0或FF1。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]

c_cflag flag constants:

   CBAUD(不在POSIX中)波特率掩碼(4 + 1位)。 [需要_BSD_SOURCE或_SVID_SOURCE]
   CBAUDEX
          (不在POSIX中)CBAUD中包含的額外波特率掩碼(1位)。 [需要_BSD_SOURCE或_SVID_SOURCE]

          (POSIX表示,波特率速度存儲在termios結構中,而沒有指定精確的位置,並提供cfgetispeed()和cfsetispeed()來實現。某些系統使用
          CBAUD在c_cflag中選擇的位,其他系統使用單獨的字段,例如sg_ispeed和sg_ospeed。)

   CSIZE字符大小掩碼。值爲CS5,CS6,CS7或CS8。

   CSTOPB設置兩個停止位,而不是一個。

   CREAD啓用接收器。

   PARENB啓用輸出奇偶校驗生成和輸入奇偶校驗。

   PARODD如果設置,則輸入和輸出的奇偶校驗爲奇數;否則爲0。否則,將使用奇偶校驗。

   HUPCL在最後一個過程關閉設備(掛斷)後,降低調制解調器控制線。

   CLOCAL忽略調制解調器控制線。

   LOBLK(不在POSIX中)阻止非當前Shell層的輸出。供shl(外殼層)使用。 (未在Linux上實現。)

   CIBAUD(不在POSIX中)輸入速度的掩碼。 CIBAUD位的值與CBAUD位的值相同,向左移IBSHIFT位。 [需要_BSD_SOURCE或_SVID_SOURCE]
          (未在Linux上實現。)

   CMSPAR(不在POSIX中)使用“ stick”(標記/空格)奇偶校驗(某些串行設備支持):如果設置了PARODD,則奇偶校驗位始終爲1;否則爲0。如果未設置PARODD,則奇偶校驗位始終爲
          0)。 [需要_BSD_SOURCE或_SVID_SOURCE]

   CRTSCTS
          (不在POSIX中)啓用RTS / CTS(硬件)流控制。 [需要_BSD_SOURCE或_SVID_SOURCE]

c_lflag flag constants:

   ISIG  當接收到任何字符INTR,QUIT,SUSP或DSUSP時,生成相應的信號。
   ICANON啓用規範模式(如下所述)。

   XCASE(在POSIX中不是;在Linux中不受支持)如果還設置了ICANON,則終端僅是大寫。輸入將轉換爲小寫字母,但\之前的字符除外。在輸出上
          大小寫字符以\開頭,小寫字符轉換爲大寫。 [需要_BSD_SOURCE或_SVID_SOURCE或_XOPEN_SOURCE]

   ECHO 輸入字符。

   ECHOE 如果還設置了ICANON,則ERASE字符將擦除前面的輸入字符,而WERASE將擦除前面的單詞。

   ECHOK如果還設置了ICANON,則KILL字符將刪除當前行。

   ECHONL如果還設置了ICANON,即使未設置ECHO,也應回顯NL字符。

   ECHOCTL
          (不適用於POSIX)如果還設置了ECHO,則將TAB,NL,START和STOP以外的終端特殊字符回顯爲^ X,其中X是ASCII碼比0x40大的字符。
          特殊字符。例如,字符0x08(BS)回顯爲^ H。 [需要_BSD_SOURCE或_SVID_SOURCE]

   ECHOPRT
          (不在POSIX中)如果還設置了ICANON和ECHO,則在刪除字符時將其打印出來。 [需要_BSD_SOURCE或_SVID_SOURCE]

   ECHOKE(不在POSIX中)如果還設置了ICANON,則按照ECHOE和ECHOPRT的指定,通過擦除行上的每個字符來回顯KILL。 [需要_BSD_SOURCE或_SVID_SOURCE]

   DEFECHO
          (不適用於POSIX)僅在讀取進程時回顯。 (未在Linux上實現。)

   FLUSHO(POSIX中不支持; Linux不支持)正在刷新輸出。通過輸入DISCARD字符可切換此標誌。 [需要_BSD_SOURCE或_SVID_SOURCE]

   NOFLSH在生成INT,QUIT和SUSP字符的信號時,禁用刷新輸入和輸出隊列。

   TOSTOP將SIGTTOU信號發送到嘗試寫入其控制終端的後臺進程的進程組。

   PENDIN(POSIX中不支持; Linux不支持)在讀取下一個字符時,將重新打印輸入隊列中的所有字符。 (bash(1)以這種方式處理提前輸入。)[需要_BSD_SOURCE
          或_SVID_SOURCE]
          IEXTEN啓用實現定義的輸入處理。必須對特殊字符EOL2,LNEXT,REPRINT,WERASE和要解釋的特殊字符啓用此標誌以及ICANON。
          IUCLC標誌有效。

   c_cc數組定義終端特殊字符。符號索引(初始值)和含義是:

   VDISCARD
          (不適用於POSIX; Linux不支持; 017,SI,Ctrl-O)切換:開始/停止丟棄待處理的輸出。設置IEXTEN後識別,然後不作爲輸入傳遞。

   VDSUSP(不在POSIX中;在Linux下不受支持; 031,EM,Ctrl-Y)延遲的掛起字符(DSUSP):當用戶程序讀取該字符時發送SIGTSTP信號。在IEX時被識別
          設置TEN和ISIG,並且系統支持作業控制,然後不作爲輸入傳遞。

   VEOF(004,EOT,Ctrl-D)文件結尾字符(EOF)。更準確地說:此字符使待處理的tty緩衝區被髮送到等待的用戶程序,而無需等待行尾。
          如果它是該行的第一個字符,則用戶程序中的read(2)返回0,表示文件結束。在設置ICANON時識別,然後不作爲輸入傳遞。

   VEOL(0,NUL)附加行尾字符(EOL)。設置ICANON時可識別。

   VEOL2(不在POSIX中; 0,NUL)另一個行尾字符(EOL2)。設置ICANON時可識別。

   VERASE(0177,DEL,rubout或010,BS,Ctrl-H或#)擦除字符(ERASE)。這將擦除以前尚未擦除的字符,但不會擦除過去的EOF或行首。記錄
          設置ICANON時識別,然後不作爲輸入傳遞。

   VINTR(003,ETX,Ctrl-C或0177,DEL,rubout)中斷字符(INTR)。發送SIGINT信號。設置ISIG後識別,然後不作爲輸入傳遞。

   VKILL(025,NAK,Ctrl-U或Ctrl-X或@)殺死角色(KILL)。自上次EOF或行首以來,這將擦除輸入。設置ICANON時可識別,然後不作爲
          輸入。

   VLNEXT(不在POSIX中; 026,SYN,Ctrl-V)立即數下一個(LNEXT)。引用下一個輸入字符,使它失去可能的特殊含義。設置爲IEXTEN,然後未通過時識別
          作爲輸入。

   VMIN非規範讀取的最小字符數(MIN)。

   VQUIT(034,FS,Ctrl- \)退出字符(QUIT)。發送SIGQUIT信號。設置ISIG後識別,然後不作爲輸入傳遞。
   VREPRINT
          (不在POSIX中; 022,DC2,Ctrl-R)重新打印未讀字符(REPRINT)。設置ICANON和IEXTEN,然後不作爲輸入傳遞時識別。

   VSTART(021,D​​C1,Ctrl-Q)起始字符(START)。重新啓動由Stop​​字符停止的輸出。設置IXON後識別,然後不作爲輸入傳遞。

   VSTATUS
          (不適用於POSIX; Linux不支持;狀態請求:024,DC4,Ctrl-T)。狀態字符(STATUS)。在終端上顯示狀態信息,包括前臺進程的狀態
          以及消耗的CPU時間。還將SIGINFO信號(Linux上不支持)發送到前臺進程組。

   VSTOP(023,DC3,Ctrl-S)停止字符(STOP)。停止輸出,直到鍵入開始字符。設置IXON後識別,然後不作爲輸入傳遞。

   VSUSP(032,SUB,Ctrl-Z)掛起字符(SUSP)。發送SIGTSTP信號。設置ISIG後識別,然後不作爲輸入傳遞。

   VSWTCH(不在POSIX中;在Linux下不受支持; 0,NUL)切換字符(SWTCH)。在System V中用於在Shell層中切換Shell,這是Shell作業控制的前身。

   VTIME非規範讀取(TIME)的超時(以分秒爲單位)。

   VWERASE
          (不適用於POSIX; 027,ETB,Ctrl-W)字擦除(清除)。設置ICANON和IEXTEN,然後不作爲輸入傳遞時識別。

Retrieving and changing terminal settings:

**tcgetattr()**獲取與fd引用的對象關聯的參數,並將其存儲在termios_p引用的termios結構中。 該功能可以從後臺進程中調用; 但是,終端屬性可以隨後通過前臺過程進行更改。
**tcsetattr()**從termios_p引用的termios結構中設置與終端關聯的參數(除非需要不可用的基礎硬件的支持)。 optional_actions指定更改何時生效:
TCSANOW:
更改立即發生。
TCSADRAIN:
在傳輸完所有寫入fd的輸出之後,將發生更改。 更改影響輸出的參數時,應使用此功能。
TCSAFLUSH:
更改發生在所有寫入fd引用的對象的輸出已發送之後,並且在進行更改之前,已接收但未讀取的所有輸入將被丟棄。

原始模式
cfmakeraw()將終端設置爲類似於舊版本7終端驅動程序的“原始”模式:逐字符可用輸入,禁用回顯,並且禁用終端輸入和輸出字符的所有特殊處理。 終端屬性設置如下:

 termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
                           | INLCR | IGNCR | ICRNL | IXON);
           termios_p->c_oflag &= ~OPOST;
           termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
           termios_p->c_cflag &= ~(CSIZE | PARENB);
           termios_p->c_cflag |= CS8;

 Line control
       tcsendbreak() transmits a continuous stream of zero-valued bits for a specific duration, if the terminal is using asynchronous serial data transmission.  If duration  is  zero,  it  transmits
       zero-valued bits for at least 0.25 seconds, and not more that 0.5 seconds.  If duration is not zero, it sends zero-valued bits for some implementation-defined length of time.

       If the terminal is not using asynchronous serial data transmission, tcsendbreak() returns without taking any action.

       tcdrain() waits until all output written to the object referred to by fd has been transmitted.

       tcflush() discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of queue_selector:

       TCIFLUSH
              flushes data received but not read.

       TCOFLUSH
              flushes data written but not transmitted.

       TCIOFLUSH
              flushes both data received but not read, and data written but not transmitted.

       tcflow() suspends transmission or reception of data on the object referred to by fd, depending on the value of action:

       TCOOFF suspends output.

       TCOON  restarts suspended output.

       TCIOFF transmits a STOP character, which stops the terminal device from transmitting data to the system.

       TCION  transmits a START character, which starts the terminal device transmitting data to the system.

       The default on open of a terminal file is that neither its input nor its output is suspended.

 Line speed
       The  baud  rate  functions are provided for getting and setting the values of the input and output baud rates in the termios structure.  The new values do not take effect until tcsetattr() is
       successfully called.

       Setting the speed to B0 instructs the modem to "hang up".  The actual bit rate corresponding to B38400 may be altered with setserial(8).

       The input and output baud rates are stored in the termios structure.

       cfgetospeed() returns the output baud rate stored in the termios structure pointed to by termios_p.

       cfsetospeed() sets the output baud rate stored in the termios structure pointed to by termios_p to speed, which must be one of these constants:

            B0
            B50
            B75
            B110
            B134
            B150
            B200
            B300
            B600
            B1200
            B1800
            B2400
            B4800
            B9600
            B19200
            B38400
            B57600
            B115200
            B230400

       The zero baud rate, B0, is used to terminate the connection.  If B0 is specified, the modem control lines shall no longer be asserted.  Normally, this will disconnect the line.  CBAUDEX is  a
       mask for the speeds beyond those defined in POSIX.1 (57600 and above).  Thus, B57600 & CBAUDEX is nonzero.

       cfgetispeed() returns the input baud rate stored in the termios structure.

       cfsetispeed()  sets  the input baud rate stored in the termios structure to speed, which must be specified as one of the Bnnn constants listed above for cfsetospeed().  If the input baud rate
       is set to zero, the input baud rate will be equal to the output baud rate.

       cfsetspeed() is a 4.4BSD extension.  It takes the same arguments as cfsetispeed(), and sets both input and output speed.

參考文獻:
Linux man手冊
Linux 內核u_serial.c

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章