linux uart驅動——相關數據結構以及API(二)

1、核心數據結構
      串口驅動有3個核心數據結構,它們都定義在<#include linux/serial_core.h>
一、uart_driver
     uart_driver包含了串口設備名、串口驅動名、主次設備號、串口控制檯(可選)等信息,還封裝了tty_driver(底層串口驅動無需關心tty_driver)。 css

   1:  struct uart_driver {
   2:      struct module    *owner;      /* 擁有該uart_driver的模塊,通常爲THIS_MODULE */
   3:      const char    *driver_name; /* 串口驅動名,串口設備文件名以驅動名爲基礎 */
   4:      const char    *dev_name;      /* 串口設備名 */
   5:      int             major;          /* 主設備號 */
   6:      int             minor;          /* 次設備號 */
   7:      int             nr;          /* 該uart_driver支持的串口個數(最大) */
   8:      struct console    *cons;    /* 其對應的console.若該uart_driver支持serial console,不然爲NULL */
   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_port
      uart_port用於描述串口端口的I/O端口或I/O內存地址、FIFO大小、端口類型、串口時鐘等信息。實際上,一個uart_port實例對應一個串口設備 html

   1:  struct uart_port {
   2:      spinlock_t        lock;            /* port lock 串口端口鎖 */
   3:      unsigned long        iobase;        /* in/out[bwl] io端口基地 */
   4:      unsigned char __iomem    *membase;/* read/write[bwl] IO內存基地址,經映射(如ioremap)後的IO內存虛擬基地址 */
   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:  };

     uart_iconut爲串口信息計數器,包含了發送字符計數、接收字符計數等。在串口的發送中斷處理函數和接收中斷處理函數中,咱們須要管理這些計數。linux

   1:  struct uart_icount {
   2:      __u32    cts;
   3:      __u32    dsr;
   4:      __u32    rng;
   5:      __u32    dcd;
   6:      __u32    rx;      /* 發送字符計數 */
   7:      __u32    tx;      /* 接受字符計數 */
   8:      __u32    frame;   /* 幀錯誤計數 */
   9:      __u32    overrun; /* Rx FIFO溢出計數 */
  10:      __u32    parity;  /* 幀校驗錯誤計數 */
  11:      __u32    brk;     /* break計數 */
  12:      __u32    buf_overrun;
  13:  };

      uart_stat有兩個成員在底層串口驅動會用到:xmit和port。用戶空間程序經過串口發送數據時,上層驅動將用戶數據保存在xmit;而串口發送中斷處理函數就是經過xmit獲取到用戶數據並將它們發送出去。串口接收中斷處理函數須要經過port將接收到的數據傳遞給行規則層。ios

   1:  /*
   2:   * This is the state information which is persistent across opens.
   3:   */
   4:  struct uart_state {
   5:      struct tty_port        port;
   6:   
   7:      int            pm_state;
   8:      struct circ_buf        xmit;
   9:   
  10:      struct tasklet_struct    tlet;
  11:      struct uart_port    *uart_port;
  12:  };
 

三、uart_ops 緩存

uart_ops涵蓋了串口驅動可對串口設備進行的全部操做 數據結構

   1:  /*
   2:   * This structure describes all the operations that can be
   3:   * done on the physical hardware.
   4:   */
   5:  struct uart_ops {
   6:      unsigned int    (*tx_empty)(struct uart_port *);/* 串口的Tx FIFO緩存是否爲空 */
   7:      void        (*set_mctrl)(struct uart_port *, unsigned int mctrl);/* 設置串口modem控制 */
   8:      unsigned int    (*get_mctrl)(struct uart_port *); /* 獲取串口modem控制 */
   9:      void        (*stop_tx)(struct uart_port *);/* 禁止串口發送數據 */
  10:      void        (*start_tx)(struct uart_port *);/* 使能串口發送數據 */
  11:      void        (*send_xchar)(struct uart_port *, char ch);/* 發送xChar */
  12:      void        (*stop_rx)(struct uart_port *);/* 禁止串口接收數據 */
  13:      void        (*enable_ms)(struct uart_port *);/* 使能modem的狀態信號 */
  14:      void        (*break_ctl)(struct uart_port *, int ctl); /* 設置break信號 */
  15:      int        (*startup)(struct uart_port *);/* 啓動串口,應用程序打開串口設備文件時,該函數會被調用 */
  16:      void        (*shutdown)(struct uart_port *);/* 關閉串口,應用程序關閉串口設備文件時,該函數會被調用 */
  17:      void        (*flush_buffer)(struct uart_port *);
  18:      void        (*set_termios)(struct uart_port *, struct ktermios *new,
  19:                         struct ktermios *old);/* 設置串口參數 */
  20:      void        (*set_ldisc)(struct uart_port *, int new);
  21:      void        (*pm)(struct uart_port *, unsigned int state,
  22:                    unsigned int oldstate);/* 串口電源管理 */
  23:      int        (*set_wake)(struct uart_port *, unsigned int state);
  24:      void        (*wake_peer)(struct uart_port *);
  25:   
  26:      /*
  27:       * Return a string describing the type of the port
  28:       */
  29:      const char *(*type)(struct uart_port *);/* 返回一描述串口類型的字符串 */
  30:   
  31:      /*
  32:       * Release IO and memory resources used by the port.
  33:       * This includes iounmap if necessary.
  34:       */
  35:      void        (*release_port)(struct uart_port *);/* 釋放串口已申請的IO端口/IO內存資源,必要時還需iounmap */
  36:   
  37:      /*
  38:       * Request IO and memory resources used by the port.
  39:       * This includes iomapping the port if necessary.
  40:       */
  41:      int        (*request_port)(struct uart_port *); /* 申請必要的IO端口/IO內存資源,必要時還能夠從新映射串口端口 */
  42:      void        (*config_port)(struct uart_port *, int);/* 執行串口所需的自動配置 */
  43:      int        (*verify_port)(struct uart_port *, struct serial_struct *);/* 驗證串口所需的自動配置 */
  44:      int        (*ioctl)(struct uart_port *, unsigned int, unsigned long);
  45:  #ifdef CONFIG_CONSOLE_POLL
  46:      void    (*poll_put_char)(struct uart_port *, unsigned char);
  47:      int        (*poll_get_char)(struct uart_port *);
  48:  #endif
  49:  };
 
2、串口驅動API

一、uart_register_driver app

   1:  /  * 功能:uart_register_driver用於將串口驅動uart_driver註冊到內核(串口核心層)中,一般在模塊初始化函數調用該函數。   
   2:     * 參數 drv:要註冊的uart_driver  
   3:     * 返回值:  成功,返回0;不然返回錯誤碼  
   4:  */   
   5:    int uart_register_driver(struct uart_driver *drv)   

二、uart_unregister_driver 函數

   1:  /* 功能:    uart_unregister_driver用於註銷咱們已註冊的uart_driver,一般在模塊卸載函數調用該函數
   2:   * 參數 drv:要註銷的uart_driver
   3:  
   4:   * 返回值:  成功,返回0;不然返回錯誤碼
   5:   */
   6:  void uart_unregister_driver(struct uart_driver *drv)
   7:   

三、uart_add_one_port this

   1:  /* 功能:    uart_add_one_port用於爲串口驅動添加一個串口端口,一般在探測到設備後(驅動的設備probe方法)調用該函數
   2:   * 參數 drv:串口驅動
   3:   *      port:要添加的串口端口
   4:  
   5:   * 返回值:  成功,返回0;不然返回錯誤碼
   6:   */
   7:  int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)

