RT-Thread操作系统(2)

RT-Thread操作系统(2)

目录

RT-Thread操作系统(2)

设备驱动

IO设备模型框架

PIN设备(控制LED灯)

软件包开发

DHT11的使用

自动初始化机制

串口

LCD

LVGL

连接阿里云和服务器


设备驱动

IO设备模型框架

-- RT-Thread 提供了一套简单的 I/O 设备模型框架,如下图所示,它位于硬件和应用程序之间,共分成三层,从上到下分别是 I/O 设备管理层、设备驱动框架层、设备驱动层。

alt text

应用程序通过 I/O 设备管理接口获得正确的设备驱动,然后通过这个设备驱动与底层 I/O 硬件设备进行数据(或控制)交互。

I/O 设备管理层实现了对设备驱动程序的封装**。应用程序通过图中的"I/O设备管理层"提供的标准接口访问底层设备,设备驱动程序的升级、更替不会对上层应用产生影响。这种方式使得设备的硬件操作相关的代码能够独立于应用程序而存在,双方只需关注各自的功能实现,

设备驱动框架层是对同类硬件设备驱动的抽象,将不同厂家的同类硬件设备驱动中相同的部分抽取出来,将不同部分留出接口,由驱动程序实现。

设备驱动层是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。它负责创建和注册 I/O 设备,对于操作逻辑简单的设备,可以不经过设备驱动框架层,直接将设备注册到 I/O 设备管理器中,使用序列图如下图所示,主要有以下 2 点:

设备驱动根据设备模型定义,创建出具备硬件访问能力的设备实例,将该设备通过 rt_device_register() 接口注册到 I/O 设备管理器中。

应用程序通过 rt_device_find() 接口查找到设备,然后使用 I/O 设备管理接口来访问硬件。

alt text

PIN设备(控制LED灯)

-- 首先来看pin设备(也就是GPIO)

alt text

  • 输入输出的模式

alt text

  • pin设备的管理接口

alt text

-- 参考例程:

alt text

#define LED2_PIN        GET_PIN(E,2)static rt_thread_t tid1 = RT_NULL;static void thread1_entry(void *parameter)
{rt_pin_mode(LED2_PIN, PIN_MODE_OUTPUT);for (; ; ){rt_pin_write(LED2_PIN, PIN_LOW);rt_thread_mdelay(500);rt_pin_write(LED2_PIN, PIN_HIGH);rt_thread_mdelay(500);}}int main(void)
{int count = 1;tid1 = rt_thread_create("thread1",thread1_entry, RT_NULL,512,25, 5);/* 如果获得线程控制块,启动这个线程 */if (tid1 != RT_NULL)rt_thread_startup(tid1);while (count++){LOG_D("Hello RT-Thread!");rt_thread_mdelay(1000);}return RT_EOK;
}

-- 效果:LED2 闪烁

软件包开发

  • 1、软件包的使用(会报错)
  • 2、有自动初始化机制(不用在主函数中调用)
  • 3、设备的注册,使用流程

DHT11的使用

alt text

-- 搜索DHT11软件包并添加

alt text

alt text

-- 添加过后,点击ctrl+s保存

alt text

-- 回到工程,就能看到DHT11软件包已经在工程中了

alt text

-- 更改DHT11的引脚,改成我们使用的开发板对应的原理图上的引脚

alt text

-- 并且要更改头文件

alt text

-- 我们可以看到DHT11的代码中有关于设备的操作

alt text

alt text

-- 我们可以看到工程中使用了自动初始化

alt text

-- 编译,下载,效果图

alt text

自动初始化机制

alt text

-- 这里为了更好的理解这个自动初始化,我们将本来写在main函数中的代码,写成一个函数,然后使用自动初始化的机制。

-- 在main函数下面写一个函数,将上面我们写过的线程创建和启动写在这个函数中,然后宏定义声明,这样就算我们不在main中调用,我们也可以执行。

-- 源代码:

int main(void)
{int count = 1;tid1 = rt_thread_create("thread1",thread1_entry, RT_NULL,512,25, 5);/* 如果获得线程控制块,启动这个线程 */if (tid1 != RT_NULL)rt_thread_startup(tid1);while (count++){LOG_D("Hello RT-Thread!");rt_thread_mdelay(1000);}return RT_EOK;
}

-- 更改为自动初始化后的代码


int main()
{while (count++){LOG_D("Hello RT-Thread!");rt_thread_mdelay(1000);}return RT_EOK;
}void aaa(void)
{tid1 = rt_thread_create("thread1",thread1_entry, RT_NULL,512,25, 5);/* 如果获得线程控制块,启动这个线程 */if (tid1 != RT_NULL)rt_thread_startup(tid1);
}
INIT_APP_EXPORT(aaa);

串口

