RT-Thread内核学习

内核框架

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

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

线程调度

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

支持256个线程优先级(也可通过配置文件更改为最大支持32个或8个线程优先级,针对STM32默认配置是32个线程优先级)。
0优先级代表最高优先级,最低优先级留给空闲线程使用。
同时也支持创建多个具有相同优先级的线程,相同优先级的线程间采用时间片的轮转调度算法,使每个线程运行相应时间。

调度器在寻找那些处于就绪状态的具有最高优先级的线程时,所经历的时间是恒定的。

系统也不限制线程数量的多少,线程数目只和硬件平台的具体内存相关。

时钟管理

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

提供两类定时器机制:

  1. 单次触发定时器,这类定时器在启动后只会触发一次定时器事件,然后定时器自动停止。
  2. 周期触发定时器,定时器会周期性的触发定时器事件,直到用户手动停止定时器。

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

通常使用定时器定时回调函数(即超时函数),完成定时服务。

线程间同步

采用信号量、互斥量与事件集实现线程间同步。
线程通过对信号量、互斥量的获取与释放进行同步。

互斥量采用优先级继承的方式解决了实时系统常见的优先级翻转问题。
线程同步机制支持线程按优先级等待或按先进先出方式获取信号量或互斥量。

线程通过对事件的发送与接收进行同步。

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

线程间通信

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

内存管理

支持静态内存池管理和动态内存堆管理。

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

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

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

I/O设备管理

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

RTT内核启动流程

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 先关掉硬件中断:rt_hw_interrupt_disable()
  2. 板级初始化:rt_hw_board_init() rt_components_board_init() board init functions
  3. 展示版本号rt_show_version()
  4. 系统定时器初始化rt_system_timer_init()
  5. 系统调度器初始化rt_system_scheduler_init()
  6. 信号初始化rt_system_signal_init()
  7. 应用层初始化rt_application_init() rt_thread_init(main_thread_entry)
  8. 系统定时器线程初始化,rt_system_timer_thread_init() rt_thread_init(rt_thread_timer_entry)
  9. 空闲线程初始化rt_thread_idle_init() rt_thread_init(rt_thread_idle_entry)
  10. rt_system_scheduler()启动调度器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
清空BSS段,为C语言执行准备条件。
C语言中全局未初始化变量放在BSS段,所以当我们打印全局未初始化变量时,也会显示0。

在这里插入图片描述
调用SystemInit,调用完后进入entry入口,由此进入C语言代码执行。

void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= 0x00000001U;/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#if !defined(STM32F105xC) && !defined(STM32F107xC)RCC->CFGR &= 0xF8FF0000U;
#elseRCC->CFGR &= 0xF0FF0000U;
#endif /* STM32F105xC */   /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= 0xFEF6FFFFU;/* Reset HSEBYP bit */RCC->CR &= 0xFFFBFFFFU;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= 0xFF80FFFFU;#if defined(STM32F105xC) || defined(STM32F107xC)/* Reset PLL2ON and PLL3ON bits */RCC->CR &= 0xEBFFFFFFU;/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x00FF0000U;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000U;
#elif defined(STM32F100xB) || defined(STM32F100xE)/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000U;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000U;      
#else/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000U;
#endif /* STM32F105xC */
#elif defined(__GNUC__)
/* Add -eentry to arm-none-eabi-gcc argument */
int entry(void)
{rtthread_startup();return 0;
}
#endif
int rtthread_startup(void)
{rt_hw_interrupt_disable();/* board level initialization* NOTE: please initialize heap inside board 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_SMPrt_hw_spin_lock(&_cpus_lock);
#endif /*RT_USING_SMP*//* start scheduler */rt_system_scheduler_start();/* never reach here */return 0;
}
void rt_application_init(void)
{rt_thread_t tid;#ifdef RT_USING_HEAPtid = rt_thread_create("main", main_thread_entry, RT_NULL,RT_MAIN_THREAD_STACK_SIZE, RT_MAIN_THREAD_PRIORITY, 20);RT_ASSERT(tid != RT_NULL);
#elsert_err_t result;tid = &main_thread;result = rt_thread_init(tid, "main", main_thread_entry, RT_NULL,main_stack, sizeof(main_stack), RT_MAIN_THREAD_PRIORITY, 20);RT_ASSERT(result == RT_EOK);/* if not define RT_USING_HEAP, using to eliminate the warning */(void)result;
#endifrt_thread_startup(tid);
}
/* the system main thread */
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_SMPrt_hw_secondary_cpu_up();
#endif/* invoke system main function */
#if defined(__CC_ARM) || defined(__CLANG_ARM)$Super$$main(); /* for ARMCC. */
#elif defined(__ICCARM__) || defined(__GNUC__)main();
#endif
}

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

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

