当前位置: 首页 > news >正文

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.使用

文档

相关文章:

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设备基类 struc…...

PyCharm - Script parameters (脚本参数)

PyCharm - Script parameters [脚本参数] References Run -> Edit Configurations… -> Run/Debug Configurations -> Configuration -> Script parameters 命令行: python display_yolo_log.py ./person_training_log/person_train_log_DIMM40_stdout…...

Security6.2 中的SpEL 表达式应用(权限注解使用)

最近学习若依框架,里面的权限注解涉及到了SpEL表达式 PreAuthorize("ss.hasPermi(system:user:list)"),若依项目中用的是自己写的方法进行权限处理, 也可以只用security 来实现权限逻辑代码,下面写如何用security 实现。…...

软考笔记--信息系统开发方法(下)

信息系统是一个极其复杂的人机交互系统,它不仅包含计算机技术,通信技术和网络规划以及其他的工程技术,而且,它还是一个复杂的管理系统,需要管理理论和方法的支持,因此,与其他工程项目相比&#…...

从 AGP 4.1.2 到 7.5.1——XmlParser、GPathResult、QName 过时

新年首发, 去年的问题,今年解决~ 问题 & 排查 1: Task failed with an exception. ----------- * What went wrong: Execution failed for task :app:processCommonReleaseManifest. > org.xml.sax.SAXParseException; lineNumber: 1; columnNu…...

spring boot 使用AOP实现是否已登录检测

前后端分离的开发中,用户http请求应用服务的接口时, 如果要求检测该用户是否已登录。可以实现的方法有多种, 本示例是通过aop 的方式实现,简单有效。 约定:前端http的post 请求 export async function request(url,data) {const …...

为什么从没有负值的数据中绘制的小提琴图(Violin Plot)会出现负值部分?

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 小提琴图(Violin Plot) 是一种用于展示和比较数据分布的可视化工具。它结合了箱形图(Box Plot)和密度图(Kernel Density Plot)的特…...

有哪几种行为会导致服务器被入侵

导致服务器被入侵的行为有很多种,以下是一些常见的行为: 系统漏洞:服务器操作系统或软件存在漏洞,攻击者可以通过利用这些漏洞获取系统权限,从而入侵服务器。 弱口令:服务器的账号密码过于简单或者未及时更…...

Redis RabbitMQ

Redis:轻量级,NoSQL数据库 redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这…...

http 和 https 的区别?

目录 1.http 和 https 的基本概念 2.http 和 https 的区别 3.https 协议的工作原理 4.https 协议的优点 5.https 协议的缺点 1.http 和 https 的基本概念 http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和…...

C++中线程的创建

线程创建 引言为什么要使用线程线程的创建使用函数指针示例运行结果使用类对象示例运行结果使用lambda表达式示例运行结果使用带参数的函数作为线程处理函数示例运行结果使用类成员函数示例运行结果引言 在学习C++的过程中,线程的使用作为一个非常重要的部分,也是在复杂项目…...

基于JavaWeb开发的家政服务平台计算机毕业设计[附源码]

基于JavaWeb开发的家政服务平台计算机毕业设计[附源码] 🍅 作者主页 央顺技术团队 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 文末获取源码联系方式 📝 🍅 查看下方微信号获取联系方式 承接各种定制系统…...

性能调优:容易忽视的JavaScript标签属性及其性能影响

在性能优化中,我们都知道,async属性可以让script标签变得不阻塞HTML解析,defer属性也有类似的功能,但实际defer是会阻塞script解析的(用defer的话,多个script会按顺序执行,而async执行是无序的&…...

【机器学习笔记】7 KNN算法

距离度量 欧氏距离(Euclidean distance) 欧几里得度量(Euclidean Metric)(也称欧氏距离)是一个通常采用的距离定义,指在𝑚维空间中两个点之间的真实距离,或者向量的自然长度(即该点…...

mysql 2-20

TEXT类型 枚举类型 SET类型 二进制字符串类型 BLOB类型 注意事项 JSON类型 提取数据 空间类型 选择建议 约束...

Unity3D Shader 素描风格渲染管线实现详解

前言 在游戏开发中,渲染效果是非常重要的一部分,它可以直接影响游戏的视觉效果和玩家的体验。而素描风格的渲染效果是一种非常独特和有趣的风格,可以为游戏增添一种艺术氛围。在Unity3D中,可以通过编写Shader来实现素描风格的渲染…...

WordPress站点如何实现发布文章即主动推送到百度快速收录和普通收录?

我们在WordPress后台成功发布文章之后,如果靠搜索引擎来抓取的话,可能会比较慢,所以十分有必要将我们成功发布的文章马上提交到百度、必应等搜索引擎中。下面boke112百科就跟大家说一说WordPress站点如何实现发布文章即主动推送到百度快速收录…...

C++11---(3)

目录 一、可变参数模板 1.1、可变参数模板的概念 1.2、可变参数模板的定义方式 1.3、如何获取可变参数 二、lambda表达式 2.1、Lamabda表达式定义 2.2、为什么有Lambda 2.3、Lambda表达式的用法 2.4、函数对象与lambda表达式 三、包装器 3.1、function 3.2、bind …...

【常识】大数据设计基础知识

底层存储:hadoop(hdfsmapreduce) Hadoop已经有十几年的历史,它是大数据领域的存储基石,HDFS目前仍然没有成熟替代品;MapR 文件系统在业内已经具有一定知名度了,不仅 MapR 宣布它自己的文件系统比 HDFS 快2-…...

Vue:Vuex模块化编码(非常实用)

一、情景说明 通过前面的学习,我们知道,Vuex的核心文件就是indexc.js 这个文件里面,主要是四个对象 actions、mutations、state、getters 那么,随着业务的复杂化,所有的逻辑都写在一个actions里面吗? 显然…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

uniapp 字符包含的相关方法

在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

Linux部署私有文件管理系统MinIO

最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...

​​企业大模型服务合规指南:深度解析备案与登记制度​​

伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...

JS红宝书笔记 - 3.3 变量

要定义变量,可以使用var操作符,后跟变量名 ES实现变量初始化,因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符,可以创建一个全局变量 如果需要定义…...

数据库正常,但后端收不到数据原因及解决

从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...

数据库优化实战指南:提升性能的黄金法则

在现代软件系统中,数据库性能直接影响应用的响应速度和用户体验。面对数据量激增、访问压力增大,数据库性能瓶颈经常成为项目痛点。如何科学有效地优化数据库,提升查询效率和系统稳定性,是每位开发与运维人员必备的技能。 本文结…...

[KCTF]CORE CrackMe v2.0

这个Reverse比较古老,已经有20多年了,但难度确实不小。 先查壳 upx压缩壳,0.72,废弃版本,工具无法解压。 反正不用IDA进行调试,直接x32dbg中,dump内存,保存后拖入IDA。 这里说一下…...