RT-Thread内核介绍

news2024/11/15 22:35:16

目录

三、RT-Thread内核介绍

3.1、内核框架

3.1.1、线程调度

3.1.2、时钟管理

3.1.3、线程间同步

3.1.4、线程间通信

3.1.5、内存管理

3.1.6、I/O 设备管理

3.2、RTT内核启动流程

3.2.1、汇编阶段

3.2.2、C阶段

3.2.3、rtthread_startup函数

3.2.4、创建主线程


三、RT-Thread内核介绍

3.1、内核框架

内核是操作系统最基础也是最重要的部分。下图为 RT-Thread 内核架构图,内核处于硬件层之上,内核部分包括内核库、实时内核实现。

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

实时内核的实现包括:

  • 对象管理
  • 线程管理及调度器
  • 线程间通信管理
  • 时钟管理
  • 内存管理
  • 设备管理

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

对于嵌入式产品,是针对某一个应用领域或者某一个应用去生产一个设备,所以它的功能要求没那么多,系统占用的资源少,成本低。

3.1.1、线程调度

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

3.1.2、时钟管理

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

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

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

3.1.3、线程间同步

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

3.1.4、线程间通信

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

3.1.5、内存管理

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

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

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

3.1.6、I/O 设备管理

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

3.2、RTT内核启动流程

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

3.2.1、汇编阶段

Reset_Handler:    //复位

/* Copy the data segment initializersfrom flash to SRAM */
 movs r1, #0
 b LoopCopyDataInit

CopyDataInit:
 ldr r3, =_sidata
 ldr r3, [r3, r1]
 str r3, [r0, r1]
 adds r1, r1, #4

LoopCopyDataInit:
 ldr r0, =_sdata
 ldr r3, =_edata
 adds r2, r0, r1
 cmp r2, r3
 bcc CopyDataInit
 ldr r2, =_sbss
 b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
 movs r3, #0
 str r3, [r2], #4

LoopFillZerobss:
 ldr r3, = _ebss
 cmp r2, r3
 bcc FillZerobss

/* Call the clock systemintitialization function.*/
   bl  SystemInit
/* Call static constructors */
   /* bl __libc_init_array */
/* Call the application's entrypoint.*/
 bl  entry
 bx lr

主要过程:

  • 从Flash中拷贝数据段到SRAM中
  • 清空BSS段(BSS段清零)
  • 初始化系统时钟(SystemInit)
  • 进入entry入口

3.2.2、C阶段

【1】系统时钟初始化

system_stm32f1xx.c中的系统初始化函数,参考之前章节内容

时钟系统配置文件board.h

使用外部高速时钟,时钟源晶振8MHz,系统时钟72MHz

【2】entry入口

int entry(void)
{
    rtthread_startup();
    return 0;
}

3.2.3、rtthread_startup函数

int rtthread_startup(void)
{
   rt_hw_interrupt_disable();       //关闭硬件中断

   /* 
    * board level initialization
    */
   rt_hw_board_init();

   /* show RT-Thread version */
   rt_show_version();

   /* timer system initialization */
   rt_system_timer_init();

   /* scheduler system initialization */
   rt_system_scheduler_init();

#ifdef RT_USING_SIGNALS
   /* signal system initialization */
   rt_system_signal_init();
#endif

   /* create init_thread */
   rt_application_init();

   /* timer thread initialization */
   rt_system_timer_thread_init();

   /* idle thread initialization */
   rt_thread_idle_init();

#ifdef RT_USING_SMP
   rt_hw_spin_lock(&_cpus_lock);
#endif /*RT_USING_SMP*/

   /* start scheduler */
   rt_system_scheduler_start();
   
   return 0;
}

主要过程:

  • 初始化系统相关硬件
  • 初始化系统内核对象、例如定时器、调度器、信号
  • 创建主线程、定时器线程、idle线程
  • 启动调度器

3.2.4、创建主线程

线程函数入口:main_thread_entry

栈大小:2048

优先级:10

同等优先级时间片轮询时间:20 个OS Tick    rfconfig.h 中配置 :

#define RT_TICK_PER_SECOND 1000   Tick每秒1000次,一次的时间为1ms

