/************************ 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 的函数. 注册就这样从上层一层层到下层, 回调就这样从下层一层层到上层.
rt-thread UART 驱动注册IO设备管理器的调用关系
最新推荐文章于 2024-09-25 16:18:55 发布