標籤:io os 使用 ar for 檔案 資料 sp art
- 簡介
- tty裝置的名稱是從過去的電傳打字機縮寫而來,最初是指串連到Unix系統上的物理或虛擬終端
- Linux tty驅動程式的核心緊挨在標準字元裝置驅動層之下,並提供了一系列的功能,作為介面被終端類型裝置使用
- 有三種類型的tty驅動程式:控制台、串口和pty
- /proc/tty/drivers
- 當前註冊並存在於核心的tty裝置在/sys/class/tty下都有自己的子目錄
- 小型TTY驅動程式
- <linux/tty_driver.h>
- struct tty_driver
- tiny_tty_driver = alloc_tty_driver(TINY_TTY_MINORS);
- static struct tty_operations serial_ops = {.open=tiny_open, .close=tiny_close, .write=tiny_write, .write_room=tiny_write_room, .set_termios=tiny_set_termios,}
- tiny_tty_driver->owner=THIS_MODULE;
- tiny_tty_driver->driver_name=”tiny_tty”;
- tiny_tty_driver->name=”ttty”;
- tiny_tty_driver->devfs_name=”tty/ttty%d”;
- tiny_tty_driver->major=TINY_TTY_MAJOR;
- tiny_tty_driver->type=TTY_DRIVER_TYPE_SERIAL;
- tiny_tty_driver->subtype=SERIAL_TYPE_NORMAL;
- tiny_tty_driver->flags=TTY_DRIVER_REAL_RAW|TTY_DRIVER_NO_DEVFS;
- tiny_tty_driver->init_termios=tty_std_termios;
- tiny_tty_driver->init_termios.c_cflag=B9600|CS8|CREAD|HUPCL|CLOCAL;
- tty_set_operaions(tiny_tty_driver, &serial_ops);
- retval = tty_register_driver(tiny_tty_driver);
- for (i=0;i<TINY_TTY_MINORS; ++i) tty_unregister_device(tiny_tty_driver, i);
- tty_unregister_driver(tiny_tty_driver);
- termios結構
- 用來提供一系列安全的設定值
- struct termios
- tcflag_t c_iflag;
- tcflag_t c_oflag;
- tcflag_t c_cflag;
- tcflag_c c_lflag;
- cc_t c_line;
- tty_driver函數指標
- open和close
- 當使用者使用open開啟由驅動程式分配的裝置節點時,tty核心將調用open函數
- 當調用open函數時,tty驅動程式或者將資料儲存到傳遞給它的tty_struct變數中
- 資料流
- 當資料要發送給硬體時,使用者調用write函數
- 首先tty核心接收到了該調用,然後核心將資料發送給tty驅動程式的write函數
- tty驅動程式在中斷上下文中時,它不會調用任何可能休眠的函數
- 當tty子系統本身需要將一些資料傳送到tty裝置之外時,可以調用write函數
- 當tty核心想知道由tty驅動程式提供的可用寫入緩衝區大小時,就會調用write_room函數
- 其他緩衝函數
- flush_chars
- wait_until_sent
- flush_buffer
- 怎麼沒有read函數
- 當tty驅動程式接收到資料後,它將負責把從硬體擷取的任何資料傳遞給tty核心,而不使用傳統的read函數
- tty核心將緩衝資料直到接到來自使用者的請求
- 在一個名為tty_flip_buffer的結構中,tty核心緩衝從tty驅動程式接收的資料
- tty_insert_flip_char
- tty_flip_buffer_push
- TTY線路設定
- set_termios
- 大部分termios的使用者空間函數將會被庫轉換成對驅動程式節點的ioctl調用
- 大量的不同tty ioctl調用會被ttyp核心轉換成一個對tty驅動程式的set_termios函數調用
- tty驅動程式必須能夠對在termios結構中所有不同的設定進行解碼,並對任何需要的改變做出響應
- tiocmget和tiocmset
- 在2.4及更早的核心中,使用了大量的tty ioctl調用來獲得及設定不同的控制線路參數
- 這通過常量TIOCMGET、TIOCMBIS、TIOCMBIC和TIOCMSET來完成
- TIOCMGET用來獲得核心的線路設定值,在2.6.版本的核心中,該ioctl調用被tty驅動程式中的tiocmget回呼函數所代替
- 剩下的三個ioctl現在被簡化成tty驅動程式中的一個tiocmset回呼函數了
- int (*tiocmget) (struct tty_struct *tty, struct file *file);
- int (*tiocmset) (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
- ioctls
- 當ioctl為一個裝置節點被調用時,tty核心將調用tty_driver結構中的ioctl回呼函數
- 常用詞tty ioctl的列表
- TIOCSERGETLSR
- TIOCGSERIAL
- TIOCSSERIAL
- TIOCMIWAIT
- TIOCGICOUNT
- proc和sys對TTY裝置的處理
- tty核心為任何tty驅動程式都提供了非常簡單的辦法,用來維護在/proc/tty/driver目錄中的一個檔案
- 如果驅動程式定義了read_proc或者write_proc函數,將建立該檔案,接著任何對該檔案的讀寫將被發送給驅動程式
- tty_driver結構詳解
- tty_driver結構用來向tty核心註冊一個tty驅動程式
- struct tty_driver
- struct module *owner;
- int magic;
- const char *driver_name;
- 在/proc/tty和sysfs中使用,表示驅動程式的名字
- const char *name;
- int name_base;
- short major;
- short minor_start;
- short num;
- short type;
- TTY_DRIVER_TYPE_SYSTEM
- TTY_DRIVER_TYPE_CONSOLE
- TTY_DRIVER_TYPE_SERIAL
- TTY_DRIVER_TYPE_PTY
- short subtype;
- struct termios init_termios;
- int flags;
- struct proc_dir_entry *proc_entry;
- struct tty_driver *other;
- void *driver_state;
- struct tty_driver *next;
- struct tty_driver *prev;
- tty_operations結構詳解
- tty_operations結構中包含所有的回呼函數,它們被tty驅動程式設定,並被tty核心調用
- struct tty_operations
- int (*open) (struct tty_struct *tty, struct file *filp);
- int (*close) (struct tty_struct *tty, struct file *filp);
- int (*write) (struct tty_struct *tty, const unsigned char *buf, int count);
- void (*put_char) (struct tty_struct *tty, unsigned char ch);
- void (*flush_chars) (struct tty_struct *tty);
- void (*wait_until_sent) (struct tty_struct *tty, int timeout);
- int (*write_room) (struct tty_struct *tty);
- int (*chars_in_buffer) (struct tty_struct *tty);
- int (*ioctl) (struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
- void (*set_termios) (struct tty_struct *tty, struct termios *old);
- void (*throttle) (struct tty_struct *tty);
- void (*unthrottle) (struct tty_struct *tty);
- void (*stop) (struct tty_struct *tty);
- void (*start) (struct tty_struct *tty);
- void (*hangup) (struct tty_struct *tty);
- void (*bread_ctl) (struct tty_struct *tty, int state);
- void (*flush_buffer) (struct tty_struct *tty);
- void (*set_ldisc) (struct tty_struct *tty);
- void (*send_xchar) (struct tty_struct *tty, char ch);
- int (*read_proc) (char *page, char **start, off_t off, int count, int *eof, void *data);
- int (*write_proc) (struct file *file, const char *buffer, unsigned long count, void *data);
- int (*tiocmget) (struct tty_struct *tty, struct file *file);
- int (*tiocset) (struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear);
- tty_struct結構詳解
- tty核心使用tty_struct儲存當前特定tty連接埠的狀態
- struct tty_struct
- unsigned long flags;
- 當前tty裝置的狀態
- TTY_THROTTLED
- TTY_IO_ERROR
- TTY_OTHER_CLOSED
- TTY_EXCLUSIVE
- TTY_DEBUG
- TTY_DO_WRITE_WAKEUP
- TTY_PUSH
- TTY_CLOSING
- TTY_DONT_FLIP
- TTY_HW_COOK_OUT
- TTY_HW_COOK_IN
- TTY_PTY_LOCK
- TTY_NO_WRITE_SPLIT
- struct tty_flip_buffer flip;
- struct tty_ldisc ldisc;
- wait_queue_head_t write_wait;
- struct termios *termios;
- unsigned char stopped:1;
- unsigned char hw_stopped:1
- unsigned char low_latency:1
- unsigned char closing:1
- struct tty_driver driver;
- void *driver_data;
- tty_driver用來把資料儲存在tty驅動程式中的指標
《Linux Device Drivers》第十八章 TTY驅動程式——note