嵌入式面向对象学习 RT-Thread I/O 设备管理框架 设备驱动层 案例测试

嵌入式面向对象 RT-Thread I/O 设备管理框架 设备驱动层

注:本文介绍性内容转载于《RT-Thread记录(十、全面认识 RT-Thread I/O 设备模型)》

注: 本次使用的开发板 :

​ 兆易创新GD32F407VET6开发板

​ 雅特力科技AT32A403A开发板

在这里插入图片描述
在这里插入图片描述

一、RT-Thread 的 I/O设备管理

1.1 什么是 I/O 设备模型
1.2 I/O 设备模型框架解析
1.3 I/O 设备操作逻辑说明
1.4 I/O 设备模型框架用处

二、I/O 设备模型操作 API

2.1 I/O 设备控制块
2.2 创建 I/O 设备相关
2.3 访问 I/O 设备相关

三、新建 I/O 设备模型实例

3.1 设备驱动层编写
3.2 应用层测试

一、RT-Thread 的 I/O设备管理

我们先从基本概念说起,了解RT-Thread 对 I/O 设备的管理方式,以及 I/O 设备模型框架的用途:

1.1 什么是 I/O 设备模型

有些小伙伴在刚接触到这个概念的时候还不太明白, I/O 设备模型,IO口?IO口的模型?

注意这里的 I/O 指的是 Input/Output。I/O 设备,就是指的输入 / 输出设备。

所谓 I/O 设备模型,指的是 RT-Thread 把所有的 输入 / 输出设备当做一类对象,然后通过自己的一套体系对这类对象进行管理,这类 I/O 设备对象就可以认为是 I/O 设备模型。

RT-Thread 提供了一套模型框架用来对所有的输入/输出设备进行管理的,名叫 I/O 设备模型框架 ,其 位于硬件层和应用程序之间,包括IO设备管理层、设备驱动框架层和设备驱动层, 向上层层抽象,目标是针对各种不同的I/O设备提供给应用程序相同的接口,如下图:
在这里插入图片描述
内容太多,具体内容在 嵌入式面向对象学习 RT-Thread I/O 设备管理框架 设备驱动层

三、新建 I/O 设备模型实例

前面的大部分内容都是参考文章的东西,对于I/O 设备模型进行了大量的说明。接下来进行案例测试

RT-Thread 驱动都是在 drivers 目录下面:
在这里插入图片描述

我们在目录下新建一个文件,作为驱动示例:

我们写一个简单的基本框架:

1、创建一个设备;
使用 rt_device_create 创建一个设备,需要定义一个 rt_device_t 接口体接收设备设备句柄。

2、实现设备操作的函数:
实现设备对象中对于 设备操作的init,open,close,read,write,control等 函数。在这里插入图片描述
3、注册设备到 I/O 设备管理器;
使用 rt_device_register 将设备注册到设备管理器。

drv_demo.c 中,我们实现如下代码:

在这里插入图片描述
其次,我们需要实现一下设备操作的函数:
在这里插入图片描述
最后,别忘了使用 INIT_BOARD_EXPORT 把设备初始化的代码加入板级硬件初始化:

设备模型实例代码:

#include <rtdevice.h>
#include <rtdbg.h>rt_err_t  demo_init(rt_device_t dev)
{rt_kprintf("demo_init ok!\n");return RT_EOK;
}
rt_err_t  demo_open(rt_device_t dev, rt_uint16_t oflag)
{rt_kprintf("demo_open ok!\n");return RT_EOK;
}
rt_err_t  demo_cloes(rt_device_t dev)
{rt_kprintf("demo_cloes ok!\n");return RT_EOK;
}rt_ssize_t demo_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{buffer = "this is device read example";rt_kprintf("read example: %s\n",buffer);return RT_EOK;
}
rt_ssize_t demo_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{buffer = "this is device write example";rt_kprintf("write example: %s\n",buffer);return RT_EOK;
}
rt_err_t  demo_control(rt_device_t dev, int cmd, void *args)
{switch(cmd){case 0:rt_kprintf("this is demo_control example cmd-1!\n");	break;case 1:rt_kprintf("this is demo_control example  cmd-2!\n");	break;case 2:rt_kprintf("this is demo_control example  cmd-3!\n");	break;default:break;}
}int rt_drvdemo_init(void)
{rt_device_t demo_dev = RT_NULL;demo_dev = rt_device_create(RT_Device_Class_Char, 0);if(demo_dev == RT_NULL){LOG_E("demo device create failed...\n");return RT_ERROR;}demo_dev->init=demo_init;demo_dev->open=demo_open;demo_dev->close=demo_cloes;demo_dev->read = demo_read;demo_dev->write = demo_write;demo_dev->control =demo_control;rt_device_register(demo_dev,"drvdemo",RT_DEVICE_FLAG_RDWR);return 0;
}INIT_BOARD_EXPORT(rt_drvdemo_init);

