rt-thread UART 驱动注册IO设备管理器的调用关系

/************************ UART 驱动注册IO设备管理器的调用关系 ************************/
struct imxrt_uart{
    char *name;
    LPUART_Type *uart_base;
    IRQn_Type irqn;
    rt_uint16_t dma_flag;
    struct rt_serial_device serial;
};

struct rt_uart_ops
{
    rt_err_t (*configure)(struct rt_serial_device *serial, struct serial_configure *cfg);
    rt_err_t (*control)(struct rt_serial_device *serial, int cmd, void *arg);

    int (*putc)(struct rt_serial_device *serial, char c);
    int (*getc)(struct rt_serial_device *serial);

    rt_size_t (*dma_transmit)(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
};

INIT_BOARD_EXPORT(rt_hw_uart_init);     drv_uart.c
    rt_hw_uart_init     static struct imxrt_uart uarts[];   drv_uart.c
        uarts[i].serial.ops    = &imxrt_uart_ops;
        uarts[i].serial.config = config;
        rt_hw_serial_register(&uarts[i].serial, uarts[i].name, ...);    serial.c
        rt_hw_serial_register(struct rt_serial_device *serial, const char *name, ...)
            device = &(serial->parent);
            device->init        = rt_serial_init;     
            device->open        = rt_serial_open;
            device->close       = rt_serial_close;
                rt_serial_close(struct rt_device *dev)
                    serial = (struct rt_serial_device *)dev;
            device->read        = rt_serial_read;
            device->write       = rt_serial_write;
            device->control     = rt_serial_control;
            rt_device_register(device, name, ...)      device.c
            rt_device_register(rt_device_t dev, const char *name, ...)
            

rt-thread IO设备管理器 调用流程, 拿UART举例
1.用户编写 drv_uart.c 在 rt_hw_uart_init 注册串口设备; 并将 rt_hw_uart_init 作为board初始化时调用 "INIT_BOARD_EXPORT"
2. 在 drv_uart.c 文件中主要做如下事情
    a.定义 serial 设备, 在 Linux2.x以上 设备与驱动分开, 这里参考的是 Linux2.x以下版本, 设备与驱动在一起
    b."serial串口设备驱动框架"是 rt-thread 将公共部分进行抽离, 抽象出来的这一层
    c.补充 "serial串口设备驱动框架", 针对具体的设备做具体实现, 而实现方式就是对 rt_serial_device.ops 成员赋值
    d.补充 "serial串口设备驱动框架", 针对初始化时具体配置, 做具体调整, 实现方式是对 rt_serial_device.config 成员赋值
    e.在 drv_uart.c 与 serial.c 中传递的是 struct rt_serial_device 结构体, 那从 serial.c 回调 drv_uart.c 中的函数, 是怎么找到 struct imxrt_uart 结构体呢?
        通过 rt_container_of 函数
3. 在 serial.c 文件中做了如下事情
    a.对抽象出来的公共成员及方法做对应的处理
    b.回调 drv_uart.c 文件中的方法, 传递 struct rt_serial_device, 该结构体定义在 serial.h 文件中. 所以在 drv_uart.c 与 serial.c 之间的传递中要传递 struct rt_serial_device
    c.在 rt_hw_serial_register 函数中就 找到 rt_device_t 成员, 并对 rt_device_t 成员进行初始化, 主要是初始化"回调函数", 在 IO设备管理器 执行过程中, 才能找 "serial串口设备驱动框架" 的处理函数. 执行到 serial.c 中的函数时, 再回调 drv_uart.c 的函数. 注册就这样从上层一层层到下层, 回调就这样从下层一层层到上层.

你可能感兴趣的:(#,嵌入式OS之RTThread)