linux serial构架分析及驱动开发(5)

    技术2024-07-11  73

    uart_close主要在tty_release和do_tty_hundup中调用,做与uart_pen相反的操作,具体源码如下:

    /* * In 2.4.5, calls to this will be serialized via the BKL in *  linux/drivers/char/tty_io.c:tty_release() *  linux/drivers/char/tty_io.c:do_tty_handup() */static void uart_close(struct tty_struct *tty, struct file *filp){ struct uart_state *state = tty->driver_data; //uart_open中我们做的赋值 struct uart_port *port;

     BUG_ON(!kernel_locked());

     if (!state || !state->port)  return;

     port = state->port;

     pr_debug("uart_close(%d) called/n", port->line);

     mutex_lock(&state->mutex);

     if (tty_hung_up_p(filp))  goto done;

     if ((tty->count == 1) && (state->count != 1)) {  /*   * Uh, oh.  tty->count is 1, which means that the tty   * structure will be freed.  state->count should always   * be one in these conditions.  If it's greater than   * one, we've got real problems, since it means the   * serial port won't be shutdown.   */  printk(KERN_ERR "uart_close: bad serial port count; tty->count is 1, "         "state->count is %d/n", state->count);  state->count = 1; } if (--state->count < 0) {  printk(KERN_ERR "uart_close: bad serial port count for %s: %d/n",         tty->name, state->count);  state->count = 0; }

    //只有state->count 为0才说明此外没有对串口的操作可以关闭串口 if (state->count)  goto done;

     /*  * Now we wait for the transmit buffer to clear; and we notify  * the line discipline to only process XON/XOFF characters by  * setting tty->closing.  */ tty->closing = 1;

     

    //在关闭之前先把缓存中或者待发送的数据先发送完,这里先唤醒写等待队列,然后调用wait_until_sent发送数据

    //该函数主要将数据发射出去

     if (state->closing_wait != USF_CLOSING_WAIT_NONE)  tty_wait_until_sent(tty, msecs_to_jiffies(state->closing_wait));

     /*  * At this point, we stop accepting input.  To do this, we  * disable the receive line status interrupts.  */ if (state->info.flags & UIF_INITIALIZED) {  unsigned long flags;  spin_lock_irqsave(&port->lock, flags);  port->ops->stop_rx(port);   //停止发送数据  spin_unlock_irqrestore(&port->lock, flags);  /*   * Before we drop DTR, make sure the UART transmitter   * has completely drained; this is especially   * important if there is a transmit FIFO!   */  uart_wait_until_sent(tty, port->timeout); }

    //清除一些标志,释放串口资源

     uart_shutdown(state);

    //对发送缓存及其标志做清理 uart_flush_buffer(tty);

    //对线路规程中的数据做清理

     tty_ldisc_flush(tty);

     tty->closing = 0; state->info.port.tty = NULL;

    //若有其他进程在等待打开次串口,先等待一段时间,然后清理打开标志,并在最后唤醒等待的进程

     if (state->info.port.blocked_open) {  if (state->close_delay)   msleep_interruptible(state->close_delay); } else if (!uart_console(port)) {  uart_change_pm(state, 3); }

     /*  * Wake up anyone trying to open this port.  */ state->info.flags &= ~UIF_NORMAL_ACTIVE; wake_up_interruptible(&state->info.port.open_wait);

     done: mutex_unlock(&state->mutex);}

     

     

    最新回复(0)