-- 我们可以看到串口设备也是这几个函数

alt text

-- 1、查找设备

  • 用程序根据串口设备名称获取设备句柄,进而可以操作串口设备,查找设备函数如下所示,
rt_device_t rt_device_find(const char* name);

alt text

-- 2、打开设备

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

rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags);

alt text

  • oflags 参数支持下列取值 (可以采用或的方式支持多种取值):
#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 发送模式 */
  • 串口数据接收和发送数据的模式分为 3 种:中断模式、轮询模式、DMA 模式。在使用的时候,这 3 种模式只能选其一,若串口的打开参数 oflags 没有指定使用中断模式或者 DMA 模式,则默认使用轮询模式。

-- 3、控制串口设备

  • 通过控制接口,应用程序可以对串口设备进行配置,如波特率、数据位、校验位、接收缓冲区大小、停止位等参数的修改。控制函数如下所示:
rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg);

alt text

  • 控制参数结构体 struct serial_configure 原型如下
struct serial_configure
{rt_uint32_t baud_rate;            /* 波特率 */rt_uint32_t data_bits    :4;      /* 数据位 */rt_uint32_t stop_bits    :2;      /* 停止位 */rt_uint32_t parity       :2;      /* 奇偶校验位 */rt_uint32_t bit_order    :1;      /* 高位在前或者低位在前 */rt_uint32_t invert       :1;      /* 模式 */rt_uint32_t bufsz        :16;     /* 接收数据缓冲区大小 */rt_uint32_t reserved     :4;      /* 保留位 */
};

-- 4、串口设备使用实例

alt text

alt text

alt text

-- 可以查看默认的参数判断要不要更改参数

alt text

-- 这里没有写注册函数的原因是因为串口2在系统中就有,所以不用写

  • usart2222.c
