RT-Thread I/O设备模型(二)

news2024/11/25 13:41:11

访问I/O设备

应用程序通过I/O设备管理接口来访问硬件设备,当设备驱动程序实现后,应用程序就可以访问该硬件。I/O设备管理接口与I/O设备的操作方法映射关系如下:
在这里插入图片描述
查找设备
应用程序根据设备名称获取设备句柄,进而操作设备。

rt_device_t rt_device_find(const char* name);

初始化设备
获得设备句柄后,应用程序可对设备进行初始化操作。

rt_err_t rt_device_init(rt_device_t dev);

当一个设备已经初始化成功后,调用这个接口将不再重复初始化。

打开和关闭设备
通过设备句柄,应用程序可以打开和关闭设备,打开设备时,会检测设备是否已经初始化,没有初始化会默认调用初始化接口初始化设备。

rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags);
  • dev:设备句柄。
  • oflags:设备打开模式。
  • RT_EOK:设备打开成功。
  • -RT_EBUSY:如果设备注册时指定的参数中包括RT_DEVICE_FLAG_STANDALONE参数,此设备将不允许重复打开。
#define RT_DEVICE_OFLAG_CLOSE 0x000   /* 设备已经关闭(内部使用)*/
#define RT_DEVICE_OFLAG_RDONLY 0x001  /* 以只读方式打开设备 */
#define RT_DEVICE_OFLAG_WRONLY 0x002  /* 以只写方式打开设备 */
#define RT_DEVICE_OFLAG_RDWR 0x003    /* 以读写方式打开设备 */
#define RT_DEVICE_OFLAG_OPEN 0x008    /* 设备已经打开(内部使用)*/
#define RT_DEVICE_FLAG_STREAM 0x040   /* 设备以流模式打开 */
#define RT_DEVICE_FLAG_INT_RX 0x100   /* 设备以中断接收模式打开 */
#define RT_DEVICE_FLAG_DMA_RX 0x200   /* 设备以 DMA 接收模式打开 */
#define RT_DEVICE_FLAG_INT_TX 0x400   /* 设备以中断发送模式打开 */
#define RT_DEVICE_FLAG_DMA_TX 0x800   /* 设备以 DMA 发送模式打开 */

如果上层应用程序需要设置设备的接收回调函数,则必须以RT_DEVICE_FLAG_INT_RX或者RT_DEVICE_FLAG_DMA_RX的方式打开设备,否则不会回调函数。

应用程序打开设备完成读写等操作后,如果不需要再对设备进行操作则可以关闭设备,通过如下函数完成:

rt_err_t rt_device_close(rt_device_t dev);

关闭设备接口和打开设备接口需配对使用,打开一次设备对应要关闭一次设备,这样设备才能够完全被关闭,否则设备仍处于未关闭状态。

控制设备
通过命令控制字,应用程序也可以对设备进行控制,通过如下函数完成:

rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg);
  • cmd:命令控制字,这个参数通常与设备驱动程序相关。
  • arg:控制的参数。
#define RT_DEVICE_CTRL_RESUME           0x01   /* 恢复设备 */
#define RT_DEVICE_CTRL_SUSPEND          0x02   /* 挂起设备 */
#define RT_DEVICE_CTRL_CONFIG           0x03   /* 配置设备 */
#define RT_DEVICE_CTRL_SET_INT          0x10   /* 设置中断 */
#define RT_DEVICE_CTRL_CLR_INT          0x11   /* 清中断 */
#define RT_DEVICE_CTRL_GET_INT          0x12   /* 获取中断状态 */

数据收发回调
当硬件设备接收到数据时,可以通过函数回调另一个函数来设置数据接收指示,通知上层应用线程有数据到达。

rt_err_t rt_device_set_rx_indicate(rt_device_t dev, rt_err_t (*rx_ind)(rt_device_t dev,rt_size_t size));

rx_ind:回调函数指针

该函数的回调参数由调用者提供。当硬件设备接收到数据时,会回调这个函数,并把收到的数据长度放在size参数中传递给上层应用。上层应用线程在收到指示后,立刻从设备中读取数据。

在应用程序调用 rt_device_write() 写入数据时,如果底层硬件能够支持自动发送,那么上层应用可以设置一个回调函数。这个回调函数会在底层硬件数据发送完成后 (例如 DMA 传送完成或 FIFO 已经写入完毕产生完成中断时) 调用。可以通过如下函数设置设备发送完成指示,函数参数及返回值见:

rt_err_t rt_device_set_tx_complete(rt_device_t dev, rt_err_t (*tx_done)(rt_device_t dev,void *buffer));

调用这个函数时,回调函数由调用者提供,当硬件设备发送完数据时,由驱动程序回调这个函数并把发送完成的数据块地址 buffer 作为参数传递给上层应用。上层应用(线程)在收到指示时会根据发送 buffer 的情况,释放 buffer 内存块或将其作为下一个写数据的缓存。

设备访问示例

#include <rtthread.h>
#include <rtdevice.h>

#define IWDG_DEVICE_NAME    "wdt"

static rt_device_t wdg_dev;

static void idle_hook(void)
{
    /* 在空闲线程的回调函数里喂狗 */
    rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL);
    rt_kprintf("feed the dog!\n ");
}

int main(void)
{
    rt_err_t res = RT_EOK;
    rt_uint32_t timeout = 10;    /* 溢出时间 */

    /* 根据设备名称查找看门狗设备,获取设备句柄 */
    wdg_dev = rt_device_find(IWDG_DEVICE_NAME);
    if (!wdg_dev)
    {
        rt_kprintf("find %s failed!\n", IWDG_DEVICE_NAME);
        return RT_ERROR;
    }
    /* 初始化设备 */
    res = rt_device_init(wdg_dev);
    if (res != RT_EOK)
    {
        rt_kprintf("initialize %s failed!\n", IWDG_DEVICE_NAME);
        return res;
    }
    /* 设置看门狗溢出时间 */
    res = rt_device_control(wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &timeout);
    if (res != RT_EOK)
    {
        rt_kprintf("set %s timeout failed!\n", IWDG_DEVICE_NAME);
        return res;
    }
    /* 设置空闲线程回调函数 */
    rt_thread_idle_sethook(idle_hook);

    return res;
}

I/O设备框架补充图

在这里插入图片描述
图中各类里的.c文件是各类对应的管理接口所在,比如设备基类rt_device的管理接口在device.c中。

图中设备驱动框架层有很多RT-Thread写好的类,图中只列出2类,其它类用“xxx”来表示,这些省略的类及其管理接口可以在conponents/drivers目录下找寻。

设备驱动层的“xxx”,是RT-Thread支持的各BSP平台,在源码的src/bsp目录下找寻,

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

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

相关文章

MybatisPlus基本配置查询操作

无侵入&#xff1a;只做增强不做改变&#xff0c;引入它不会对现有工程产生影响&#xff0c;如丝般顺滑损耗小&#xff1a;启动即会自动注入基本 CURD&#xff0c;性能基本无损耗&#xff0c;直接面向对象操作强大的 CRUD 操作&#xff1a;内置通用 Mapper、通用 Service&#…

手把手教你用Vite构建第一个Vue3项目

写在前面 在之前的文章中写过“如何创建第一个vue项目”&#xff0c;但那篇文章写的是创建vue2的 项目。 传送门如何创建第一个vue项目 打开Vue.js官网:https://cn.vuejs.org/&#xff0c;我们会发现Vue 2 将于 2023 年 12 月 31 日停止维护 虽然Vue2的项目还不少&#xff0…

day5 qt

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);timer_idthis->startTimer(100);//啓動一個定時器 每100ms發送一次信號ui->Edit1->setPlaceholderTex…

Leetcode:349. 两个数组的交集【题解超详细】

题目 给定两个数组 nums1 和 nums2 &#xff0c;返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 难度&#xff1a;简单 题目链接&#xff1a;349.两个数组的交集 示例 1&#xff1a; 输入&#xff1a;nums1 [1,2,2,1], nums2 [2,…

CentOS7上源码安装Redis6

CentOS7上源码安装Redis6 安装依赖开始安装下载安装包解压安装包编译源代码修改配置文件 启动并连接启动redis服务器本地连接远程连接 下篇预告 安装依赖 首先我们是源码包安装我们需要安装C语言编译器&#xff0c;顺便下载wget&#xff1a; yum install -y gcc wget开始安装…

Ab3d.PowerToys 11.0.8614 Crack

版本 11.0.8614 修补程序 使用 MouseCameraController 移动相机时防止旋转 FreeCamera。 版本 11.0.8585 重大更改&#xff1a;由于专利问题删除了 ViewCubeCameraController - 请联系支持人员以获取更多信息以及如果您想继续使用此控件。添加了 CameraNavigationCircles 控件…