相关文章

自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-@RequestParam

😀前言 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-RequestParam 🏠个人主页:尘觉主页 🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家&#xff0c…

python爬虫的js逆向入门到进阶教程文章分享汇总~持续更新

目录 一、内容介绍二 、专栏内容-持续更新1、JS逆向入门2、Js逆向进阶3、爬虫基础知识4、工具与安装5、漫星内容分享 三、星球使用四、b站up主视频推荐 一、内容介绍 二 、专栏内容-持续更新 1、JS逆向入门 2023-08-25》11.常见加密>xx音乐RSA加密 https://articles.zsxq.c…

微信小程序开发教学系列(4)- 数据绑定与事件处理

4. 数据绑定与事件处理 在微信小程序中,数据绑定和事件处理是非常重要的部分。数据绑定可以将数据和页面元素进行关联,实现数据的动态渲染;事件处理则是响应用户的操作,实现交互功能。本章节将详细介绍数据绑定和事件处理的基本原…

STM32--SPI通信与W25Q64(1)

文章目录 前言SPI通信硬件电路移位过程 SPI时序起始与终止条件交换一个字节 W25Q64硬件电路框图 FLASH操作注意事项软件SPI读写W25Q64 前言 USART串口链接入口 I2C通信链接入口 SPI通信 SPI(Serial Peripheral Interface)是一种高速的、全双工、同步的串…

C#__自定义类传输数据和前台线程和后台线程

// 前台线程和后台线程 // 默认情况下,用Thread类创建的线程是前台线程。线程池中的线程总是后台线程。 // 用Thread类创建线程的时候,可以设置IsBackground属性,表示一个后台线程。 // 前台线程在主函数运行结束后依旧执行,后台线…

用 Audacity 比较两段音频差异

工作中遇到相同的处理流程,处理同一段音频,看看处理结果是否一致,可以用audacity来处理。 假设待比较的音频分别为 1.wav 2.wav 1、用Audacity打开1.wav 2、用Audacity打开2.wav,选中音频,然后用 效果 -> 反向&am…

弯道超车必做好题集锦二(C语言选择题)

前言: 编程想要学的好,刷题少不了,我们不仅要多刷题,还要刷好题!为此我开启了一个弯道超车必做好题锦集的系列,每篇大约10题左右。此为第二篇选择题篇,该系列会不定期更新,后续还会…

解决idea登录github copilot报错问题

试了好多方案都没用,但是这个有用, 打开idea-help-edit custonm vm options 然后在这个文件里面输入 -Dcopilot.agent.disabledtrue再打开 https://github.com/settings/copilot 把这个设置成allow,然后重新尝试登录copilot就行就行 解决方…

智慧课堂学生行为检测评估算法

智慧课堂学生行为检测评估算法通过yolov5系列图像识别和行为分析,智慧课堂学生行为检测评估算法评估学生的表情、是否交头接耳行为、课堂参与度以及互动质量,并提供相应的反馈和建议。智慧课堂学生行为检测评估算法能够实时监测学生的上课行为&#xff0…

Linux TCP协议——三次握手,四次挥手

一、TCP协议介绍 TCP协议是可靠的、面向连接的、基于字节流的传输层通信协议。 TCP的头部结构: 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去;(tcp是传输层的协议,端与端之间的数据传输,在TCP和UDP协议当中不会体现出I…

缓存最佳实践

目录 前言 一、Cache Aside(旁路缓存)策略 二、不一致解决场景及解决方案 一、数据库主从不一致 二、缓存与数据库不一致 三、问题分析 三、缓存误用 一、多服务共用缓存实例 二、调用方缓存数据 三、缓存作为服务与服务之间传递数据的媒介 四…

如何搭建数字化招商加盟体系?如何推动企业招商加盟增速?

线索转化率低、客户数据不完整及合作过程中服务满意度低等情景是企业在进行招商加盟的过程中常常会遇到的问题。如何使用数字化招商加盟工具,在业务运营的过程中来提高企业成单率、提高企业线索价值,提高客户满意度? 开利网络数字化招商加盟系…