RTT 内核基础学习

RT-Thread 内核介绍

内核是操作系统的核心,负责管理系统的线程、线程间通信、系统时钟、中断以及内存等。

在这里插入图片描述
内核位于硬件层之上,内核部分包括内核库、实时内核实现。

内核库是为了保证内核能够独立运行的一套小型的类似C库的函数实现子集。
这部分根据编译器的不同自带C库的情况也会有些不同,当使用GNU GCC编译器时,会携带更多的标准C库实现。

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

内核最小的资源占用情况是 3KB ROM,1.2KB RAM。

线程调度

线程是RT-Thread操作系统中最小的调度单位,线程调度算法是基于优先级的全抢占式调度算法,即在系统中除了中断处理函数、调度器上锁部分的代码和禁止中断的代码是不可抢占的之外,系统其它部分都可以抢占,包括线程调度器自身。支持 256 个线程优先级(也可通过配置文件更改为最大支持 32 个或 8 个线程优先级,针对 STM32 默认配置是 32 个线程优先级),0 优先级代表最高优先级,最低优先级留给空闲线程使用;同时它也支持创建多个具有相同优先级的线程,相同优先级的线程间采用时间片的轮转调度算法进行调度,使每个线程运行相应时间;另外调度器在寻找那些处于就绪状态的具有最高优先级的线程时,所经历的时间是恒定的,系统也不限制线程数量的多少,线程数目只和硬件平台的具体内存相关。

时钟管理

RT-Thread的时钟管理以时钟节拍为基础,时钟节拍是RTT操作系统中最小的时钟单位。

RT-Thread 的定时器提供两类定时器机制:第一类是单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动停止。第二类是周期触发定时器,这类定时器会周期性的触发定时器事件,直到用户手动的停止定时器否则将永远持续执行下去。

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

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

线程间同步

RT-Thread 采用信号量、互斥量与事件集实现线程间同步。线程通过对信号量、互斥量的获取与释放进行同步;互斥量采用优先级继承的方式解决了实时系统常见的优先级翻转问题。

线程同步机制支持线程按优先级等待方式获取信号量或互斥量。线程通过对事件的发送与接收进行同步;

事件集支持多事件的 “或触发” 和“与触发”,适合于线程等待多个事件的情况。

线程间通信

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

RT-Thread启动流程

一般了解一份代码大多从启动部分开始,同样这里也采用这种方式,先寻找启动的源头。

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

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

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

在main函数前加上这个前缀,可以先调用一些补偿在main之前的功能函数。

在汇编代码内调用了启动文件rtthread_startup()函数,

