USB转串口驱动分析(二)

在static int __init usb_serial_init(void)里

tty_set_operations(usb_serial_tty_driver, &serial_ops); //赋值tty设备的操作集合,操作函数在serial_ops中定义将serial_ops与驱动绑定,应用层调用系统调用就会调用到这个操作集合里面的函数,下面来看一下serial_ops这个结构体:

static const struct tty_operations serial_ops = {

    .open =         serial_open,

    .close =        serial_close,

    .write =        serial_write,

    .hangup =       serial_hangup,

    .write_room =       serial_write_room,

    .ioctl =        serial_ioctl,

    .set_termios =      serial_set_termios,

    .throttle =     serial_throttle,

    .unthrottle =       serial_unthrottle,

    .break_ctl =        serial_break,

    .chars_in_buffer =  serial_chars_in_buffer,

    .tiocmget =     serial_tiocmget,

    .tiocmset =     serial_tiocmset,

    .get_icount =       serial_get_icount,

    .cleanup =      serial_cleanup,

    .install =      serial_install,

    .proc_fops =        &serial_proc_fops,

};

主要看serial_open和 serial_write在这可能会问为什么没有serial_read函数,下面慢慢分析就会明白。

先来看看serial_open,应用层open会调用到这

static int serial_open(struct tty_struct *tty, struct file *filp)

{

    struct usb_serial_port *port = tty->driver_data;

 

    dbg("%s - port %d", __func__, port->number);

    return tty_port_open(&port->port, tty, filp);

}

最后是调用了tty_port_open这个函数,继续追踪                                                                                                                       

int tty_port_open(struct tty_port *port, struct tty_struct *tty,

                            struct file *filp)

{

    spin_lock_irq(&port->lock);

    if (!tty_hung_up_p(filp))

        ++port->count; //打开端口计数加一

    spin_unlock_irq(&port->lock);

    tty_port_tty_set(port, tty);

    

    /*

     * Do the device-specific open only if the hardware isn't

     * already initialized. Serialize open and shutdown using the

     * port mutex.

     */

    

    mutex_lock(&port->mutex);

 

    if (!test_bit(ASYNCB_INITIALIZED, &port->flags)) {

        clear_bit(TTY_IO_ERROR, &tty->flags);

        if (port->ops->activate) {

            int retval = port->ops->activate(port, tty);

            if (retval) {

                mutex_unlock(&port->mutex);

                return retval;

            }

        }

        set_bit(ASYNCB_INITIALIZED, &port->flags);

}

    mutex_unlock(&port->mutex);

    return tty_port_block_til_ready(port, tty, filp); //串口端口阻塞直至准备好

}

到这就追不下去了,回头看看来struct tty_port *port这个结构体

struct tty_port {

    struct tty_struct   *tty;       /* Back pointer */

    const struct tty_port_operations *ops;  /* Port operations */

    spinlock_t      lock;       /* Lock protecting tty field */

    int         blocked_open;   /* Waiting to open */

    int         count;      /* Usage count */

    wait_queue_head_t   open_wait;  /* Open waiters */

    wait_queue_head_t   close_wait; /* Close waiters */

    wait_queue_head_t   delta_msr_wait; /* Modem status change */

    unsigned long       flags;      /* TTY flags ASY_*/

    unsigned char       console:1;  /* port is a console */

    struct mutex        mut

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值