tty关键结构体清单及其分层简述

一: 用户层:

1
 //字符设备操作集
   /kernel/include/linux/fs.h
   static const struct file_operations tty_fops = {
        .llseek     = no_llseek,
        .read       = tty_read,
        .write      = tty_write,
        .poll       = tty_poll,
        .unlocked_ioctl = tty_ioctl,
        .compat_ioctl   = tty_compat_ioctl,
        .open       = tty_open,
        .release    = tty_release,
        .fasync     = tty_fasync,
    };
    调用位置在  /kernel/driver/tty/Tty_io.c
    static const struct file_operations tty_fops{ ... }

二 : tty_core层:

2.1
 //tty驱动结构体
    /kernel/include/linux/tty_driver.h
    struct tty_driver {
    int magic;      /* magic number for this structure */
    struct kref kref;   /* Reference management */
    struct cdev **cdevs;
    struct module   *owner;
    const char  *driver_name;
    const char  *name;
    int name_base;  /* offset of printed name */
    int major;      /* major device number */
    int minor_start;    /* start of minor device number */
    unsigned int    num;    /* number of devices allocated */
    short   type;       /* type of tty driver */
    short   subtype;    /* subtype of tty driver */
    struct ktermios init_termios; /* Initial termios */
    unsigned long   flags;      /* tty driver flags */
    struct proc_dir_entry *proc_entry; /* /proc fs entry */
    struct tty_driver *other; /* only used for the PTY driver */
    struct tty_struct **ttys;
    struct tty_port **ports;
    struct ktermios **termios;
    void *driver_state;
    const struct tty_operations *ops;
    struct list_head tty_drivers;
    };
    调用位置 :/kernel/drivers/tty/serial/XXX.uart.c
    struct tty_driver{ ... } 在设备驱动层 注册设备驱动时 创建初始化
2.2
//tty设备驱动 操作函数
    /kernel/include/linux/tty_driver.h
    struct tty_operations {
    struct tty_struct * (*lookup)(struct tty_driver *driver,
            struct inode *inode, int idx);
    int  (*install)(struct tty_driver *driver, struct tty_struct *tty);
    void (*remove)(struct tty_driver *driver, struct tty_struct *tty);
    int  (*open)(struct tty_struct * tty, struct file * filp);
    void (*close)(struct tty_struct * tty, struct file * filp);
    void (*shutdown)(struct tty_struct *tty);
    void (*cleanup)(struct tty_struct *tty);
    int  (*write)(struct tty_struct * tty,
              const unsigned char *buf, int count);
    int  (*put_char)(struct tty_struct *tty, unsigned char ch);
    void (*flush_chars)(struct tty_struct *tty);
    int  (*write_room)(struct tty_struct *tty);
    int  (*chars_in_buffer)(struct tty_struct *tty);
    int  (*ioctl)(struct tty_struct *tty,
            unsigned int cmd, unsigned long arg);
    long (*compat_ioctl)(struct tty_struct *tty,
                 unsigned int cmd, unsigned long arg);
    void (*set_termios)(struct tty_struct *tty, struct ktermios * 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);
    int (*break_ctl)(struct tty_struct *tty, int state);
    void (*flush_buffer)(struct tty_struct *tty);
    void (*set_ldisc)(struct tty_struct *tty);
    void (*wait_until_sent)(struct tty_struct *tty, int timeout);
    void (*send_xchar)(struct tty_struct *tty, char ch);
    int (*tiocmget)(struct tty_struct *tty);
    int (*tiocmset)(struct tty_struct *tty,
            unsigned int set, unsigned int clear);
    int (*resize)(struct tty_struct *tty, struct winsize *ws);
    int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew);
    int (*get_icount)(struct tty_struct *tty,
                struct serial_icounter_struct *icount);
    #ifdef CONFIG_CONSOLE_POLL
    int (*poll_init)(struct tty_driver *driver, int line, char *options);
    int (*poll_get_char)(struct tty_driver *driver, int line);
    void (*poll_put_char)(struct tty_driver *driver, int line, char ch);
    #endif
    const struct file_operations *proc_fops;
    };
    调用位置 :  /kernel/drivers/tty/serial/serial_core.c
    static const struct tty_operations uart_ops { ... }

三 :线程规划层:

