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

目录

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

1.触摸设备基类

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

在/ components / drivers / include / drivers /touch.h定义了如下touch设备基类
struct rt_touch_device
{
struct rt_device parent;
struct rt_touch_info info;
struct rt_touch_config config;
const struct rt_touch_ops *ops;
rt_err_t (*irq_handle)(rt_touch_t touch);
};

触摸设备基类是继承自设备基类,再增加私有属性和方法而成。

触摸设备基类中抽象出的共性操作方法定义如下
struct rt_touch_ops
{
rt_size_t (*touch_readpoint)(struct rt_touch_device *touch, void *buf, rt_size_t touch_num);
rt_err_t (*touch_control)(struct rt_touch_device *touch, int cmd, void *arg);
};
抽象出了读取坐标点方法和控制方法。
在这里插入图片描述

该类的构造函数:rt_hw_touch_register。

2.触摸设备基类的子类

此层是设备驱动层,此类是实现类,由各个bsp实现。例如
/bsp / stm32 / stm32f407-atk-explorer / board / ports / touch /drv_touch_xpt.h定义的xpt2046触摸设备类。
其他芯片厂家如此这般一样。

3.初始化/构造流程

以stm32正点原子探索者bsp的电阻屏上的触摸设备为例,从设备驱动层、设备驱动框架层到io设备管理层从下到上的构造/初始化流程如下

3.1设备驱动层

此层是驱动层,是bsp所在,也是可以实例化的实现类所在。

/bsp / stm32 / stm32f407-atk-explorer / board / ports / touch / drv_touch_xpt.h中

定义了stm32的xpt2046触摸设备类
struct rt_xpt2046
{
struct rt_touch_device parent;
struct rt_spi_device *spi;
rt_uint16_t min_raw_x;
rt_uint16_t min_raw_y;
rt_uint16_t max_raw_x;
rt_uint16_t max_raw_y;
};

xpt2046触摸设备类的组成:
继承自触摸设备基类,
又关联了spi设备类,因为它这个开发板的触摸设备是spi通信的,所以要关联下,
然后又记录下触摸屏输出得最小最大xy值,用以计算并限制输出范围。

其构造函数: xpt2046_hw_init。

/ bsp / stm32 / stm32f407-atk-explorer / board / ports / touch / drv_touch_xpt.c中

实现了其构造函数 xpt2046_hw_init。

在其构造函数中实例化了xpt2046触摸设备类:
rt_xpt2046_t dev_obj = rt_malloc(sizeof(struct rt_xpt2046));

然后初始化其私有属性和父类(触摸设备基类)部分属性,然后重写父类(触摸设备基类)的方法:
dev_obj->parent.ops = &xpt2046_ops;

重写的方法定义如下:
static struct rt_touch_ops xpt2046_ops =
{
.touch_readpoint = xpt2046_touch_readpoint,
.touch_control = xpt2046_touch_control,
};
然后调用父类(触摸设备基类)的构造函数rt_hw_touch_register继续后续的初始化。
请添加图片描述

3.2 设备驱动框架层

/ components / drivers / touch / touch.c中实现了设备驱动框架层接口rt_hw_touch_register——也是触摸设备基类的构造函数——开启触摸设备基类的构造/初始化流程。

该层重写了触摸设备基类的父类——设备基类——的方法:
#ifdef RT_USING_DEVICE_OPS
device->ops = &rt_touch_ops;
#else
device->init = RT_NULL;
device->open = rt_touch_open;
device->close = rt_touch_close;
device->read = rt_touch_read;
device->write = RT_NULL;
device->control = rt_touch_control;
#endif

并最终调用触摸设备基类的父类——设备基类——的构造函数rt_device_register进行设备基类的初始化。
在这里插入图片描述

3.3 io设备管理层

在/ components / drivers / core 下的device.c中实现了设备基类的构造函数rt_device_register,它是io设备管理层的入口。
它将xpt2046触摸设备对象放到对象容器里管理。

详细参见io设备管理层。
https://blog.csdn.net/yhb1206/article/details/136440373

4.总结

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

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

其构造整体的实质,是对结构体进行初始化,在C中没有面向对象语言层面的机制,只能采用结构体套用结构体来模拟,这样原先定义好的结构体以及其对象构造函数对新扩展的(包含它的)结构体是解耦的,你新增一个新扩展(包含它的)新结构体,初始化它(面向对象叫父类)时只需要调用它对应的构造函数即可,对于新结构体来说原先的结构体是固定不变的,解耦了。所以这个方式的初始化不像那种把结构体成员挨个赋值这么繁琐,因为rtt规定了这些结构体以及封装了其初始化函数(在c++面向对象中叫构造函数),只需调用即可。