//创建线程,线程函数main_thread_entry
tid =rt_thread_create("main", main_thread_entry, RT_NULL,
        RT_MAIN_THREAD_STACK_SIZE,RT_MAIN_THREAD_PRIORITY, 20);
//开启线程 —— 将线程加入到系统的线程队列中,等待系统线程调度器遍历队列调用                
rt_thread_startup(tid);
开启线程调度器
//选择优先级最高的线程开始调度
rt_system_scheduler_start();

void main_thread_entry(void*parameter)
{
   extern int main(void);
   extern int $Super$$main(void);
   
#ifdef RT_USING_COMPONENTS_INIT
   /* RT-Thread components initialization */
   rt_components_init();
#endif    
#ifdef RT_USING_SMP
   rt_hw_secondary_cpu_up();
#endif
   /* invoke system main function */
#if defined(__CC_ARM) ||defined(__CLANG_ARM)
   $Super$$main(); /* for ARMCC. */  //进入用户的main函数入口
#elif defined(__ICCARM__) ||defined(__GNUC__)
   main();
#endif
}

注意:

$Sub$ $foo :定义的新功能函数,在foo()函数之前/后使用$Sub$$foo 可以添加一些新的程序代码。

$Super$ $foo :就是原始的未修补的foo函数,使用这个$Super$ $foo函数将直接跳转到foo()函数。

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

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

相关文章

jupyter notebook内核挂掉的解决方案

今天在运行notebook时报错 “jupyter notebook内核挂掉了”查找发现是下面这一句出的错,这是pytorch深度学习实战中的一个例程,读取三维体素文件并把其中的一张当作图片显示出来 plt.imshow(vol_arr[50]) 完整代码如下 import torch torch.set_printo…

决策树精讲

一、决策树的构造 决策树的构造是一个递归的过程,有三种情形会导致递归返回:(1)当前结点包含的样本全属于同一类别,这时直接将该结点标记为叶结点,并设为相应的类别;(2)当前属性集为空,或是所有样本在所有…

消息队列选型——为什么选择RabbitMQ

前言 MQ消息是目前分布式系统必不可少的组件,但是面对市面上众多的MQ组件,我们该用什么呢?我以实际项目的需求触发,介绍今天的主角——rabbitMQ。同时也会告知又有哪些优势和不足。事不宜迟,就开始今天的学习吧 目录…

ghost cms配置qq邮箱

