一文读懂Freertos内核(大学生更懂大学生)


前言

作为一名学习时间一年左右的大学生,本文肯定对rtos的解释不如一些老师和一些博主,对一些解释可能不是很科学,希望各位读者大佬能够指正,本文是以记录学习过程为出发点,将自己学习过程中的理解,通过更通俗的解释分享出来,让读者初步的了解rots内核。


一、Freertos最最最最核心在哪?

通过这段时间的学习,以及自己实现的rtos内核来看,Freertos实时操作的核心在于任务调度,就是其中的sp指针的切换入栈以及上下文的切换

那么本文就以三个部分来讲解rtos的核心、分别是创建任务、任务调度、任务切换。其中更是以任务调度为重,剩下的进入临界区、支持优先级、时间片需要根据读者的反馈进行文章更新读者也可以读完本文之后自己涉及。

首先知道,Freertos和裸机的最大区别是什么?如果我们使用裸机开发,是不是轮询查找?(在主函数中的死循环里按照顺序依次执行)
充其量在主函数中添加标志位,让其在中断进行处理。这固然是一种响应和处理分开的方法。但是今天我们来讲解一下实时操作系统、主打的一个实时、我们在中断进行响应,处理在任务中执行。那么引入一个知识点、什么是任务? 所谓任务就是一个个在主函数中的死循环,根据任务的优先级来处理优先级最高的任务,再通过任务切换去另外一个任务.

此时大家脑海里有没有思路了?
在江湖中,强者为尊实力为大、每天都是在厮杀,但是大家都规定好了,谁是大哥谁先享受、如果期间谁成为新的大哥,那么新的大哥才有资格享受资源
这里面的“大家”就是任务资源就是“CPU的使用”、大哥就是“优先级高的任务

1、创建任务

创建任务可以分为动态创建、静态创建。本文以最简单的静态创建为例、读者可以阅读完本文之后去看看rtos动态创建的源码比较一下区别。

1、任务栈?

首先问大家一个问题、如果使用裸机开发,我们定义的全局变量、函数中的局部变量都放在哪里?是不是在栈中?栈就是单片机RAM里面一段连续的内存空间,大小一般在启动文件里面或者连接脚本里面定义,通过外在的调用初始化。
那么和任务栈有什么关系?在江湖中、各路豪杰英雌距地分割。每个人都有自己的地盘。那我内部的吃喝开销不是我自己负责?
同样,栈也是一个个独立的,每个栈都有自己的独立栈空间,只是这个栈空间需要提前定义好,就是一个全局数组
在这里插入图片描述
我们此时不管函数的参数(其实就是宏定义uint32_t 类型)

2、任务函数

其实在上面的时候大家都对任务函数脑中有了初步的构想,就是一个死循环函数
在这里插入图片描述

3、任务也有身份证?

你没听错,人在江湖混,别人怎么知道你叫啥籍贯哪里,那肯定需要一个身份证来证明这个是我。同乡的出去也能说我和英雄一个村从小玩到大的 (说过头了)、那么任务的身份证叫什么呢?TCB

typedef struct tskTaskControlBlock
 {
volatile StackType_t *pxTopOfStack;                         /* 栈顶 */

ListItem_t xStateListItem;                                  /* 任务节点 */

StackType_t *pxStack;                                       /* 任务栈起始地址 */

char pcTaskName[ configMAX_TASK_NAME_LEN ];                 /* 任务名称,字符串形式 */
 
TickType_t xTicksToDelay;                                   /* 用于延时 */
 
 UBaseType_t uxPriority;
}tskTCB;
typedef tskTCB TCB_t;

可以看到TCB就是结构体、里面包含了栈顶指针、任务节点(其实就是将该节点放入链表中,从而实现任务挂到链表上,因为TCB就是任务的身份证,挂TCB就是挂任务)、任务栈起始地址、任务名字~~、延时、优先级~~ (暂且不谈)

4、创建任务的函数

不是哥们,我看了这么久你就给我上理论啊?能不能来点实际的操作啊?
可以的读者,量大管饱,我们上干活,看看任务创建的内部是怎么实现

1、xTaskCreateStatic
	TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,
                                    const char * const pcName, 
                                    const uint32_t ulStackDepth, 
                                    void * const pvParameters, 
                                    UBaseType_t uxPriority,
                                    StackType_t * const puxStackBuffer, 
                                    TCB_t * const pxTaskBuffer ) 
	{
   
    TCB_t *pxNewTCB;												//创建tcb、创建身份证
    TaskHandle_t xReturn; 											//创建函数返回值
    
    if ( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) )			
    {
   
        pxNewTCB = ( TCB_t *</
### FreeRTOS 内核介绍 FreeRTOS 是一个开源的实时操作系统 (RTOS) 内核,专门为资源受限的嵌入式系统设计[^1]。该内核提供了一系列核心功能和服务来简化复杂系统的开发过程。 #### 核心特性 - **任务管理**: 支持多任务调度机制,允许开发者定义不同优先级的任务并合理安排它们之间的切换。 - **同步原语**: 提供信号量、互斥锁以及事件标志组等多种工具用于进程间通信和资源共享控制。 - **消息传递**: 队列为应用程序组件之间传输数据提供了可靠的方法;支持多种类型的队列操作以满足不同的应用场景需求。 - **时间处理**: 定时器服务可以周期性触发回调函数或延迟特定时间段后再继续执行某项工作流。 - **内存分配**: 实现了几种灵活高效的动态存储池方案以便于快速申请释放临时对象所需的空间。 - **中断响应**: 中断服务例程接口使得硬件外设能够及时打断当前正在运行的任务而得到即时处理。 - **可移植架构**: 设计上充分考虑到了跨平台兼容性和易用性,因此很容易被集成至各种微控制器平台上使用。 ```c // 创建两个具有不同优先级的任务示例 void vTaskCode(void *pvParameters); const char *pcTextForTask1 = "Task 1 is running\r\n"; const char *pcTextForTask2 = "Task 2 is running\r\n"; xTaskCreate(vTaskCode, "TASK 1", configMINIMAL_STACK_SIZE, ( void * ) pcTextForTask1, tskIDLE_PRIORITY + 1, NULL ); xTaskCreate(vTaskCode, "TASK 2", configMINIMAL_STACK_SIZE, ( void * ) pcTextForTask2, tskIDLE_PRIORITY + 2, NULL ); vTaskStartScheduler(); ``` 上述代码展示了如何利用 `xTaskCreate` 函数创建两个新任务,并通过设置各自的优先级参数 (`tskIDLE_PRIORITY + N`) 来影响调度顺序。当较高优先级的任务就绪时它会抢占较低者获得 CPU 控制权直至完成或者进入等待状态为止[^5]。 #### 应用场景 由于其小巧精悍的特点加上丰富的API集成功能模块,FreeRTOS 成为了众多物联网设备制造商的理想选择之一,在智能家居产品、工业自动化控制系统乃至消费类电子产品等领域均有广泛应用案例存在[^3]。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值