RT-Thread学习

RT-Thread三个版本——标准版本

RT-Thread,全称是Real Time-Thread,顾名思义,它是一个嵌入式实时多线程操作系统,基本属性之一是支持多任务:一个处理器核心在某一时刻只能运行一个任务,由于每次对一个任务的执行时间很短,任务与任务之间通过任务调度器进行非常快速地切换。

RT-Thread系统中,任务是通过线程实现的,RT-Thread中的线程调度器也就是以上提到的任务调度器。

RT-Thread主要采用C语言编写,浅显易懂,方便移植。
它把面向对象的设计方法应用到实时系统设计中,使得代码风格优雅、架构清晰、系统模块化并且可裁剪性非常好

针对资源受限的微控制器(MCU)系统,可通过方便易用的工具,裁剪出仅需要3KB Flash、1.2KB RAM内存资源的NANO版本(NANO版本是RT-Thread官方于2017年7月份发布的一个极简版内核)。

而对于资源丰富的物联网设备,RT-Thread又能使用在线的软件包管理工具,配合系统配置工具,实现直观快速地模块化裁剪,无缝地导入丰富的软件功能包,实现类似Android的图形界面及触摸滑动效果、智能语音交互效果等复杂功能。

相较于Linux操作系统,RT-Thread体积小,成本低,功耗低,启动快速,除此以外RT-Thread还具有实时性高、占用资源小等特点,非常适用于各种资源受限(如成本、功耗限制等)的场合。

虽然32位MCU是它的主要运行平台,实际上很多带有MMU、基于ARM9、ARM11的甚至Cortex-A系列级别CPU的应用处理器在特定应用场合也适合使用RT-Thread。

NANO版本是标准版本的极简内核版本,SMART版本是在标准版本上增加了用户态创造而来,所以学习标准版本是学习RT-Thread的基础。

Env工具:Env工具用于对源码功能进行配置或裁剪,可以生成MDK/IAR/GCC工程,需要配合使用。

RT-Thread简介

RT-Thread是一款完全由国内团队开发维护的嵌入式实时操作系统,具有完全的自主知识产权。经过16个年头的沉淀,伴随着物联网的兴起,它正演变成一个功能强大、组件丰富的物联网操作系统。

RT-Thread的架构

近年来,物联网(Internet Of Things,IoT)概念广为普及,物联网市场发展迅猛,嵌入式设备的联网已是大势所趋。
物联网操作系统是指以操作系统内核为基础,包括如文件系统、图形库等较为完整的中间件组件,具备低功耗、安全、通信协议支持和云端连接能力的软件平台,RT-Thread就是一个IoT OS。

RT-Thread与其他很多RTOS如FreeRTOS主要区别之一是,它不仅仅是一个实时内核,还具备丰富的中间层组件
在这里插入图片描述

  • 内核层:RT-Thread内核,包括了内核系统中对象的实现,例如多线程及其调度、信号量、邮箱、消息队列、内存管理、定时器等。libcpu/BSP(芯片移植相关文件/板级支持包)与硬件密切相关,由外设驱动和CPU移植构成。
  • 组件与服务层:组件是基于RT-Thread内核之上的上层软件,例如虚拟文件系统、FinSH命令行界面、网络框架、设备框架等。采用模块化设计,做到组件内部高内聚,组件之间低耦合。
  • RT-Thread软件包:运行于RT-Thread物联网操作系统平台上,面向不同应用领域的通用软件组件,由描述信息、源代码或库文件组成。开放的软件包平台,存放了官方提供或开发者提供的软件包,这也是生态的重要组成部分。
    生态对于一个操作系统的选择至关重要,因为这些软件包具有很强的可重用性,模块化程度很高,极大的方便应用开发者在最短时间内,打造出自己想要的系统。

内核基础

从软件架构入手讲解实时内核的组成与实现,内核的组成部分,系统如何启动,内存分布情况以及内核配置方法。

RT-Thread内核介绍

内核是一个操作系统核心,负责管理系统的线程、线程间通信、系统时钟、中断及内存等。
在这里插入图片描述
内核处于硬件层之上,内核部分包括内核库、实时内核实现。
内核库是为了保证内核能够独立运行的一套小型的类似C库的函数实现子集。这部分根据编译器的不同自带C库的情况会有些不同,当使用GNU GCC编译器时,会携带更多的标准C库实现。