第12节——生命周期

一、概念 生命周期指 React 组件从装载至卸载的全过程&#xff0c;这个过程内置多个函数供开发者在组件的不同阶段执行需要的逻辑。 状态组件主要通过 3 个生命周期阶段来管理&#xff0c;分别是 挂载阶段&#xff08;MOUNTING&#xff09;&#xff0c;更新阶段&#xff08;U…

AJAX学习笔记3练习

AJAX学习笔记2发送Post请求_biubiubiu0706的博客-CSDN博客 1.验证用户名是否可用 需求,用户输入用户名,失去焦点-->onblur失去焦点事件,发送AJAX POST请求,验证用户名是否可用 新建表 前端页面 WEB-INF下新建lib包引入依赖,要用JDBC 后端代码 package com.web;import jav…

ModaHub魔搭社区:自动化机器学习框架AutoML

AutoML 自动化机器学习AutoML 是机器学习中一个相对较新的领域,它主要将机器学习中所有耗时过程自动化,如数据预处理、最佳算法选择、超参数调整等,这样可节约大量时间在建立机器学习模型过程中。 自动机器学习 AutoML: 对于 ,令 表示特征向量, 表示对应的目标值。给定…

基于SpringCloudAlibaba实现的NacosConfig

概述 Nacos除了实现了服务的注册发现之外&#xff0c;还将配置中心功能整合在了一起。通过Nacos的配置管理功能&#xff0c;我们可以将整个架构体系内的所有配置都集中在Nacos中存储。这样做的好处主要有以下几点&#xff1a; 分离的多环境配置&#xff0c;可以更灵活的管理权…

基于Java+SpringBoot+Vue前后端分离大学生智能消费记账系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

基于Java+SpringBoot+Vue前后端分离农商对接系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

机器人中的数值优化(十三)——QP二次规划

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

MLOps:掌握机器学习部署:Docker、Kubernetes、Helm 现代 Web 框架

介绍&#xff1a; 在机器学习的动态世界中&#xff0c;从开发模型到将其投入生产的过程通常被认为是复杂且多方面的。 然而&#xff0c;随着 Docker、Kubernetes 等工具以及 FastAPI、Streamlit 和 Gradio 等用户友好的 Web 框架的出现&#xff0c;这一过程变得比以往更加简化…

CS420 课程笔记 P3 - 计数系统基础和 Hex, Decimal, Binary 进制

文章目录 IntroductionInspirationWhy base systemsBinary & HexCounting in binaryAdditional resources Introduction 笔记作者 tips&#xff1a;这一节是关于进制的讲解&#xff0c;推荐观看原视频或学会二进制的读者跳过这一篇&#xff01; 本节课将介绍基本的计算机系…

台球击球角度公式. 包含数学推导

第一步. 物理来分析. 第二步. 数学计算.

【jsvue】联合gtp仿写一个简单的vue框架,以此深度学习JavaScript

用 gtp 学习 Vue 生命周期的原理 lifecycle.js function Vue(options) {// 将选项保存到实例的 $options 属性中this.$options options;// 若存在 beforeCreate 钩子函数&#xff0c;则调用之if (typeof options.beforeCreate function) {options.beforeCreate.call(this);…

Qt 5.15编译及集成Crypto++ 8.7.0笔记

一、背景 为使用AES加密库&#xff08;AES/CBC加解密&#xff09;&#xff0c;选用Crypto 库&#xff08;官网&#xff09;。   最新Crypto C库依次为&#xff1a;8.8.0版本&#xff08;2023-6-25&#xff09;、8.7.0&#xff08;2022-8-7&#xff09;和8.6.0&#xff08;202…

MySQL数据库——多表查询(4)-实例练习、多表查询总结

目录 练习1 练习2 总结 1.多表关系 2.多表查询 进行案例练习之前&#xff0c;需要先增加一个表格 create table salgrade(grade int,losal int, -- 对应等级的最低薪资hisal int -- 对应等级的最高薪资 ) comment 薪资等级表;insert into salgrade values (1,0,3000)…

【高等数学1800】——一元函数微分学的应用

本文仅用于个人学习记录&#xff0c;使用的教材为汤家凤老师的《高等数学辅导讲义》。本文无任何盈利或者赚取个人声望的目的&#xff0c;如有侵权&#xff0c;请联系删除&#xff01; 文章目录 一、入门练习二、基础练习 一、入门练习 本题需要注意在写凸区间时应该是闭区间。…