5.使用

文档

5.1实例

以上面xpt2046触摸设备为例,在/bsp / stm32 / stm32f407-atk-explorer / board / ports / touch /下面3个相关文件:
drv_touch_xpt.c
drv_touch_xpt.h
drv_xpt2046_init.c

其中drv_touch_xpt.c和drv_touch_xpt.h实现了定义xpt2046触摸设备类及其实例化,并实现了该类的构造函数xpt2046_hw_init,前面第3节讲过。而drv_xpt2046_init.c是使用xpt2046触摸设备的。

该类对象是讲的触摸LCD屏上的触摸设备对象xpt2046,先澄清下这个。

drv_xpt2046_init.c中的使用如下:
static int touch_xpt2046_init(void)
{
xpt2046_init_hw();
rt_thread_t tid = rt_thread_create(“xpt2046”, xpt2046_entry, RT_NULL, 1024, 8, 20);
RT_ASSERT(tid != RT_NULL);
rt_thread_startup(tid);
return RT_EOK;
}
INIT_COMPONENT_EXPORT(touch_xpt2046_init);

可以看到它采用的rtt的自动初始化机制,在main_entry线程里自动调用。

xpt2046_init_hw();主要是获取第3节讲的xpt2046设备对象指针,然后又拿到硬件原理图链接的spi设备对象(相关的软件spi总线和spi设备早自动初始化了),然后查找lcd设备,启动lcd,然后触摸屏矫正。

而xpt2046_entry这个线程呢,就是检查触摸的线程,如果开启了LVGL就告诉lvgl处理模块,否则就在屏幕上显示触摸点痕迹。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/720592.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云计算 3月2号 (自配本地和远程yum源)

自建yum源 本地源 一、使用本地的镜像文件来制作yum源(做完记得删除) 1、挂载dvd镜像或将镜像拷贝到机器中 mkdir /yum-repo mount /dev/cdrom /yum-repo # 如果我们在设置中挂载了镜像使用这个方法 mount 镜像的路径 /yum-repo # 如果我们拷贝镜像到了系统中,可…

flink on yarn paimon

目录 概述实践paimon 结束 概述 ogg kafka paimon 实践 前置准备请看如下文章 文章链接hadoop一主三从安装链接spark on yarn链接flink的yarn-session环境链接 paimon 目标: 1.同步表2.能过 kafka 向 paimon写入 SET parallelism.default 2; set table.exec.sink.not-n…

Ai学社致力于Ai视觉设计和AI绘画

Ai学社来啦!致力于短时间搞定Ai视觉设计、AI绘画。 遍知首席Ai讲师,教大家如何利用Ai迅速提升工作效率,升职加xin!目前申请对ai感兴趣的均可以参加!免费报名。 招生人数:本批次至少招募100名。招生时间&…

C++ Date类型定义 (类的简单实践案例)

//头文件#include<iostream> #include<assert.h> using namespace std;class Date { public:// 获取某年某月的天数int GetMonthDay(int year, int month);// 全缺省的构造函数Date(int year 1900, int month 1, int day 1);// 拷贝构造函数// d2(d1)Date(const…

LeetCode-02

225. 用队列实现栈 用两个队列实现栈的功能&#xff0c;思路如下&#xff1a; 往空队列中放新元素把非空队列中的元素依次放入刚才添加了新元素的队列&#xff0c;直到非空队列变为空队列 class MyStack(object):def __init__(self):self.queue1 []self.queue2 []def push(…