四、uart_remove_one_port spa

   1:  /* 功能:     uart_remove_one_port用於刪除一個已添加到串口驅動中的串口端口,一般在驅動卸載時調用該函數
   2:   * 參數 drv: 串口驅動
   3:   *      port: 要刪除的串口端口
   4:   * 返回值:   成功,返回0;不然返回錯誤碼
   5:   */
   6:  int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)

五、uart_write_wakeup

   1:  /* 功能:     uart_write_wakeup喚醒上層因向串口端口寫數據而阻塞的進程,一般在串口發送中斷處理函數中調用該函數
   2:   * 參數 port:須要喚醒寫阻塞進程的串口端口
   3:   */
   4:  void uart_write_wakeup(struct uart_port *port)

六、uart_suspend_port

   1:  /* 功能:     uart_suspend_port用於掛起特定的串口端口
   2:   * 參數 drv: 要掛起的串口端口所屬的串口驅動
   3:   *      port:要掛起的串口端口
   4:   * 返回值:   成功返回0;不然返回錯誤碼
   5:   */
   6:  int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)

七、uart_resume_port

   1:  /* 功能:     uart_resume_port用於恢復某一已掛起的串口
   2:   * 參數 drv: 要恢復的串口端口所屬的串口驅動
   3:   *      port:要恢復的串口端口
   4:   * 返回值:   成功返回0;不然返回錯誤碼
   5:   */
   6:  int uart_resume_port(struct uart_driver *drv, struct uart_port *port)

八、uart_get_baud_rate

   1:  /* 功能:        uart_get_baud_rate經過解碼termios結構體來獲取指定串口的波特率
   2:   * 參數 port:  要獲取波特率的串口端口
   3:   *     termios:當前指望的termios配置(包含串口波特率)
   4:   *     old:    之前的termios配置,能夠爲NULL
   5:   *     min:    可接受的最小波特率
   6:   *     max:    可接受的最大波特率
   7:   * 返回值:     串口的波特率
   8:   */
   9:  unsigned int
  10:  uart_get_baud_rate(struct uart_port *port, struct ktermios *termios,
  11:  struct ktermios *old, unsigned int min, unsigned int max)

九、uart_get_divisor

   1:  /* 功能:     uart_get_divisor用於計算某一波特率的串口時鐘分頻數(串口波特率除數)
   2:   * 參數 port:要計算時鐘分頻數的串口端口
   3:   *      baud:指望的波特率
   4:   *返回值:    串口時鐘分頻數
   5:   */
   6:  unsigned int uart_get_divisor(struct uart_port *port, unsigned int baud)

十、uart_update_timeout

   1:  /* 功能:      uart_update_timeout用於更新(設置)串口FIFO超時時間
   2:   * 參數 port: 要更新超時時間的串口端口
   3:   *     cflag:termios結構體的cflag值
   4:   *     baud: 串口的波特率
   5:   */
   6:  void uart_update_timeout(struct uart_port *port, unsigned int cflag, unsigned int baud)

十一、uart_match_port

   1:  /* 功能:uart_match_port用於判斷兩串口端口是否爲同一端口
   2:   * 參數 port一、port2:要判斷的串口端口
   3:   * 返回值:不一樣返回0;不然返回非0
   4:   */
   5:  int uart_match_port(struct uart_port *port1, struct uart_port *port2)

十二、uart_console_write

   1:  /* 功能:        uart_console_write用於向串口端口寫一控制檯信息
   2:  
   3:   * 參數 port:    要寫信息的串口端口
   4:   *     s:       要寫的信息
   5:   *     count:   信息的大小
   6:   *     putchar: 用於向串口端口寫字符的函數,該函數函數有兩個參數:串口端口和要寫的字符
   7:   */
   8:  void uart_console_write(struct uart_port *port, const char *s,
   9:  unsigned int count,
  10:  void (*putchar)(struct uart_port *, int))
  11:   
相關文章
相關標籤/搜索