C库:也叫C运行库,它提供了类似strcpy、memcpy等函数,有些也会包括printf、scanf函数的实现。内核库仅提供内核用到的一小部分C库函数实现,为了避免与标准C库重名,这些函数前面会添加rt_前缀。

线程管理

线程是RT-Thread操作系统中最小的调度单位,线程调度算法是基于优先级的全抢占式多线程调度算法,即在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占之外,系统的其它部分是可以抢占的,包括线程调度器自身。

支持256个线程优先级(也可以通过配置文件更改为最大支持32个或8个线程优先级,针对STM32默认配置是32个线程优先级),0优先级代表最高优先级,最低优先级留给空闲线程使用;同时它也支持创建多个具有相同优先级的线程,相同优先级的线程采用时间片的轮转调度算法进行调度,使每个线程运行相应时间;另外调度器在寻找那些处于就绪状态的具有最高优先级的线程时,所经历的时间是恒定的系统也不限制线程数量的多少,线程数目只和硬件平台的具体内存相关。

时钟管理

RT-Thread的时钟管理以时钟节拍为基础,时钟节拍是RT-Thread操作系统中最小的时钟单位。
RT-Thread的定时器提供两类定时器机制:第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动停止。
第二类是周期触发定时器,这类定时器会周期性地触发定时器事件,直到用户手动的停止定时器否则将永远持续执行下去。

另外,根据超时函数执行时所处的上下文环境,RT-Thread的定时器可以设置为HARD_TIMER模式或者SOFT_TIMER模式。

通常使用定时器定时回调函数(即超时函数),完成定时服务。用户根据自己对定时处理的实时性要求选择合适类型的定时器。

线程间同步

RT-Thread采用信号量、互斥量与事件集实现线程间同步。
线程通过对信号量、互斥量的获取与释放进行同步;互斥量采用优先级继承的方式解决了实时系统常见的优先级翻转问题。
线程同步机制支持线程按优先级等待方式获取信号量或互斥量。
线程通过对事件的发送与接收进行同步。
事件集支持多事件的或触发和与触发,适合于线程等待多个事件的情况。

线程间通信

RT-Thread支持邮箱和消息队列等通信机制。
邮箱中一封邮件的长度固定为4字节大小;消息队列能够接收不固定长度的消息,并把消息缓存在自己的内存空间中。
邮箱效率较消息队列更为高效。
邮箱和消息队列的发送动作可安全用于中断服务例程中。
通信机制支持线程按优先级等待方式获取。

内存管理

RT-Thread支持静态内存池管理及动态内存堆管理。
当静态内存池具有可用内存时,系统对内存块分配的时间将是恒定的;当静态内存池为空时,系统将申请内存块的线程挂起或阻塞掉(即线程等待一段时间后仍未获得内存块就放弃申请并返回,或者立刻返回。等待的时间取决于申请内存块时设置的等待时间参数),当其它线程释放内存块到内存池时,如果有挂起的待分配内存块的线程存在的话,则系统会将这个线程唤醒。

动态内存堆管理模块在系统资源不同的情况下,分别提供了面向小内存系统的内存管理算法以及面向大内存系统的SLAB内存管理算法。

还有一种动态内存堆管理叫做memheap,适用于系统含有多个地址且不连续的内存堆。使用memheap可以将多个内存堆“粘贴”在一起,让用户操作起来像是在操作一个内存堆。

I/O设备管理

RT-Thread将PIN、IIC、SPI、UART等作为外设设备,统一通过设备注册完成。
实现了按名称访问的设备管理子系统,可按照统一的API界面访问硬件设备。
在设备驱动接口上,根据嵌入式系统的特点,对不同的设备挂接相应的事件。当设备事件触发时,由驱动程序通知给上层的应用程序。

RT-Thread启动流程

RTT支持多种平台和多种编译器,而rtthread_startup()函数是RTT规定的统一启动入口。
执行顺序是:系统先从启动文件开始运行,然后进入RTT的启动函数rtthread_startup(),最后进入用户入口函数main()。

在这里插入图片描述
以MDK-ARM为例,用户程序入口为main()函数,位于main.c文件中。
系统启动后先从汇编代码开始运行,然后跳转到C代码,然后跳转到C代码,进行RTT系统启动,最后进入用户程序入口函数main()。