【教程】Kotlin语言学习笔记(四)——方法(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【Kotlin语言学习】系列文章 第一章 《认识Kotlin》 第二章 《数据类型》 第三章 《数据容器》 第四章 《方法》 文章目录 【…

突发,Anthropic推出突破性Claude 3系列模型,性能超越GPT-4

&#x1f989; AI新闻 &#x1f680; 突发&#xff0c;Anthropic推出突破性Claude 3系列模型 摘要&#xff1a;人工智能创业公司Anthropic宣布推出其Claude 3系列大型语言模型&#xff0c;该系列包括Claude 3 Haiku、Claude 3 Sonnet和Claude 3 Opus三个子模型&#xff0c;旨…

Cesium 自定义Primitive-绘制圆

一、创作来源 1、cesium的entity绘制圆 2、不使用entity的情况下&#xff0c;使用自定义的primitive来动态绘制圆 3、结合上一篇文章的圆&#xff0c;执行动态圆的更新 二、编写步骤 1、创建绘制线的类 包括构造函数、绘图函数以及销毁函数 import { Viewer, ScreenSpaceEven…

docker-compose启动postgres数据库,实现主从备份

文章目录 1. 主库2. 从库3. 测试 1. 主库 创建pg-m 目录&#xff0c;并进入该目录创建docker-compose.yml文件&#xff0c;内容如下&#xff1a; version: "3.1" services:pg_master:image: postgres:15.3container_name: pg_masterenvironment:POSTGRES_PASSWORD:…

Domain Adaptation Vs. Prompt-Tuning:能否用域自适应解决大模型提示学习问题?

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 作者简介 李江梦&#xff0c;中国科学院软件研究所天基综合信息系统全国重点实验室助理研究员 论文简介 今天介绍的是被机器学习领域顶级学术会议ICLR 2024接收的论文&#xff1a;BayesPrompt: Prompting Large…

广东Lenovo SR588服务器维修升级硬盘内存

本案例描述了对联想SR588服务器进行硬件升级的过程&#xff0c;包括更换固态硬盘作为系统盘&#xff0c;以及增加内存容量至128GB。升级后&#xff0c;服务器性能得到显著提升&#xff0c;同时通过重新配置RAID阵列和操作系统的重新安装&#xff0c;确保了系统的稳定性和数据的…

STM32 NAND FLASH知识点

1.NAND FLASH的简介 NAND FLASH 的概念是由东芝公司在 1989 年率先提出&#xff0c;它内部采用非线性宏单元模式&#xff0c;为固态大容量内存的实现提供了廉价有效的解决方案。 NAND FLASH 存储器具有容量较大&#xff0c;改写速度快等优点&#xff0c;适用于大量数据的存储&…

MySQL EXPLAIN 性能分析工具详解

EXPLAIN 是 MySQL 中一个非常重要的性能分析工具&#xff0c;它用于显示 MySQL 如何执行 SQL 查询。通过 EXPLAIN&#xff0c;你可以查看查询的执行计划&#xff0c;从而理解查询是如何被优化和执行的&#xff0c;从而找出可能的性能瓶颈。 如何使用 EXPLAIN 使用 EXPLAIN 非…

CC++语言强制类型转换的类型

介绍 在C语言中&#xff0c;可以使用强制类型转换&#xff08;也称为显式类型转换&#xff09;来改变一个变量的类型。这通常在你需要将一个类型的值转换为不兼容的另一种类型时非常有用。 强制类型转换的语法如下&#xff1a; (type_name) expression其中&#xff0c;type_…

Unix Network Programming Episode 88

‘inetd’ Daemon On a typical Unix system, there could be many servers in existence, just waiting for a client request to arrive. Examples are FTP, Telnet, Rlogin, TFTP, and so on. With systems before 4.3BSD, each of these services had a process associate…

如何利用Flutter来写后端 服务端应用

前言 Flutter是谷歌推出的一款跨平台开发框架&#xff0c;现在属于此领域star最多的框架&#xff0c;其被广泛应用于构建前台界面&#xff0c;但或许很少人知道&#xff0c;他也可以写后端应用。 本文主角 flutter非常著名的getx库推出的get server jonataslaw/get_server:…

实验01-STP+链路聚合+VRRP实验

1.实验拓扑 2 实验需求 根据拓扑图配置IP地址。交换机之间通过STP防环为了防止SW2-SW3之间聚合的高效链路被STP 阻塞&#xff0c;请配置SW2 为网络中的主根&#xff0c;SW3为网络中的备份根桥。通过VRRP实现网关冗余&#xff0c;网关在SW2和SW3上&#xff0c;其中VLAN10的网关…

【3GPP】【核心网】【5G】5G核心网协议解析(一)(超详细)

1. 5G核心网概念 5G核心网是支撑5G移动通信系统的关键组成部分&#xff0c;是实现5G移动通信的重要基础设施&#xff0c;它负责管理和控制移动网络中的各种功能和服务。它提供了丰富的功能和服务&#xff0c;支持高速、低时延、高可靠性的通信体验&#xff0c;并为不同行业和应…

前端监控为什么采用GIF图片做埋点?

一、什么是埋点监控 前端监控是开发人员用来跟踪和维护应用程序表现层的运行状况的过程和工具。它主要包括三种类型&#xff1a;数据监控、性能监控和异常监控。 1、数据监控 主要是为了收集跟用户相关的数据&#xff0c;例如用户设备类型、浏览器版本、页面浏览量&#xff08;…

GIS之深度学习05:VisualStudio安装教程

在安装CUDA前&#xff0c;建议先安装VisualStudio&#xff0c;以防报错 VisualStudio安装步骤简单&#xff0c;但时间较长。。。。。。 正文开始&#xff1a; VisualStudio官网&#xff1a;Visual Studio: IDE and Code Editor for Software Developers and Teams 点击右上角…