int rtthread_startup(void){
	rt_hw_interrupt_disable();

	/* 板级初始化,需要在该函数内部进行系统堆的初始化 */
	rt_hw_board_init();

	/* 定时器初始化 */
	rt_system_timer_init();

	/* 调度器初始化 */
	rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
    /* 信号初始化 */
    rt_system_signal_init();
#endif	

	/* 创建一个用户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()中完成系统时钟设置,为系统提供心跳,串口初始化,将系统输入输出终端绑定到这个串口,后续系统运行信息就会从串口打印出来。

RT-Thread程序内存分布

一般MCU包含的存储空间有:片内Flash与片内RAM,RAM相当于内存,Flash相当于硬盘。

编译器会将一个程序分类为好几个部分,分别存储在MCU不同的存储区。

Keil工程在编译完之后,会有相应的程序所占用的空间提示消息。

linking...
Program Size: Code=48008 RO-data=5660 RW-data=604 ZI-data=2124
After Build - User command \#1: fromelf --bin.\\build\\rtthread-stm32.axf--output rtthread.bin
".\\build\\rtthread-stm32.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:07

上面提到的program size包含:

  1. Code:代码段,存放程序的代码部分;
  2. RO-data:只读数据段,存放程序中定义的常量;
  3. RW-data:读写数据段,存放初始化为非零值的全局变量;
  4. ZI-data:0数据段,存放未初始化的全局变量以及初始化为0的变量。

编译完工程会生成一个.map文件,该文件说明了各个函数占用的尺寸和地址,在文件的最后几行也说明了上面几个字段的关系:

在这里插入图片描述

  1. RO Size包含了Code以及RO-data,表示程序占用Flash空间的大小。
  2. RW Size包含了RW-data以及ZI-data,表示运行时占用的RAM的大小。
  3. ROM Size包含了Code、RO-data以及RW-data,表示程序烧写时所占用的Flash空间大小。

程序运行之前,需要有文件实体被烧录到STM32的Flash中,一般是bin或者hex文件,该被烧录文件称为可执行映像文件。

在这里插入图片描述
STM32上电之后默认从Flash启动,会将RW段中的RW-data搬运到RA中,但不会搬运RO段,即CPU的执行代码从Flash中读取,另外根据编译器给出的ZI地址和大小分配出ZI段,并将这块RAM区域清零。

其中动态内存堆为未使用的RAM空间,应用程序申请和释放的内存块都来自该空间。

RT-Thread内核对象模型

RT-Thread内核采用面向对象的设计思想进行设计,系统级的基础设施都是一种内核对象,如线程,信号量,互斥量,定时器等。
内核对象分为两类:静态内核对象放在RW段和ZI段中,在系统启动后在程序中初始化;动态内核对象则是从内存堆中创建的,而后手工做初始化。

thread1对象的内存空间,包括线程控制块thread1与栈空间thread1_stack都是编译时决定的。

内核对象管理架构

RTT采用内核对象管理系统来访问/管理所有内核对象,内核对象包含了内核中绝大部分设施,这些内核对象可以是静态的也可以是动态的。

RTT内核对象包括:线程、信号量、互斥量等。
对象容器包含了每类内核对象的信息,包括对象类型、大小等。
对象容器给每类内核对象分配了一个链表,所有的内核对象都被链接到该链表上。

在这里插入图片描述
下图显示了RTT各类内核对象的派生和继承关系。
在这里插入图片描述
对于每一种具体内核对象和对象控制块,除了基本结构外,还有自己的扩展属性(私有属性),例如,对于线程控制块,在基类对象上进行扩展,增加了线程状态、优先级等属性。

内核对象管理方式

内核对象容器的数据结构:

struct rt_object_information{
	enum rt_object_class_type type;
	rt_list_t object_list;
	rt_size_t object_size;
};

一类对象由一个rt_object_information结构体来管理,每一个这类对象的具体实例都通过链表的形式挂接在object_list上。
而这一类对象的内存块尺寸由object_size标识出来(每一类对象的具体实例,它们占用的内存块大小是相同的)。

初始化对象

在使用一个未初始化的静态对象前必须先对其进行初始化。

void rt_object_init(struct rt_object* object, enum rt_object_class_type  type ,
                    const char* name)

遍历所有线程

rt_thread_t thread = RT_NULL;

struct rt_list_node *node = RT_NULL;
struct rt_object_information *information = RT_NULL;

information = rt_object_get_information(RT_Object_Class_Thread);

rt_list_for_each(node, &(information->object_list))
{
	thread = (rt_thread_t)rt_list_entery(node, struct object, list);
	rt_kprintf("name:%s\n", thread->name);
}

RT-Thread

RT-Thread的一个重要特性是高度可裁剪性,支持对内核进行精细调整,对组件进行灵活拆卸。

配置主要是通过修改工程目录下的rtconfig.h文件来进行,用户可以通过打开/关闭该文件中的宏定义来对代码进行条件编译,最终达到系统配置和裁剪的目的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

qt QPixmapCache详解

1、概述 QPixmapCache是Qt框架中提供的一个功能强大的图像缓存管理工具类。它允许开发者在全局范围内缓存QPixmap对象,从而有效减少图像的重复加载,提高图像加载和显示的效率。这对于需要频繁加载和显示图像的用户界面应用来说尤为重要,能够…

纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码

一、纯css制作声波扩散动画 参考文章&#xff1a;纯css制作声波扩散动画 播放效果通过音频状态来控制 效果如下 完整代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>波纹动画特效…

CocosCreator 构建透明背景应用(最新版!!!)

文章目录 透明原理补充设置截图以及代码step1: electron-js mian.jsstep2:ENABLE_TRANSPARENT_CANVASstep3:SOLID_COLOR Transparentstep:4 Build Web phonestep5:package electron-js & change body background-color 效果图补充 透明原理 使用Cocos creator 做桌面应用开…

在数据抓取的时候,短效IP比长效IP有哪些优势?

在数据抓取领域&#xff0c;代理IP的选择对于任务的成功率和效率至关重要。短效IP和长效IP各有其特点和适用场景&#xff0c;但在数据抓取过程中&#xff0c;短效IP因其独特的优势而受到青睐。本文将和大家一起探讨短效IP在数据抓取中相比长效IP的优势。 短效IP的定义与特点 …

FTP文件传输操作步骤

FTP文件传输操作步骤 步骤一&#xff1a;运行FTPServer.exe程序 步骤二、设置用户名和密码密码 步骤三、设置共享文件夹 步骤五、点击启动 步骤六、查看电脑ip(FTP server端) 步骤七、连接FTP 此电脑&#xff0c;地址栏输入&#xff1a;ftp://192.168.1.100 回车即可&…

【react使用AES对称加密的实现】

react使用AES对称加密的实现 前言使用CryptoJS库密钥存放加密方法解密方法结语 前言 项目中要求敏感信息怕被抓包泄密必须进行加密传输处理&#xff0c;普通的md5加密虽然能解决传输问题&#xff0c;但是项目中有权限的用户是需要查看数据进行查询的&#xff0c;所以就不能直接…

【网络原理】关于HTTP状态码以及请求的构造的哪些事

前言 &#x1f31f;&#x1f31f;本期讲解关于HTTP协议的重要的机制~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不…

苹果发布iOS 18.2首个公测版:Siri接入ChatGPT、iPhone 16拍照按钮有用了

今天凌晨&#xff0c;苹果正式发布了iOS 18.2首个公测版&#xff0c;将更多AI功能大批量推送给用户。其中最重要的就是Siri接入ChatGPT了&#xff0c;用户不必创建账户就可以免费使用ChatGPT&#xff0c;Siri将利用ChatGPT的专业知识回答用户问题&#xff0c;并在查询之前征求用…

前端 Canvas 绘画 总结

目录 一、使用案例 1、基础使用案例 2、基本案例改为直接JS实现 二、相关资料 1、API教程文档 2、炫酷案例 一、使用案例 1、基础使用案例 使用Canvas的基本步骤&#xff1a; 1、需要一个canvas标签 2、需要获取 画笔 对象 3、使用canvas提供的api进行绘图 <!--…

高级 <HarmonyOS主题课>借助AR引擎帮助应用实现虚拟与现实交互的能力的课后习题

持而盈之&#xff0c;不如其已&#xff1b; 揣而锐之&#xff0c;不可长保。 金玉满堂&#xff0c;莫之能守&#xff1b; 富贵而骄&#xff0c;自遗其咎。 功成身退&#xff0c;天之道也。 VR (Virtual Reality): 虚拟现实技术 AR (Augmented Reality): 增强现实) XR.(Extend…

tp接口 入口文件 500 错误原因

一、描述 二、可能的原因 1、runtime目录没权限 2、关闭了Tp记录日志的功能 3、关闭debug调试模式 4、关闭了debug模式还是报错 一、描述 Thinkphp项目本地正常&#xff0c;上传到线上后静态文件访问正常&#xff0c;访问tp接口报500错误。 经调试发现&#xff0c;在php入…

解决:ros进行gazebo仿真,rviz没有显示传感器数据

目录 前言解决总结 前言 看了很多urdf、xacro文件的编写&#xff0c;每次看了都觉得自己会了&#xff0c;然后自己写一点&#xff0c;就是废物了。 在我这里的案例是&#xff0c;我在一个大方块上面&#xff0c;添加了两个VLP-16的雷达&#xff0c;然后我想获取雷达扫描的数据…

C语言 | Leetcode C语言题解之第546题移除盒子

题目&#xff1a; 题解&#xff1a; int dp[100][100][100];int calculatePoints(int* boxes, int l, int r, int k) {if (l > r) {return 0;}if (dp[l][r][k] 0) {int r1 r, k1 k;while (r1 > l && boxes[r1] boxes[r1 - 1]) {r1--;k1;}dp[l][r][k] calcu…

基于开源 AI 智能名片、S2B2C 商城小程序的用户获取成本优化分析

摘要&#xff1a;本文围绕用户获取成本&#xff08;CAC&#xff09;这一关键指标展开深入剖析&#xff0c;详细阐述其计算方式&#xff0c;并紧密结合开源 AI 智能名片与 S2B2C 商城小程序的独特性质&#xff0c;从多个维度探讨如何通过挖掘新的获客渠道、巧妙运用私域流量池等…

实践出真知:MVEL表达式中for循环的坑

目录标题 背景MVEL脚本(有问题的)MVEL脚本(正确的)结论分析 背景 需要从一个URL的拼接参数中解析出id的值并输出 比如&#xff1a; 存在URLhttps://xxxxxxxxxx?id999999&type123&name345 然后需要输出id999999 MVEL脚本(有问题的) 入参&#xff1a;parseThisUrlhttp…

【C#】使用.net9在C#中向现有对象动态添加属性

在 C# 中向现有对象动态添加属性并不像在 Python 或 JavaScript 中那样容易&#xff0c;因为 C# 是一种强类型语言。 但是&#xff0c;我们可以通过使用一些技术和库来实现这一点&#xff0c;例如扩展方法、字典等。本文将详细介绍如何在 C# 中实现这一点。ExpandoObject 方法 …

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置...-CSDN博客 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明-CSDN博客 工作…

如何有效销售和应用低代码软件?探索其市场机会与策略

随着技术的进步&#xff0c;企业对自动化和数字化的需求日益增加。低代码开发平台应运而生&#xff0c;成为企业实现快速应用程序开发的重要工具。然而&#xff0c;在市场上推广和应用低代码软件并非易事&#xff0c;需要深入了解客户需求&#xff0c;提供定制化的解决方案&…

【css】overflow: hidden效果

1. 不添加overflow: hidden 1.1 效果 上面无圆角 1.2 代码 <template><view class"parent"><view class"child1">child1</view><view class"child2">child2</view></view></template><…

VB6.0桌面小程序(桌面音乐播放器)

干货源码 Imports System.IO Imports System.Security.Cryptography Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Button1.Text “上一曲” Button4.Text “播放” Button3.Text “下一曲” Button2.Text “顺序播…