为了在进入main()之前完成RTT系统功能初始化,我们使用了MDK的扩展功能 S u b Sub Sub$ 和 S u p e r Super Super$。

s u b sub sub m a i n 先调用一些补充在 m a i n 之前的功能函数,再调用 main先调用一些补充在main之前的功能函数,再调用 main先调用一些补充在main之前的功能函数,再调用super$$main转到main()函数执行,这样可以让用户不用去管main()之前的系统初始化操作。

在components.c中定义了这段代码:

int $Sub$$main(void){rtthread_startup();return 0;
}
int rtthread_startup(void){rt_hw_interrupt_disable();/*板级初始化:需要在该函数内部进行系统堆的初始化*/rt_board_init();/*定时器初始化*/rt_system_timer_init();/*调度器初始化*/rt_system_scheduler_init();/*用户创建一个main线程*/rt_application_init();/*定时器线程初始化*/rt_system_timer_thread_init();/*空闲线程初始化*/rt_thread_idle_init();/*启动调度器*/rt_system_scheduler_start();/*不会执行至此*/return 0;
}

这部分启动代码,大致可以分为四个部分:

  1. 初始化与系统相关的硬件;
  2. 初始化系统内核对象,例如定时器、调度器、信号;
  3. 创建main线程,在main线程中对各类模块依次进行初始化;
  4. 初始化定时器线程、空闲线程,并启动调度器。

启动调度器之前,系统所创建的线程在执行rt_thread_startup()后并不会立马运行,它们会处于就绪状态等待系统调度;待启动调度器之后,系统才转入第一个线程开始运行,根据调度规则,选择的是就绪队列中优先级最高的线程。

rt_hw_board_init()中完成系统时钟设置,为系统提供心跳,串口初始化,将系统输入输出终端绑定到这个串口,后续系统运行信息就会从串口打印出来。

main() 函数是 RT-Thread 的用户代码入口,用户可以在 main() 函数里添加自己的应用。

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

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

相关文章

HCIP【ospf综合实验】