3.1
//给tty设备的线路规程
    /kernel/include/linux : Tty_ldisc.h
    struct tty_ldisc {
        struct tty_ldisc_ops *ops;
        struct tty_struct *tty;
    };
3.2
//用来保存当前tty端口的信息
    /kernel/include/linux/tty.h
    struct tty_struct {
    int magic;
    struct kref kref;
    struct device *dev;
    struct tty_driver *driver;
    const struct tty_operations *ops;
    int index;
    struct ld_semaphore ldisc_sem;
    struct tty_ldisc *ldisc;   //具体关联的 线程
    struct mutex atomic_write_lock;
    struct mutex legacy_mutex;
    struct mutex throttle_mutex;
    struct rw_semaphore termios_rwsem;
    struct mutex winsize_mutex;
    spinlock_t ctrl_lock;
    spinlock_t flow_lock;
    /* Termios values are protected by the termios rwsem */
    struct ktermios termios, termios_locked;
    struct termiox *termiox;    /* May be NULL for unsupported */
    char name[64];
    struct pid *pgrp;       /* Protected by ctrl lock */
    struct pid *session;
    unsigned long flags;
    int count;
    struct winsize winsize;     /* winsize_mutex */
    unsigned long stopped:1,    /* flow_lock */
              flow_stopped:1,
              unused:BITS_PER_LONG - 2;
    int hw_stopped;
    unsigned long ctrl_status:8,    /* ctrl_lock */
              packet:1,
              unused_ctrl:BITS_PER_LONG - 9;
    unsigned int receive_room;  /* Bytes free for queue */
    int flow_change;

    struct tty_struct *link;
    struct fasync_struct *fasync;
    int alt_speed;      /* For magic substitution of 38400 bps */
    wait_queue_head_t write_wait;
    wait_queue_head_t read_wait;
    struct work_struct hangup_work;
    void *disc_data;
    void *driver_data;
    struct list_head tty_files;
    #define N_TTY_BUF_SIZE 4096
    int closing;
    unsigned char *write_buf;
    int write_cnt;
    /* If the tty has a pending do_SAK, queue it here - akpm */
    struct work_struct SAK_work;
    struct tty_port *port;
    };
    调用位置 : 在上层用户 open /dev/XXX 的时候创建并初始化 
    tty_struct{ ... }
3.3
 //线程规划ops(操作函数)
    /kernel/include/linux : Tty_ldisc.h
    struct tty_ldisc_ops tty_ldisc_N_TTY = {
        .magic           = TTY_LDISC_MAGIC,
        .name            = "n_tty",
        .open            = n_tty_open,
        .close           = n_tty_close,
        .flush_buffer    = n_tty_flush_buffer,
        .chars_in_buffer = n_tty_chars_in_buffer,
        .read            = n_tty_read,
        .write           = n_tty_write,
        .ioctl           = n_tty_ioctl,
        .set_termios     = n_tty_set_termios,
        .poll            = n_tty_poll,
        .receive_buf     = n_tty_receive_buf,
        .write_wakeup    = n_tty_write_wakeup,
        .fasync      = n_tty_fasync,
        .receive_buf2    = n_tty_receive_buf2,
    };

    调用位置 : /kernel/drivers/tty/n_tty.c
    struct tty_ldisc_ops tty_ldisc_N_TTY{ ... }

四 Serial_driver设备层:

4.1
//tty设备驱动结构体 
    /kernel/include/linux/serial_core.h
    struct uart_driver {
        struct module       *owner;
        const char      *driver_name;
        const char      *dev_name;
        int          major;
        int          minor;
        int          nr;
        struct console      *cons;
        struct uart_state   *state;
        struct tty_driver   *tty_driver;
    };
    调用位置 : /kernel/drivers/tty/serial/uartxxx.c
    static struct uart_driver XXX_uart_driver
4.2
//tty设备空间
    /kernel/include/linux/serial_core.h
    struct uart_state {
        struct tty_port     port;
        enum uart_pm_state  pm_state;
        struct circ_buf     xmit;
        struct uart_port    *uart_port;
    };