上面我们完成的是 设备驱动层的 代码,接下来我们还需要简单演示一下,如果在应用层 使用这个 demo 设备。

我们根据上文所介绍的 访问 I/O 设备 进行对应操作,这里直接上图说明一下使用流程:

应用测试函数

rt_device_t dev = RT_NULL;void *read_buf;
void *write_buf;int main(void)
{dev = rt_device_find("drvdemo");rt_device_init(dev);rt_thread_mdelay(1000);rt_device_open(dev,RT_DEVICE_OFLAG_OPEN);rt_device_read(dev,0,read_buf,20);rt_device_write(dev,0,write_buf,20);rt_device_control(dev,0,RT_NULL);rt_device_close(dev);return RT_EOK;
}

看一下测试结果,我们实现的 3 个驱动函数都只有打印输出,所以我们可以通过打印信息查看是否正确执行的驱动函数的内容:

下面是在雅特力AT32开发板的测试结果。

(原本打算使用gd32去做实验的,但是从官方的MDK工程打开一直存在问题,然后就换了一块板子,进行测试,从这里可以发现,统一的API接口的好处,应用层无缝对接)

在这里插入图片描述
在这里插入图片描述
下面是在对于立创开发板GD32F407进行详细实验。

  1. 下载rt-thread 源码
  2. 寻找bsp-gd32工程,gd32有两个类型一个是arm,一个risc-v
  3. 寻找立创开发板GD32F407模板工程 gd32f407v-lckfb
  4. 使用env工具进行配置

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  1. 如果直接编译,会报一个错误bug,需要修改,解决方法是添加condvar.c文件即可。

在这里插入图片描述

  1. 添加编写的drv_demo.c文件,完成设备驱动的添加

在这里插入图片描述
7. 编写应用层程序 测试

/** Copyright (c) 2006-2024, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2024-01-13     yuanzihao    first implementation*/#include <stdio.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>/* defined the LED1 pin: PB2 */
#define LED_PIN GET_PIN(B, 2)
rt_device_t dev = RT_NULL;void *read_buf;
void *write_buf;
int main(void)
{int count = 1;dev = rt_device_find("drvdemo");rt_device_init(dev);rt_thread_mdelay(1000);rt_device_open(dev,RT_DEVICE_OFLAG_OPEN);rt_device_read(dev,0,read_buf,20);rt_device_write(dev,0,write_buf,20);rt_device_control(dev,1,RT_NULL);rt_device_close(dev);/* set LED1 pin mode to output */rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);while (count++){rt_pin_write(LED_PIN, PIN_HIGH);rt_thread_mdelay(500);//rt_kprintf("this is led_control on  [ok]!\n");	rt_pin_write(LED_PIN, PIN_LOW);rt_thread_mdelay(500);//rt_kprintf("this is led_control off [ok]!\n");	}return RT_EOK;
}

在这里插入图片描述
在这里插入图片描述

通过上面的测试,我们实现了一个简单的设备驱动的设计,虽然demo比较简单,但是经过这么一个过程可以让我们更加的理解 RT-Thread I/O 设备模型的工作方式和流程。

在这里,同时介绍一个开源项目mr-library。

mr-library 是一个开源项目,设备抽象层应该比RT-Thread更加轻量级,是一个学习设备框架,设备驱动,面向对象操作的好东西。

设备抽象层的开源库 mr-library

mr-library 框架是专为嵌入式系统设计的轻量级框架。充分考虑了嵌入式系统在资源和性能方面的需求。 通过提供标准化的设备管理接口,极大简化了嵌入式应用开发的难度,帮助开发者快速构建嵌入式应用程序。

