Linux Serial driver Analysis--turn on the device

Source: Internet
Author: User
Tags function prototype

  The serial port driver is implemented by the Tty_driver architecture. A function in an application is to manipulate the hardware, first passing through a TTY, and then reaching the driver after a level call. This article first describes the entire process of opening the device's open function in the application.

First in the serial port initialization will first register a serial port driver, the function prototype is

int uart_register_driver (struct uart_driver *drv)

  The function that registers the TTY driver is called in this function

int tty_register_driver (struct tty_driver *driver)
{
...
    Cdev_init (&driver->cdev, &tty_fops);
...
}

From this code can be seen that the serial port is essentially a character device. Using Soucesight to backtrack the parameter tty_fops, you can find out the function call relationship table of the application and the TTY schema file_operations

 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,};  

You can see that the open function in the application is actually the Tty_open function in the TTY schema, and view the function

Static int tty_open (structstruct file *filp)
{
struct Tty_struct *tty = NULL;
int Noctty, retval;
struct Tty_driver *driver;
int index;
dev_t device = inode->i_rdev;
unsigned saved_flags = filp->f_flags;
...
if (Tty->ops->open)
...
}

This call to the open function in Tty->ops, which is the struct tty_operations type, is actually the UART_OPS structure

Static Const struct tty_operations uart_ops = {    . Open        = uart_open,    ...};

We can see that the Uart_open function is called again.

Static int uart_open (structstruct file *filp)
{
...
retval = Uart_startup (TTY, State, 0);
...
}

 static  int  Uart_startup (struct  tty_struct *tty, struct  uart_state *state, int   INIT_HW) { struct  Uart_port *    Uport = State->uart_port;  struct  tty_port *port = &state-> long   page;  int  retval = 0  ;  ... retval  = Uport->ops->startup (Uport); ...}

After the layer call to here, called to the uport structure of the function, Uport for the struct uart_port type, each uart_port corresponding to a serial device, that is, this has been called to the underlying driver of the startup function. Initialize the Uart_port with an array when the serial port is initialized

Static structS3c24xx_uart_port S3c24xx_serial_ports[config_serial_samsung_uarts] = {    [0] ={. Port= {            .Lock= __spin_lock_unlocked (s3c24xx_serial_ports[0].port.Lock),. Iotype=Upio_mem,. IRQ=irq_s3cuart_rx0,. UARTCLK=0,. Fifosize= -, . OPS = & s3c24xx_serial_ops, . Flags=upf_boot_autoconf,. Line=0,        }    },    ...}

Function Action Set

Static structUart_ops S3c24xx_serial_ops ={. PM=s3c24xx_serial_pm,. Tx_empty=s3c24xx_serial_tx_empty,. Get_mctrl=S3c24xx_serial_get_mctrl,. Set_mctrl=S3c24xx_serial_set_mctrl,. Stop_tx=S3c24xx_serial_stop_tx,. Start_tx=S3c24xx_serial_start_tx,. Stop_rx=S3c24xx_serial_stop_rx,. Enable_ms=S3c24xx_serial_enable_ms,. Break_ctl=S3c24xx_serial_break_ctl, . Startup = S3c24xx_serial_startup, . Shutdown=S3c24xx_serial_shutdown,. Set_termios=S3c24xx_serial_set_termios,. Type=S3c24xx_serial_type,. Release_port=s3c24xx_serial_release_port,. Request_port=s3c24xx_serial_request_port,. Config_port=s3c24xx_serial_config_port,. Verify_port=S3c24xx_serial_verify_port,};

So, retval = Uport->ops->startup (uport); Here we finally call the S3c24xx_serial_startup function, the truth has basically surfaced. The open function in the application is called through the TTY schema, and finally to the S3c24xx_serial_startup function in the samsung.c driver file.

Static intS3c24xx_serial_startup (structUart_port *Port) {    structS3c24xx_uart_port *ourport =To_ourport (port); intret; DBG ("s3c24xx_serial_startup:port=%p (%08lx,%p) \ n", Port->mapbase, port->membase); rx_enabled (port) = 1; ret     = Request_irq (OURPORT->RX_IRQ, S3c24xx_serial_rx_chars, 0, S3c24xx_serial_portname (port), ourport); if(Ret! =0) {PRINTK (Kern_err"cannot get IRQ%d\n", ourport->RX_IRQ); returnret; } ourport->rx_claimed =1; DBG ("requesting TX irq...\n"); tx_enabled (port) = 1; ret     = Request_irq (OURPORT->TX_IRQ, S3c24xx_serial_tx_chars, 0, S3c24xx_serial_portname (port), ourport); if(ret) {PRINTK (Kern_err"cannot get IRQ%d\n", ourport->TX_IRQ); Gotoerr; } ourport->tx_claimed =1; DBG ("S3c24xx_serial_startup ok\n"); /*The port reset code should has the do the correct * register setup for the port controls*/    returnret; Err:s3c24xx_serial_shutdown (port); returnRet

This function mainly does four things, the code has been highlighted:

1. Open the Receive Enable

2, registration data receive interrupt

3. Turn on Send to enable

4, registration data transmission interruption

At this point, the Linux serial driver to open the device implementation has been analyzed. If you have questions or suggestions, please note.

Linux Serial driver Analysis--turn on the device

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.