rtt设备io框架面向对象学习-uart设备

目录

        • 1.uart设备基类
        • 2.uart设备基类的子类
        • 3.初始化/构造流程
          • 3.1设备驱动层
          • 3.2 设备驱动框架层
          • 3.3 设备io管理层
        • 4.总结
        • 5.使用
1.uart设备基类

此层处于设备驱动框架层。也是抽象类。

在/ components / drivers / include / drivers 下的serial.h定义了如下uart设备基类

struct rt_serial_device

{

struct rt_device parent;

const struct rt_uart_ops *ops;

struct serial_configure config;

void *serial_rx;

void *serial_tx;

struct rt_spinlock spinlock;

struct rt_device_notify rx_notify;

};

uart设备基类继承自设备基类,剩下都是私有属性和私有方法。

uart设备基类的方法定义如下

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_ssize_t (*dma_transmit)(struct

rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);

};

抽象出了串口的共性配置、发送、接受、dma传输成为uart设备基类的方法。

2.uart设备基类的子类

此层是设备驱动层,此类是实现类。各个uart设备基类的子类在各个bsp来实现,例如

/ bsp / stm32 / libraries / HAL_Drivers / drivers 下的drv_usart.h定义的stm32_uart 类,这是可以实例化的实现类。其他芯片厂家如此这般一样。

3.初始化/构造流程

以stm32为例,从设备驱动层、设备驱动框架层到设备io管理层从下到上的构造/初始化流程如下

3.1设备驱动层

此层是bsp层,可以实例化的终类地。

c文件:

/ bsp / stm32 / libraries / HAL_Drivers / drivers 下的drv_usart.h。

定义了stm32的uart类

struct stm32_uart

{

UART_HandleTypeDef handle;

struct stm32_uart_config *config;

rt_uint32_t DR_mask;

#ifdef RT_SERIAL_USING_DMA

struct

{

DMA_HandleTypeDef handle;

rt_size_t remaining_cnt;

} dma_rx;

struct

{

DMA_HandleTypeDef handle;

} dma_tx;

#endif

rt_uint16_t uart_dma_flag;
struct rt_serial_device serial;

};

stm32的uart设备类继承自uart设备基类serial,但是这样定义的类把父类写到最后------和rtt设备io框架不一致,改成这样多好:

struct stm32_uart

{
struct rt_serial_device serial;

UART_HandleTypeDef handle;

struct stm32_uart_config *config;

rt_uint32_t DR_mask;

#ifdef RT_SERIAL_USING_DMA

struct

{

DMA_HandleTypeDef handle;

rt_size_t remaining_cnt;

} dma_rx;

struct

{

DMA_HandleTypeDef handle;

} dma_tx;

#endif

rt_uint16_t uart_dma_flag;

};

这样舒服多了。

在/ bsp/stm32/libraries /HAL_Drivers/drivers/drv_usart.c中:

实例化了stm32的uart设备:

static struct stm32_uart uart_obj[sizeof(uart_config) / sizeof(uart_config[0])] = {0};

stm32支持多个串口,所以可以实例化多个stm32串口设备对象。

重写了uart设备基类的方法:

static const struct rt_uart_ops stm32_uart_ops =

{

.configure = stm32_configure,

.control = stm32_control,

.putc = stm32_putc,

.getc = stm32_getc,

.dma_transmit = stm32_dma_transmit

};

int rt_hw_usart_init中开启stm32的uart设备的初始化:

重写uart设备基类的方法与属性

uart_obj[i].config = &uart_config[i];

uart_obj[i].serial.ops = &stm32_uart_ops; uart_obj[i].serial.config = config;

最后调用/ components / drivers /serial /serial.c的rt_device_pwm_register函数来初始化uart设备基类对象:

rt_hw_serial_register(&uart_obj[i].serial, uart_obj[i].config->name,

RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX | uart_obj[i].uart_dma_flag , NULL);

3.2 设备驱动框架层

/ components / drivers /serial 下的serial.c实现了设备驱动框架层接口rt_hw_serial_register,是uart设备驱动框架层的入口,开启uart设备基类的构造/初始化流程。

该层重写了uart设备基类的父类------设备基类------的方法:

#ifdef RT_USING_DEVICE_OPS

device->ops = &serial_ops;

#else

device->init = rt_serial_init;

device->open = rt_serial_open;

device->close = rt_serial_close;

device->read = rt_serial_read;

device->write = rt_serial_write;

device->control = rt_serial_control;

#endif

并最终调用设备基类的构造函rt_device_register。

3.3 设备io管理层

在/ components / drivers / core 下的device.c中实现了rt_device_register,它是io管理层的入口。

它将stm32 uart设备对象放到对象容器里管理。

4.总结

整个设备对象的构造/初始化流程其实是对具体设备对象也就是结构体 进行初始化赋值------它这个结构体是包含一个个的结构体 ------模拟的是面向对象的继承机制 。跟套娃似的,层层进行初始化。这样的好处是什么?每层有每层的初始化(构造)函数,就模拟了面向对象的构造函数------按照先调用子类构造/初始化函数,再调用父类的构造/初始化函数方式------其实也是子类构造/初始化函数调用父类构造/初始化函数的流程,来完成设备对象的初始化/构造。最终放到对象容器里来管理。

这样的好处是可扩展,如搭积木似的,也是对内封闭,对外开放,扩展性好,模拟的是面向对象的继承多态机制。

其实每个类的注册函数模拟的是面向对象的构造函数。

5.使用

文档

相关推荐
西岸行者6 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意6 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码6 天前
嵌入式学习路线
学习
毛小茛6 天前
计算机系统概论——校验码
学习
babe小鑫6 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms6 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下6 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。6 天前
2026.2.25监控学习
学习
im_AMBER6 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J6 天前
从“Hello World“ 开始 C++
c语言·c++·学习