Linux uart 驱动

一、串口驱动框架简介

Linux 提供了串口驱动框架。串口驱动没有主机端和设备端之分,就只有一个串口驱动,而且这个驱动也是由处理器厂家编写好了。

我们真正要做的就是在设备树中添加所要使用的串口节点信息,当系统启动以后串口驱动和设备匹配成功,相应的串口就会被驱动起来,生成 /dev/ttymxcX ( X = 0….n) 文件。

二、uart_driver

Linux 内核使用 uart_driver 结构体表示UART 驱动, uart_driver 定义在 include/linux/serial_core.h 文件中。

struct uart_driver
{
    struct module       *owner;
    const char      *driver_name;
    const char      *dev_name;
    int          major;
    int          minor;
    int          nr;
    struct console      *cons;

    struct uart_state   *state;
    struct tty_driver   *tty_driver;
};

每个串口驱动都需要定义一个 uart_driver。

注册驱动

加载驱动的时候通过 uart_register_driver 函数向系统注册这个uart_driver

int uart_register_driver(struct uart_driver* drv);

注销驱动

注销驱动的时候需要注销掉前面注册的uart_driver , 注销函数原型如下:

void uart_unregister_driver( struct uart_driver* drv);

三、uart_port

uart_port 表示一个具体的port,uart_port 定义在 include/linux/serial_core.h 文件。

struct uart_port
{
    spinlock_t      lock;           /* port lock */
    unsigned long       iobase;         /* in/out[bwl] */
    unsigned char __iomem   *membase;       /* read/write[bwl] */
    unsigned int        ( *serial_in )( struct uart_port *, int );
    void            ( *serial_out )( struct uart_port *, int, int );
    ....
    const struct uart_ops   *ops;
    ....
}

uart_port 中最主要的就是ops,ops 包含了串口的具体驱动函数。

3.1 uart_add_one_port

每个uart 都有一个uart_port , 那么uart_port 是怎么和uart_driver 结合起来的呢?这里要用到uart_add_one_port 函数,原型如下:

int uart_add_one_port(struct uart_driver* drv, struct uart_port* uport)
  • drv : 此port 对应的uart_driver
  • uport : 要添加到 uart_driver 中的port
  • 返回值:0 ,成功;负值,失败。

3.2 uart_remove_one_port

卸载uart 驱动的时候也需要将uart_port 从相应的uart_driver 中移除,需要用到uart_remove_one_port 函数,函数原型如下:

int uart_remove_one_port ( struct uart_driver* drv,struct uart_port* uport);

3.3 uart_ops 实现

uart_port 中的ops 成员变量包含了针对UART 具体的驱动函数,Linux 系统收发最终调用的都是ops 中的函数。 uart_ops 定义在 include/linux/serial_core.h 文件中。

struct uart_ops
{
    unsigned int    ( *tx_empty )( struct uart_port * );
    void        ( *set_mctrl )( struct uart_port *, unsigned int mctrl );
    unsigned int    ( *get_mctrl )( struct uart_port * );
    void        ( *stop_tx )( struct uart_port * );
    void        ( *start_tx )( struct uart_port * );
    void        ( *throttle )( struct uart_port * );
    void        ( *unthrottle )( struct uart_port * );
    void        ( *send_xchar )( struct uart_port *, char ch );
    void        ( *stop_rx )( struct uart_port * );
    void        ( *enable_ms )( struct uart_port * );
    void        ( *break_ctl )( struct uart_port *, int ctl );
    int     ( *startup )( struct uart_port * );
    void        ( *shutdown )( struct uart_port * );
    void        ( *flush_buffer )( struct uart_port * );
    void        ( *set_termios )( struct uart_port *, struct ktermios *new,
                                  struct ktermios *old );
    void        ( *set_ldisc )( struct uart_port *, struct ktermios * );
    void        ( *pm )( struct uart_port *, unsigned int state,
                         unsigned int oldstate );

    /*
     * Return a string describing the type of the port
     */
    const char  *( *type )( struct uart_port * );

    /*
     * Release IO and memory resources used by the port.
     * This includes iounmap if necessary.
     */
    void        ( *release_port )( struct uart_port * );

    /*
     * Request IO and memory resources used by the port.
     * This includes iomapping the port if necessary.
     */
    int     ( *request_port )( struct uart_port * );
    void        ( *config_port )( struct uart_port *, int );
    int     ( *verify_port )( struct uart_port *, struct serial_struct * );
    int     ( *ioctl )( struct uart_port *, unsigned int, unsigned long );
#ifdef CONFIG_CONSOLE_POLL
    int     ( *poll_init )( struct uart_port * );
    void        ( *poll_put_char )( struct uart_port *, unsigned char );
    int     ( *poll_get_char )( struct uart_port * );
#endif
};

UART 驱动编写人员需要实现uart_ops ,因为uart_ops 是最底层的UART 驱动接口,是实实在在的和UART 寄存器打交道的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gdut_llkkyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值