/** Copyright (c) 2006-2021, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date           Author       Notes* 2024-11-04     皮某人       the first version*/
#include "USART2222.h"
#include <rtthread.h>
#include "board.h"
#include <rtdevice.h>/* 用于接收消息的信号量 */
static rt_device_t serial;
struct rt_semaphore rx_sem;/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{/* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */rt_sem_release(&rx_sem);return RT_EOK;
}struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;  /* 初始化配置参数 */static void serial_thread_entry(void *parameter)
{char ch[100];while (1){rt_sem_take(&rx_sem, RT_WAITING_FOREVER);/* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */while (rt_device_read(serial, 0, ch, 1)){/* 读取到的数据通过串口错位输出 */rt_device_write(serial, 0, &ch, 1);}// rt_device_write(serial, 0, ch, 1);// rt_thread_mdelay(10);}
}void api_usart2_init(void)
{serial = rt_device_find("uart2");/* 初始化信号量 */rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);/* step2:修改串口配置参数 */config.baud_rate = BAUD_RATE_9600;        //修改波特率为 9600config.data_bits = DATA_BITS_8;           //数据位 8config.stop_bits = STOP_BITS_1;           //停止位 1config.bufsz     = 128;                   //修改缓冲区 buff size 为 128config.parity    = PARITY_NONE;           //无奇偶校验位/* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);/* 以中断接收及轮询发送模式打开串口设备 */rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);/* 设置接收回调函数 */rt_device_set_rx_indicate(serial, uart_input);//rt_device_open(serial, RT_DEVICE_FLAG_STREAM);//流模式rt_device_write(serial, 0, "123456789",5);rt_thread_t thread = rt_thread_create("serial",serial_thread_entry, RT_NULL,512, 25, 10);if (thread != RT_NULL){rt_thread_startup(thread);}}
INIT_APP_EXPORT(api_usart2_init);

-- 编译,出现错误

alt text

-- 需要在board.h中宏定义串口2(系统默认只定义了串口1)

alt text

-- 查看线程状态

alt text

-- 这个串口2发送的状态需要外接一个串口转usb查看,否则无法查看,这个主要是学会如果创建新文件和一个设备是如何创建和使用的。


-- 在程序执行中如果出现错误,检查一下是不是头文件没有添加

alt text

LCD

-- 先将LCD的官方例程添加到工程中

alt text

-- 然后回到工程中点击”刷新“即可更新到工程中

alt text

-- 编译,出现错误

alt text

-- 点击错误信息,跳转到错误的代码中,发现是FSMC没有配置的问题

alt text

-- 找不到FSMC,但是我们知道他的本质是扩容

alt text

-- 再次编译,发现还有错误,需要将有关fsmc的代码,注释掉

alt text

-- 现在来看这个LCD的官方例程

  • 首先是注册设备

alt text

-- 然后是查找设备,设备初始化,之后开始应用设备

LVGL

-- 添加lcd的作用就是为了添加lvgl

-- 首先添加软件包,ctrl+s保存

alt text

-- 编译之后看有没有错误,如果还有错误,记得点亮

alt text

-- 后来就可以看到工程中有软件包的相关代码

alt text

alt text

alt text

alt text

连接阿里云和服务器

-- 打开软件包,保存

alt text

--

alt text

-- 还需要配置

  • 配置参数

alt text

alt text

alt text

alt text

-- 在board.h中添加usart3的宏定义(根据单片机的原理图)

alt text

-- 在main.c中添加引脚定义和执行函数

alt text

#include <rtthread.h>#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>#include <rtdevice.h>
#include <board.h>#define ESP_PIN         GET_PIN(E,6)int main(void)
{int count = 1;rt_pin_mode(ESP_PIN , PIN_MODE_OUTPUT);rt_pin_write(ESP_PIN , PIN_HIGH);while (count++){LOG_D("Hello RT-Thread!");rt_thread_mdelay(1000);}return RT_EOK;
}

 

-- 编译,出现显示检测不到指令的问题

alt text

-- 我们想知道设备是否连接成功,可以发送help获取指令,然后通过指令查看

alt text

alt text

-- 我们现在使用的是4.0.2版本,需要更改内核版本到4.1.1,就可以实现

-- 可以直接在当前工程中切换版本,但是会造成很多错误,因为在之前的版本加的软件包是契合之前那个版本的,所以最好是新建工程

alt text

-- 再次编译,我们这里因为加了lvgl,导致内粗过大,程序很可能会卡死,所以我们最好测试wiif的时候将lvgl的初始化代码注释掉

alt text

-- 安装新版本(4.1.1的芯片型号)

 -- 同样添加软件包,之后点击配置项

 

-- 填写阿里云的账号信息

 

-- 选择mqtt的例子

 -- 配置过后,保存,配置串口3的宏定义和在main.c中写调用代码,编译,就会连接上阿里云

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

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

相关文章

多线程--简单模拟实现线程池并使用--Java

一、序言 阅读这篇博客之前建议先读多线程--线程池概念以及使用--Java-CSDN博客&#xff0c;里面有对线程池的详细介绍&#xff0c;这边就不过多赘述。 二、模拟实现固定线程数目的线程池 通过对线程池的理解&#xff0c;我们了解到线程池将我们需要执行的任务Runnable放在阻…

bert-base-chinese模型使用教程

向量编码和向量相似度展示 import torch from transformers import BertTokenizer, BertModel import numpy as npmodel_name "C:/Users/Administrator.DESKTOP-TPJL4TC/.cache/modelscope/hub/tiansz/bert-base-chinese"sentences [春眠不觉晓, 大梦谁先觉, 浓睡…

mutable用法

mutable 关键字用于允许类的某个成员变量在 const 成员函数中被修改。通常&#xff0c;const 成员函数不能改变对象的任何成员变量&#xff0c;但将成员变量声明为 mutable 可以例外 class Hero { public:Hero():m_Hp(0), m_getHpCounter(0){}int getHp() const {m_getHpCounte…

map和set和pair

目录 一.序列式容器和关联式容器 一.set set类的介绍&#xff1a; Construct &#xff1a;set的初始化 insert&#xff1a;插入 ​编辑find&#xff1a;查找 erase&#xff1a;删除 set查找范围的函数&#xff1a;​编辑 二.map 2.1map介绍 2.2pair类型介绍 在map的i…

BEV数据集标注成本高?BEVPose:减少对标注数据依赖!

引言 本文提出了一个名为BEVPose的框架&#xff0c;通过利用自监督和传感器位姿信息&#xff0c;实现相机和激光雷达数据的多模态BEV表示对齐&#xff0c;显著减少了对标注数据的依赖。BEVPose在BEV地图分割任务中表现出色&#xff0c;能够超越全监督的方法&#xff0c;同时提升…

AI - 使用LangChain构建简单LLM应用程序

AI - 使用LangChain构建简单LLM应用程序 什么是LLM LLM&#xff08;Large Language Model&#xff0c;大型语言模型&#xff09;是一种由大量文本数据训练而成的深度学习模型&#xff0c;能够理解和生成自然语言。例如&#xff0c;GPT-3就是一种流行的LLM&#xff0c;可以用于…

linux shell脚本学习(1):shell脚本基本概念与操作

1.什么是shell脚本 linux系统中&#xff0c;shell脚本或称之为bash shell程序&#xff0c;通常是由vim编辑&#xff0c;由linux命令、bash shell指令、逻辑控制语句、注释信息组成的可执行文件 *linux中常以.sh后缀作为shell脚本的后缀。linux系统中文件乃至脚本的后缀并没有…

Linux云计算 |【第五阶段】CLOUD-DAY6

主要内容&#xff1a; 了解Kubernetes的架构、搭建Kubernetes集群 一、Kubernetes 概述 Kubernetes 这个名字来自希腊语&#xff0c;意思是“舵手”或“领航员”&#xff1b;K8S 是 Kubernetes 的缩写&#xff0c;其中“8”代表字母“ubernete”中的8个字母。Kubernetes 是由…

无人机之中继通信技术篇

一、定义与原理 无人机中继通信技术是指通过无人机搭载中继设备&#xff0c;将信号从一个地点传输到另一个地点&#xff0c;从而延长通信距离并保持较好的通信质量。其原理类似于传统的中继通信&#xff0c;即在两个终端站之间设置若干中继站&#xff0c;中继站将前站送来的信号…

【深度学习基础】深入理解 卷积与卷积核

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 卷积 1.1 …

数字身份发展趋势前瞻:身份韧性与安全

身份韧性与安全是身份与访问管理IAM发展的重要趋势&#xff0c;身份既是防御者的盾牌&#xff0c;也是攻击者的目标。面对日益复杂的网络威胁和不断增长的身份盗窃风险&#xff0c;身份韧性与安全不仅仅涉及产品的防御能力&#xff0c;还包括应对突发事件、快速恢复的弹性和灵活…

QChart中柱形图的简单使用并实现【Qt】

预备工作 如果qt没下载去下载一个&#xff0c;下载太慢了可以试试它[点击跳转]  (https://blog.csdn.net/qq_19319481/article/details/131655379)。   如果已经下载了qt发现自己的组件中没有QCharts&#xff0c;可以去试试它点击跳转。 都搞定了以后在pro文件里面添加QT …

智能语音机器人智能在哪里?AI人工智能电话机器人部署

随着科技的不断进步&#xff0c;人工智能已经成为了我们生活中不可或缺的一部分。AI人工智能机器人电话正是其中的一种形式&#xff0c;可以帮助企业或组织更好地实现电话营销的目标&#xff0c;那么智能语音机器人智能在哪里?我们来看看&#xff1a; 智能语音机器人&#xf…

UI自动化测试 —— CSS元素定位实践!

前言 自动化测试元素定位是指在自动化测试过程中&#xff0c;通过特定的方法或策略来准确识别和定位页面上的元素&#xff0c;以便对这些元素进行进一步的操作或断言。这些元素可以是文本框、按钮、链接、图片等HTML页面上的任何可见或不可见的组件。 在自动化测试中&#xf…

Unity 使用Netcode实现用户登录和登出

Unity之NetCode for GameObjets 基本使用 说明思路相关API代码实现Tips 说明 最近项目需要联机&#xff0c;项目方案选用Unity提供的NetCode for GameObjets&#xff08;以下简称NGO&#xff09;&#xff0c;踩了不少坑&#xff0c;本文不介绍基础使用&#xff0c;围绕双端&…

专业网页设计服务重要是什么

当在搜索引擎中键入“网页设计”&#xff0c;您将获得超过2000万个相关结果。在如此众多的网站制作公司中&#xff0c;应该如何做出明智的选择呢&#xff1f;首先&#xff0c;让我们深入探讨一下网页设计的重要性。网站设计需要综合各种不同领域的专业知识&#xff0c;它是一个…

【UART异步串口协议及verilog实现】

UART异步串口协议 1 UART1.1 数据格式1.2 波特率 2 UART的发送和接收模块2.1 uart发送模块2.2 uart的接收模块 【博客首发于微信公众号《 漫谈芯片与编程》】 本篇文章介绍常用的芯片外围低速协议&#xff1a;UART&#xff1b; 1 UART UART是异步串行传输协议&#xff0c;即…

彻底解决idea不识别java项目

需求背景 下载了一个java swing的项目,通过idea导入后,项目无法识别。打开java文件,也不会报错,也不编译。 无法识别效果图 可以看到左侧的菜单,项目是没有被识别。 打开java文件,可以看到没有识别,java的图标也没有出现。 解决方法 1、打开Project Structure 2、修改…

仿真APP助力汽车零部件厂商打造核心竞争力

汽车零部件是汽车工业的基石&#xff0c;是构成车辆的基础元素。一辆汽车通常由上万件零部件组成&#xff0c;包括发动机系统、传动系统、制动系统、电子控制系统等&#xff0c;它们共同确保了汽车的安全、可靠性及高效运行。 在汽车产业快速发展的今天&#xff0c;汽车零部件…

【Nginx】前端项目开启 Gzip 压缩大幅提高页面加载速度

背景 Gzip 是一种文件压缩算法&#xff0c;减少文件大小&#xff0c;节省带宽从而提减少网络传输时间&#xff0c;网站会更快更丝滑。 // nginx roothcss-ecs-1d22:/etc/nginx# nginx -v nginx version: nginx/1.24.0// node ndde v18.20.1// dependencies "vue": …