框架为开发者提供了标准化的开启(open)、关闭(close)、控制(ioctl)、读(read)、写(write) 等接口。它将应用程序与底层硬件驱动进行解耦。应用程序无需了解驱动的实现细节。 当硬件发生改变时,只需要适配底层驱动,应用程序就可以无缝迁移到新硬件上。这大大提高了软件的可重用性和应对新硬件的可扩展性。


在这里插入图片描述

关键特性

  • 标准化的设备访问接口
  • 应用程序和驱动开发解耦
  • 简化底层驱动和应用程序开发
  • 轻量易上手,资源占用低
  • 模块化设计,各部分解耦合并独立开发,极低的硬件迁移成本
  • 支持在裸机环境和操作系统环境下使用

主要组成

  • 设备框架:提供设备访问标准接口
  • 内存管理:动态内存管理
  • 工具:链表、队列、平衡树等常用数据结构
  • 各类功能组件

标准化设备接口

设备的所有操作都可通过以下接口实现:

接口描述
mr_dev_register注册设备
mr_dev_open打开设备
mr_dev_close关闭设备
mr_dev_ioctl控制设备
mr_dev_read从设备读取数据
mr_dev_write向设备写入数据

测试案例

在这里插入图片描述

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

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

相关文章

nginx配置证书和私钥进行SSL通信验证

文章目录 一、背景1.1 秘钥和证书是两个东西吗&#xff1f;1.2 介绍下nginx配置文件中参数ssl_certificate和ssl_certificate_key1.3介绍下nginx支持的证书类型1.4 目前nginx支持哪种证书格式&#xff1f;1.5 nginx修改配置文件目前方式也会有所不同1.6 介绍下不通格式的证书哪…

微服务-4 Nacos

目录 一、注册中心 二、配置管理 1. 添加配置 2. 配置自动刷新 3. 多环境配置共享​编辑 一、注册中心 服务列表&#xff1a; 服务详情&#xff1a; 二、配置管理 1. 添加配置 (1). 在 nacos 界面中添加配置文件&#xff1a; 配置列表&#xff1a; 配置详情&#xff1a;…

Qt之QSS样式表

QSS简介 QSS&#xff08;Qt Style Sheet&#xff09;样式表是一种用于描述图形用户界面&#xff08;GUI&#xff09;样式的语言。它允许开发者为应用程序的控件定义视觉外观&#xff0c;例如颜色、字体、尺寸和布局等。 QSS 样式表的主要目的是提供一种简洁而灵活的方式来美化…

【优选算法专栏】专题四:前缀和(一)

本专栏内容为&#xff1a;算法学习专栏&#xff0c;分为优选算法专栏&#xff0c;贪心算法专栏&#xff0c;动态规划专栏以及递归&#xff0c;搜索与回溯算法专栏四部分。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小…

DRF 常用功能

文章目录 一、主流认证方式Session认证Token认证JWT认证 二、DRF认证与权限Session认证所有视图&#xff08;全局&#xff09;启用认证视图级别启用认证 Token认证[推荐]安装APP启用Token认证生成数据库表(因为token要存储到数据库&#xff09;配置Token认证接口URL获取token使…

迭代器模式【行为模式C++】

1.简介 迭代器模式是一种行为设计模式&#xff0c; 让你能在不暴露集合&#xff08;聚合对象&#xff09;底层表现形式 &#xff08;列表、 栈和树等&#xff09; 的情况下遍历集合&#xff08;聚合对象&#xff09;中所有的元素。 迭代器的意义就是将这个行为抽离封装起来&a…

STM32F4 IAP跳转APP问题及STM32基于Ymodem协议IAP升级笔记

STM32F4 IAP 跳转 APP问题 ST官网IAP例程Chapter1 STM32F4 IAP 跳转 APP问题1. 概念2. 程序2.1 Bootloader 程序 问题现象2.2. APP程序 3. 代码4. 其他问题 Chapter2 STM32-IAP基本原理及应用 | ICP、IAP程序下载流程 | 程序执行流程 | 配置IAP到STM32F4xxxChapter3 STM32基于Y…

SQLite数据库在Linux系统上的使用

SQLite是一个轻量级的数据库解决方案&#xff0c;它是一个嵌入式的数据库管理系统。SQLite的特点是无需独立的服务器进程&#xff0c;可以直接嵌入到使用它的应用程序中。由于其配置简单、支持跨平台、服务器零管理&#xff0c;以及不需要复杂的设置和操作&#xff0c;SQLite非…

python如何输入多行