目录 实验要求: 实验拓扑图: 实验思路: 实验步骤: 一、划分网段 二、配置IP地址 三、搞通私网和公网 (1)先搞通私网(基于OSPF协议,在各个路由器上进行网段的宣告&#xff0c…

实现智能水控 | 基于ACM32 MCU的分体式水控方案

分体式水控概述 分体式水控是一种常见的水控系统,它的工作原理是通过水的流动来控制水的供应和排放,该系统一般由两部分组成:控制器和水阀。控制器负责监测水的流量和压力,根据设定的参数来控制水阀的开和关,从而实现水…

2024认证杯数学建模A题保暖纤维保暖能力原创论文讲解(含完整python代码)

大家好呀,从发布赛题一直到现在,总算完成了认证杯数学中国数学建模网络挑战赛第一阶段A题目保暖纤维的保暖能力完整的成品论文。 本论文可以保证原创,保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成品…

windows下vscode调试虚拟机linux c++工程的三种方法

vscode去远程调试方法有很多种,不同的插件对应了不同的调试方法,比如: 1.C/C插件进行GDB调试(编写launch.json文件) 2.C/C Runner插件 3.CMake Tools插件(只针对CMake工程,需要搭配C/C插件一起使用,但无…

Gin框架小结

Gin 简介 Gin是一个轻量级的Web框架,用于构建高性能的Go语言Web应用程序。提供了路由管理、中间件支持、参数绑定和验证、错误处理、静态文件服务等功能。 Gin框架解决了什么问题和痛点 1.golang http 标准库本身提供了比较简单的路由注册能力,只支持…

记录一次内存溢出

1、查看catalina相关日志,确定关键字相关行号 文件:catalina.out命令1:cat -n catalina.out |grep -a OutOfMemoryError与内存溢出相关的如上,每一个行号其实都对应到具体时间点。可以发现,这个范围相符合&#xff1…

清明三天,用Python赚了4万?

每年4月,是Python圈子里接私活的旺季,特别是在节假日这种数据暴增的时间段,爬虫采集、逆向破解类的私活订单会集中爆发,量大价高。几乎所有的圈内人都在趁着旺季接私活。 正好,我昨天就做了一单爬虫逆向私活&#xff…

引领软件供应链安全 比瓴科技位居安全牛全景图第一

近日,安全牛第十一版《中国网络安全行业全景图》正式发布,比瓴科技入选全景图软件供应链安全赛道中开发流程安全管理、DevSecOps和软件成分分析三个重要细分领域,并位居开发流程安全管控领域第一。 安全牛本次全景图研究工作于23年正式启动&a…

什么是云安全?云安全包含哪些方面?

云计算彻底改变了数据存储的世界,它使企业可以远程存储数据并随时随地从任何位置访问数据。存和取变得简单,也使得云上数据极易造成泄露或者被篡改,所以云安全就显得非常重要了。那么什么是云安全?云安全的工作原理是什么&#xf…

做一个好的程序员难吗?只需要这10个习惯

在这个世界上,有数以百万计的人对软件开发充满热情,他们有很多名字,如软件工程师、程序员、编码员、开发人员。一段时间后,这些人可能会成为一名优秀的编码员,并且他们将非常熟悉如何使用计算机语言完成工作。但是&…

EasyRecovery激活秘钥2024最好用的电脑数据恢复软件下载

EasyRecovery数据恢复软件是一款专业且功能强大的数据恢复工具,它旨在帮助用户从各种存储设备中恢复由于各种原因(如误删除、格式化、病毒攻击、系统崩溃等)导致丢失的数据。这款软件支持多种存储介质,包括但不限于硬盘驱动器、U盘…

0.5W 3KVDC 隔离 单输出 DC/DC 电源模块 ——TPR-W5 系列

TPR-W5系列是一款需要隔离和电压转换的产品,工业级环境温度,温度范围从–40℃到105℃,用于PCB安装的国际标准结构。此系列产品小巧,效率高,低输出纹波及提供3000V以上的直流电压隔离,用于需要隔离的场合&am…

【Spring系列】- Spring事务底层原理

实验准备 配置文件 首先在配置文件中配置jdbcTemplate和事务管理器,并且需要开启事务的注解EnableTransactionManagement以及Configuration注解 ComponentScan("com.lyd") EnableTransactionManagement Configuration public class ApplicationConfig …

[入门]测试原则-ApiHug准备-测试篇-002

🤗 ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱,有温度,有质量,有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace 写在前面…

低敏猫粮怎么选?看这一篇就够了!

亲爱的朋友们,你们是否曾经为了家中敏感肠胃的小猫咪而犯愁,不知道如何选择适合的猫粮呢?今天,就让我们一起聊聊低敏猫粮与普通猫粮的那些不同之处吧!🐱 1️⃣ **成分差异**:首先,从…

Go 自定义14位时间类型 yyyyMMddHHmmss

目录 功能 代码 功能 数据库或者接口时间类型,经常会使用14位的时间格式。每次都转换有点麻烦。可以自定义一个时间类型。 自定义类型需要实现json接口中的MarshalJSON与UnmarshalJSON两个函数,这样在做json编码解码时就会自动转为14位的时间格式了。…

第四届大数据工程与教育国际会议(BDEE 2024)即将召开!

第四届大数据工程与教育国际会议(BDEE 2024)将于2024年8月9-11日在泰国清迈举行。数据驱动教育变革,智慧点亮未来课堂!BDEE 2024是专注于大数据工程与教育领域的重要学术会议,全球大数据与教育精英齐聚,在数…

使用 Docker 部署 SurveyKing 调查问卷系统

1)SurveyKing 介绍 SurveyKing 是一款功能强大、操作简便的开源问卷系统。它不仅满足了用户对问卷调查的基本需求,还提供了丰富的逻辑设置和灵活的问题设置,使得问卷制作更加智能化和个性化。此外,SurveyKing 还具有快速部署和安全…

构建鸿蒙ACE静态库

搭建开发环境 根据说明文档下载鸿蒙全部代码,一般采取第四种方式获取最新代码(请保证代码为最新) 源码获取Windows下载编译环境 MinGW GCC 7.3.0版本 请添加环境变量IDE 可以使用两种 CLion和Qt,CLion不带有环境需要安装MinGW才可以开发,Qt自带MinGW环境&#xff0…

认识一下RAG

1.RAG技术背景与挑战 2.RAG的核心概念 3.RAG的工作流程与架构 4.RAG的优化方法 RAG的提出 •Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks是一篇重要的论文(2020年5月) •REALM: Retrieval-Augmented Language Model Pre-Training (2020)就将BERT预训练模…