背景: 在ghost cms中使用qq邮箱作为注册、登录、订阅等邮件发送方。 1 修改配置 在config.*.json文件中,添加mail配置 "mail": {"from": "xxxxxxqq.com","transport": "SMTP","options"…

Qt6 FFmpeg入门1 - 环境配置

目录 环境配置ffmpeg 下载qt 配套环境配置代码测试 环境配置 文章更新时间:2023/06/24 ffmpeg 下载 由于大部分的关于配置 ffmpegqt 环境的文章都停留在 2021 年,且许多方法均已过时,现在介绍一个最新的方法,并分析槽点供大家参考…

ElementUI在对话框中新增数据,使用rules校验规则进行校验,再点击完修改之后,在进行新增校验会报错

1.新增与修改使用同一个对话框,当修改完成一条数据后,重新打开新增的对话框,通过ElementUI的rules检验会报错 解决方案:在对应的rules校验中每个字段添加trigger: blur 即可解决上述问题,注意:下面的xxx代表需要校验的…

设计模式-05.01-行为型-观察者模板

观察者模式【常用】 我们常把 23 种经典的设计模式分为三类:创建型、结构型、行为型。前面我们已经学习了创建型和结构型,从今天起,我们开始学习行为型设计模式。我们知道,创建型设计模式主要解决“对象的创建”问题,…

工具篇7--RocketMq消息模型介绍

文章目录 前言:一、RocketMq是什么?二、RocketMq 模型介绍:1.RocketMq 模型图:2.RocketMq 生产者:2.1 生产者消费发送流程:2.2 生产者消息发送:2.2.1 同步发送普通消息:2.2.1 异步发…

AI大模型及算力要求

AI大模型对算力的要求非常高,需要高性能的硬件设备和分布式训练技术来支持。随着AI技术的不断发展,未来可能会出现更大、更复杂的模型,对算力的要求也将更高。今天和大家分享几个大模型及算力要求,希望对大家有所帮助。北京木奇移…

DETR系列:RT-DETR实战部署

上篇文章介绍RT-detr的论文内容(RT-DETR 论文解析),本篇文章介绍算法复现、tensorRT加速、python调用部署、训练等方法。 RT-DETR实战部署 1.复现模型详情2.环境准备3.训练4.部署5.测试 1.复现模型详情 本次复现主要测试下表中RT-DETR-R50和…

Kafka集群模式核心概念

文章目录 1.Kafka集群模式下Broker|主题|分区|副本的概念1.1.Broker|主题|分区|副本的概念1.2.创建一个Topic指定3个副本数1.3.多副本的Topic详细信息描述 2.集群模式下以消费者组消费Topic中各分区消息的概念2.1.分消费者组消费各分区的概念2.2.集群模式下消息的发送和消费 3.…

Go 语言中 Context 的作用和使用方法详解

KDP(数据服务平台)是一款由 KaiwuDB 独立自主研发的数据服务产品,以 KaiwuDB 为核心,面向 AIoT 场景打造的一站式数据服务平台,满足工业物联网、数字能源、车联网、智慧产业等行业核心业务场景下数据采集、处理、计算、…

在Azure SQL DB/Azure托管实例里快速查询各数据库大小以及每个数据库下表的大小

目录 (一)前言 (二)正文 1. 环境: 2. 查看实例下每个数据库的空间大小 (1) SQL语法 (2)运行结果 3. 查看特定数据库下每张表的大小 (1)SQ…

一个sql中的一张表,最多只会走一个索引吗

目录 先给结论 做实验 1.根据时间范围查询 什么是key_len? 2.根据时间范围和 is_delete 查询 最左匹配原则 2.根据时间范围和 blog_type 查询 如果加上id会怎么样 并不是索引一定会走 1.IN子表数量过多 2.单次查询超过30% 先给结论 先说结论,…

设计模式第14讲——享元模式(Flyweight)

目录 一、什么是享元模式 二、角色组成 三、优缺点 四、应用场景 4.1 生活场景 4.2 java场景 五、代码实现 5.0 代码结构 5.1 Bike——抽象享元类(FlyWeight) 5.2 具体享元类(ConcreteFlyWeight) 5.3 BikeFactory——享元…

layui框架学习(28:穿梭框模块)

Layui模块中的穿梭框模块transfer主要支撑穿梭框组件的显示、交互等操作。所谓穿梭框是指左右各有一个复选框列表,可以将左侧选中的项目移动到右边,后者将右侧的选中项移回左边的控件,其样式类似下图所示(参考文献5-6)…

TI AM62x工业开发板规格书(单/双/四核ARM Cortex-A53 + 单核ARM Cortex-M4F,主频1.4GHz)

1 评估板简介 创龙科技TL62x-EVM是一款基于TI Sitara系列AM62x单/双/四核ARM Cortex-A53 单核ARM Cortex-M4F多核处理器设计的高性能低功耗工业评估板,由核心板和评估底板组成。处理器ARM Cortex-A53(64-bit)主处理单元主频高达1.4GHz,ARM Cortex-M4F实…

如何使用 Flink SQL 探索 GitHub 数据集|Flink-Learning 实战营

为进一步帮助开发者学习使用 Flink,Apache Flink 中文社区近期发起 Flink-Learning 实战营项目。本次实战营通过真实有趣的实战场景帮助开发者实操体验 Flink,课程包括实时数据接入、实时数据分析、实时数据应用的场景实。并结合小松鼠助教模式&#xff…

USR-C216 WIIF连接手机

复位后连接USR-C216无线 浏览器输入10.10.100.254 账号密码为admin 客户端模式服务器地址无效,默认就行 打开手机网络调试助手选择客户端模式,输入10.10.100.254,端口8899 可以透传了 关于AT指令,先发“”,然后3s内发…

【数据管理架构】什么是 OLTP?

OLTP(在线事务处理)支持在 ATM 和在线银行、收银机和电子商务以及我们每天与之交互的许多其他服务背后进行快速、准确的数据处理。 什么是 OLTP? OLTP 或在线事务处理允许大量人员(通常通过 Internet)实时执行大量数据…