Python中的Input()函数在输入时&#xff0c;遇到回车符&#xff0c;那么一次输入就结束了。这不能满足输入多行文本并且行数也不确定的情形&#xff0c;当然输入空行也是允许的。 方法1&#xff1a;利用异常处理机制实现 lines[] while True:try:lines.append(input())except:…

达梦数据库清理归档日志的方法

达梦数据库清理归档日志的方法 在达梦数据库&#xff08;DM数据库&#xff09;中&#xff0c;归档日志文件是数据库运行过程中产生的&#xff0c;用于记录所有对数据库修改的详细信息。这些日志对于数据库的恢复非常关键&#xff0c;尤其是在进行灾难恢复或数据恢复时。然而&a…

关于Linux下的进程等待(进程篇)

目录 为什么存在进程等待&#xff1f;进程等待是在做什么&#xff1f; 怎样去执行进程等待&#xff1f; status options 为什么存在进程等待&#xff1f;进程等待是在做什么&#xff1f; 代码示例&#xff1a;模仿僵尸进程 #include <stdio.h> #include <unistd.…

xss跨站脚本攻击笔记

1 XSS跨站脚本攻击 1.1 xss跨站脚本攻击介绍 跨站脚本攻击英文全称为(Cross site Script)缩写为CSS&#xff0c;但是为了和层叠样式表(CascadingStyle Sheet)CSS区分开来&#xff0c;所以在安全领域跨站脚本攻击叫做XSS 1.2 xss跨战脚本攻击分类 第一种类型:反射型XSS 反射…

java数据结构与算法刷题-----LeetCode684. 冗余连接

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 并查集 并查集 解题思路&#xff1a;时间复杂度O( n ∗ l o g 2…

ThinkPHP审计(2) Thinkphp反序列化链5.1.X原理分析从0编写POC

ThinkPHP审计(2) Thinkphp反序列化链子5.1.X原理分析&从0编写POC 文章目录 ThinkPHP审计(2) Thinkphp反序列化链子5.1.X原理分析&从0编写POC动态调试环境配置Thinkphp反序列化链5.1.X原理分析一.实现任意文件删除二.实现任意命令执行真正的难点 Thinkphp反序列化链5.1.…

JVM规范中的运行时数据区

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a;每天一个知识点 ✨特色专栏&#xff1a…

SpringBoot 集成H2数据库,启动执行sql, 中文乱码

目录 H2数据库介绍 SpringBoot版本&#xff1a;SpringBoot 2.1.12.RELEASE 快速集成H2&#xff0c;maven依赖 快速集成H2&#xff0c;数据源及关键参数配置 spring.datasource.schema参数&#xff08;建表SQL脚本&#xff09; spring.datasource.data参数&#xff08;更新、…

Qt5 编译 Qt Creator 源码中的 linguist 模块

文章目录 下载 Qt Creator 源码手动翻译多语言自动翻译多语言 下载 Qt Creator 源码 Github: https://github.com/qt/qttools 笔记打算用 Qt 5.12.12 来编译 qt creator-linguist 所以笔者下载的是 tag - 5.12.12 &#xff0c;解压后如下&#xff0c;先删除多余的文件&#xf…

【Vue】Vue3中的OptionsAPI与CompositionAPI

文章目录 OptionsAPICompositionAPI对比总结 OptionsAPI 中文名:选项式API通过定义methods,computed,watch,data等属性方法&#xff0c;处理页面逻辑。以下是OptionsAPI代码结构 实例代码: <script lang"ts">// js或者tsimport { defineComponent } from vu…

【学习】软件测试需求分析要从哪些方面入手

软件测试需求分析是软件测试过程中非常重要的一个环节&#xff0c;它是为了明确软件测试的目标、范围、资源和时间等要素&#xff0c;以确保软件测试的有效性和全面性。本文将从以下几个方面对软件测试需求分析进行详细的阐述&#xff1a; 一、软件测试目标 软件测试目标是指…

读所罗门的密码笔记16_直通心智

1. 直通心智 1.1. 如今&#xff0c;科学家已经可以诱发触觉、压觉、痛觉和大约250种其他感觉 1.1.1. DARPA支持的触觉技术第一次让一位受伤的人能够用假肢和手指感知到被触碰的物体 1.1.2. 可以建立人工系统&#xff0c;来替换和弥补受损大脑的部分区域 1.1.3. 神经科学家能…