4.3
//tty真实的物理串口
/kernel/include/linux/serial_core.h
struct uart_port {  
        spinlock_t      lock;           /* port lock */  
        unsigned long       iobase;         /* io端口基地址(物理) */  
        unsigned char __iomem   *membase;       /* io内存基地址(虚拟) */  
        unsigned int        (*serial_in)(struct uart_port *, int);  
        void            (*serial_out)(struct uart_port *, int, int);  
        unsigned int        irq;            /* 中断号 */  
        unsigned long       irqflags;       /* 中断标志  */  
        unsigned int        uartclk;        /* 串口时钟 */  
        unsigned int        fifosize;       /* 串口缓冲区大小 */  
        unsigned char       x_char;         /* xon/xoff char */  
        unsigned char       regshift;       /* 寄存器位移 */  
        unsigned char       iotype;         /* IO访问方式 */  
        unsigned char       unused1;  

        unsigned int        read_status_mask;   /* 关心 Rx error status */  
        unsigned int        ignore_status_mask; /* 忽略 Rx error status */  
        struct uart_state   *state;         /* pointer to parent state */  
        struct uart_icount  icount;         /* 串口信息计数器 */  

        struct console      *cons;          /* struct console, if any */  
    #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)  
        unsigned long       sysrq;          /* sysrq timeout */  
    #endif  
        upf_t           flags;  
        unsigned int        mctrl;          /* 当前的Moden 设置 */  
        unsigned int        timeout;        /* character-based timeout */  
        unsigned int        type;           /* 端口类型 */  
        const struct uart_ops   *ops;       /* 串口端口操作函数 */  
        unsigned int        custom_divisor;  
        unsigned int        line;           /* 端口索引 */  
        resource_size_t     mapbase;        /* io内存物理基地址 */  
        struct device       *dev;           /* 父设备 */  
        unsigned char       hub6;             
        unsigned char       suspended;  
        unsigned char       unused[2];  
        void            *private_data;      /* generic platform data pointer */  
    };  
调用位置 : /kernel/drivers/tty/serial/uartxxx.c
static struct XXX_port { struct uart_port port ... }    
4.4
//tty真实串口的操作集合
    /kernel/include/linux/serial_core.h
    struct uart_ops {   
            unsigned int (*tx_empty)(struct uart_port *);/* 串口的Tx FIFO缓存是否为空 */  
            void      (*set_mctrl)(struct uart_port *, unsigned int mctrl);   /* 设置串口modem控制 */  
            unsigned int    (*get_mctrl)(struct uart_port *);   /* 获取串口modem控制 */  
            void     (*stop_tx)(struct uart_port *);     /* 禁止串口发送数据 */  
            void     (*start_tx)(struct uart_port *);    /* 使能串口发送数据 */    
            void     (*send_xchar)(struct uart_port *, char ch); /* 发送xChar */  
            void     (*stop_rx)(struct uart_port *);    /* 禁止串口接收数据 */  
            void     (*enable_ms)(struct uart_port *);  /* 使能modem的状态信号 */  
            void     (*break_ctl)(struct uart_port *, int ctl);  /* 设置break信号 */  
            int   (*startup)(struct uart_port *); /* 启动串口,应用程序打开串口设备文件时,该函数会被调用 */  
            void  (*shutdown)(struct uart_port *);/* 关闭串口,应用程序关闭串口设备文件时,该函数会被调用 */  
            void   (*flush_buffer)(struct uart_port *);  
            void   (*set_termios)(struct uart_port *, struct ktermios *new,  
                               struct ktermios *old);   /* 设置串口参数 */  
            void   (*set_ldisc)(struct uart_port *);/* 设置线路规程 */  
            void   (*pm)(struct uart_port *, unsigned int state,  
                          unsigned int oldstate);   /* 串口电源管理 */  
            int    (*set_wake)(struct uart_port *, unsigned int state);  
            const char *(*type)(struct uart_port *);  
            void   (*release_port)(struct uart_port *);   
            int  (*request_port)(struct uart_port *); /* 申请必要的IO端口/IO内存资源,必要时还可以重新映射串口端口 */  
            void        (*config_port)(struct uart_port *, int); /* 执行串口所需的自动配置 */  
            int     (*verify_port)(struct uart_port *, struct serial_struct *); /* 核实新串口的信息 */  
            int     (*ioctl)(struct uart_port *, unsigned int, unsigned long);  
        #ifdef CONFIG_CONSOLE_POLL  
            void    (*poll_put_char)(struct uart_port *, unsigned char);  
            int     (*poll_get_char)(struct uart_port *);  
        #endif  
        };  
    调用位置 : /kernel/drivers/tty/serial/uartxxx.c
    static struct uart_ops wk2xxx_pops  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值