zoukankan      html  css  js  c++  java
  • 串口驱动

    一、串口驱动中的数据结构

      尽管一个特定的UART设备驱动完全可以按照tty驱动的设计方法来设计,即定义tty_driver并实现tty_operations其中 的成员函数,但是Linux已经在文件serial_core.c中实现了UART设备的通用tty驱动层,称为串口核心层,这样,UART驱动的主要任 务变成了实现serial_core.c中定义的一组uart_xxx接口而非tty_xxx接口。

    1.1下图描述了串行系统间的层次结构关系,可以概括为:

      用户应用层 --> 线路规划层 --> TTY层 --> 底层驱动层 --> 物理硬件层

      

    1.2下图是串口核心层在整个tty源文件关系及数据流向中的位置:

      

    其中的xxx_uart.c在此处就是drivers/tty/serial/samsung.c和s3c6400.c

    二、串口驱动中的数据结构

      

    1.4使用到的数据结构

    Uart驱动程序主要围绕三个关键的数据结构展开(include/linux/serial_core.h中定义):

    1. UART驱动程序结构:struct uart_driver
    2. UART端口结构: struct uart_port
    3. UART相关操作函数结构: struct uart_ops

    1.4.1其中一个串口驱动对应一个struct uart_driver当然一个驱动是可以对应多个设备的:

    复制代码
     1 struct uart_driver {
     2     struct module        *owner;
     3     const char        *driver_name;
     4     const char        *dev_name;
     5     int             major;
     6     int             minor;
     7     int             nr;    //端口个数
     8     struct console        *cons;
     9 
    10     /*
    11      * these are private; the low level driver should not
    12      * touch these; they should be initialised to NULL
    13      */
    14     struct uart_state    *state;
    15     struct tty_driver    *tty_driver;
    16 };
    复制代码

    其中的uart_state是设备状态结构结构体:

    复制代码
    1 struct uart_state {
    2     struct tty_port        port;
    3     int            pm_state;
    4     struct circ_buf        xmit;
    5     struct tasklet_struct    tlet;
    6     struct uart_port    *uart_port;
    7 };
    复制代码

       在uart_open()中:

       tty->driver_data = state;

       在其他uart_xxx()中:

       struct uart_state *state = tty->driver_data;

       就可以获取设备私有信息结构体。

    1.4.2uart_port用于描述一个UART端口(直接对应于一个串口)的I/O端口或者IO内存地址等信息--->即一个uart_port对应一个端口

    复制代码
     1 struct uart_port {
     2     spinlock_t        lock;            /* port lock */
     3     unsigned long        iobase;            /* in/out[bwl] */
     4     unsigned char __iomem    *membase;        /* read/write[bwl] */
     5     unsigned int        (*serial_in)(struct uart_port *, int);
     6     void            (*serial_out)(struct uart_port *, int, int);
     7     void            (*set_termios)(struct uart_port *,
     8                                struct ktermios *new,
     9                                struct ktermios *old);
    10     void            (*pm)(struct uart_port *, unsigned int state,
    11                       unsigned int old);
    12     unsigned int        irq;            /* irq number */
    13     unsigned long        irqflags;        /* irq flags  */
    14     unsigned int        uartclk;        /* base uart clock */
    15     unsigned int        fifosize;        /* tx fifo size */
    16     unsigned char        x_char;            /* xon/xoff char */
    17     unsigned char        regshift;        /* reg offset shift */
    18     unsigned char        iotype;            /* io access style */
    19     unsigned char        unused1;
    20 
    21 #define UPIO_PORT        (0)
    22 #define UPIO_HUB6        (1)
    23 #define UPIO_MEM        (2)
    24 #define UPIO_MEM32        (3)
    25 #define UPIO_AU            (4)            /* Au1x00 type IO */
    26 #define UPIO_TSI        (5)            /* Tsi108/109 type IO */
    27 #define UPIO_DWAPB        (6)            /* DesignWare APB UART */
    28 #define UPIO_RM9000        (7)            /* RM9000 type IO */
    29 #define UPIO_DWAPB32        (8)            /* DesignWare APB UART (32 bit accesses) */
    30 
    31     unsigned int        read_status_mask;    /* driver specific */
    32     unsigned int        ignore_status_mask;    /* driver specific */
    33     struct uart_state    *state;            /* pointer to parent state */
    34     struct uart_icount    icount;            /* statistics */
    35 
    36     struct console        *cons;            /* struct console, if any */
    37 #if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(SUPPORT_SYSRQ)
    38     unsigned long        sysrq;            /* sysrq timeout */
    39 #endif
    40 
    41     upf_t            flags;
    42 
    43 #define UPF_FOURPORT        ((__force upf_t) (1 << 1))
    44 #define UPF_SAK            ((__force upf_t) (1 << 2))
    45 #define UPF_SPD_MASK        ((__force upf_t) (0x1030))
    46 #define UPF_SPD_HI        ((__force upf_t) (0x0010))
    47 #define UPF_SPD_VHI        ((__force upf_t) (0x0020))
    48 #define UPF_SPD_CUST        ((__force upf_t) (0x0030))
    49 #define UPF_SPD_SHI        ((__force upf_t) (0x1000))
    50 #define UPF_SPD_WARP        ((__force upf_t) (0x1010))
    51 #define UPF_SKIP_TEST        ((__force upf_t) (1 << 6))
    52 #define UPF_AUTO_IRQ        ((__force upf_t) (1 << 7))
    53 #define UPF_HARDPPS_CD        ((__force upf_t) (1 << 11))
    54 #define UPF_LOW_LATENCY        ((__force upf_t) (1 << 13))
    55 #define UPF_BUGGY_UART        ((__force upf_t) (1 << 14))
    56 #define UPF_NO_TXEN_TEST    ((__force upf_t) (1 << 15))
    57 #define UPF_MAGIC_MULTIPLIER    ((__force upf_t) (1 << 16))
    58 #define UPF_CONS_FLOW        ((__force upf_t) (1 << 23))
    59 #define UPF_SHARE_IRQ        ((__force upf_t) (1 << 24))
    60 /* The exact UART type is known and should not be probed.  */
    61 #define UPF_FIXED_TYPE        ((__force upf_t) (1 << 27))
    62 #define UPF_BOOT_AUTOCONF    ((__force upf_t) (1 << 28))
    63 #define UPF_FIXED_PORT        ((__force upf_t) (1 << 29))
    64 #define UPF_DEAD        ((__force upf_t) (1 << 30))
    65 #define UPF_IOREMAP        ((__force upf_t) (1 << 31))
    66 
    67 #define UPF_CHANGE_MASK        ((__force upf_t) (0x17fff))
    68 #define UPF_USR_MASK        ((__force upf_t) (UPF_SPD_MASK|UPF_LOW_LATENCY))
    69 
    70     unsigned int        mctrl;            /* current modem ctrl settings */
    71     unsigned int        timeout;        /* character-based timeout */
    72     unsigned int        type;            /* port type */
    73     const struct uart_ops    *ops;
    74     unsigned int        custom_divisor;
    75     unsigned int        line;            /* port index */
    76     resource_size_t        mapbase;        /* for ioremap */
    77     struct device        *dev;            /* parent device */
    78     unsigned char        hub6;            /* this should be in the 8250 driver */
    79     unsigned char        suspended;
    80     unsigned char        irq_wake;
    81     unsigned char        unused[2];
    82     void            *private_data;        /* generic platform data pointer */
    83 };
    复制代码

    1.4.3uart_ops定义了针对UART的一系列操作

    复制代码
     1 struct uart_ops {
     2     unsigned int    (*tx_empty)(struct uart_port *);
     3     void        (*set_mctrl)(struct uart_port *, unsigned int mctrl);
     4     unsigned int    (*get_mctrl)(struct uart_port *);
     5     void        (*stop_tx)(struct uart_port *);
     6     void        (*start_tx)(struct uart_port *);
     7     void        (*send_xchar)(struct uart_port *, char ch);
     8     void        (*stop_rx)(struct uart_port *);
     9     void        (*enable_ms)(struct uart_port *);
    10     void        (*break_ctl)(struct uart_port *, int ctl);
    11     int        (*startup)(struct uart_port *);
    12     void        (*shutdown)(struct uart_port *);
    13     void        (*flush_buffer)(struct uart_port *);
    14     void        (*set_termios)(struct uart_port *, struct ktermios *new,
    15                        struct ktermios *old);
    16     void        (*set_ldisc)(struct uart_port *, int new);
    17     void        (*pm)(struct uart_port *, unsigned int state,
    18                   unsigned int oldstate);
    19     int        (*set_wake)(struct uart_port *, unsigned int state);
    20 
    21     /*
    22      * Return a string describing the type of the port
    23      */
    24     const char *(*type)(struct uart_port *);
    25 
    26     /*
    27      * Release IO and memory resources used by the port.
    28      * This includes iounmap if necessary.
    29      */
    30     void        (*release_port)(struct uart_port *);
    31 
    32     /*
    33      * Request IO and memory resources used by the port.
    34      * This includes iomapping the port if necessary.
    35      */
    36     int        (*request_port)(struct uart_port *);
    37     void        (*config_port)(struct uart_port *, int);
    38     int        (*verify_port)(struct uart_port *, struct serial_struct *);
    39     int        (*ioctl)(struct uart_port *, unsigned int, unsigned long);
    40 #ifdef CONFIG_CONSOLE_POLL
    41     void    (*poll_put_char)(struct uart_port *, unsigned char);
    42     int        (*poll_get_char)(struct uart_port *);
    43 #endif
    44 };
    复制代码

    UART信息结构: struct uart_info

    二、串口初始化分析

      

    分析过程:

    2.1进入到内核的Samsung.c文件中

      找到内核模块加载函数:module_init(s3c24xx_serial_modinit);

      可以看到加载模块直接调用platform_driver_register,注册了 开发板串口这个平台驱动。

      因为把uart驱动注册为platform驱动,当平台驱动与平台设备进行匹配的时候会调用平台总线的match函数,匹配成功后就会调用平台驱动的xxx_probe()函数来进行一系列的初始化工作。

    复制代码
     1 int s3c24xx_serial_probe(struct platform_device *dev,
     2              struct s3c24xx_uart_info *info)
     3 {
     4     struct s3c24xx_uart_port *ourport;
     5     int ret;
     6 
     7     dbg("s3c24xx_serial_probe(%p, %p) %d
    ", dev, info, probe_index);
     8 
     9     ourport = &s3c24xx_serial_ports[probe_index];
    10     probe_index++;
    11 
    12     dbg("%s: initialising port %p...
    ", __func__, ourport);
    13 
    14     ret = s3c24xx_serial_init_port(ourport, info, dev);
    15     if (ret < 0)
    16         goto probe_err;
    17 
    18     dbg("%s: adding port
    ", __func__);
    19     uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
    20     platform_set_drvdata(dev, &ourport->port);
    21 
    22     ret = device_create_file(&dev->dev, &dev_attr_clock_source);
    23     if (ret < 0)
    24         printk(KERN_ERR "%s: failed to add clksrc attr.
    ", __func__);
    25 
    26     ret = s3c24xx_serial_cpufreq_register(ourport);
    27     if (ret < 0)
    28         dev_err(&dev->dev, "failed to add cpufreq notifier
    ");
    29 
    30     return 0;
    31 
    32  probe_err:
    33     return ret;
    34 }
    复制代码
  • 相关阅读:
    树状数组简述
    八皇后
    小木棍
    智力大冲浪
    晚餐队列安排
    修理牛棚
    转圈游戏
    关押罪犯
    借教室
    跳石头
  • 原文地址:https://www.cnblogs.com/zxouxuewei/p/5380654.html
Copyright © 2011-2022 走看看