跟着野火视频学习FreeRTOS——FreeRTOS的启动流程

这个FreeRTOS的学习其实只有任务的定义与任务切换的实现这一张真正认真的看了,虽然没看懂,但是整体流程知道了,了解了哪些函数都是什么功能。在后面的章节都是对这一章节的优化,具体的优化细节其实我也不是太清楚是怎么实现的,大概的过了一遍,知道了FreeRTOS这个实时操作系统是什么和其相关的一些概念。然后就是昨天开始学习第二部分内核应用开发的第一章移植FreeRTOS到STM32。本来昨天就应该很快的把前三章过一遍的,但是我太容易分心了,在小红书上看到嵌入式开发的编程环境除了Keil还有可以使用VScode使用一些插件进行编程感觉VScode界面特别好看就去看VScode相关的东西,安装交叉编译链、GDB、Openocd,弄了一上午只可以进行编译还没法调试,这些东西现在还用不到,等以后有时间再重新弄一下写个博客。现在我的主要目标是学完FreeRTOS,实现相关项目。


目录

目录

 前言

1、FreeRTOS的两种启动方式

1.1、万事俱备,只欠东风

1.2、小心翼翼,十分谨慎

2、FreeRTOS的启动流程

2.1、创建任务xTaskCreate()函数

2.2、vTaskStartScheduler()函数

3、main函数


 前言

本节内容是学习FreeRTOS的启动流程


1、FreeRTOS的两种启动方式

1.1、万事俱备,只欠东风

在main函数中将硬件初始化,RTOS系统初始化,所有的任务创建都弄好,只差最后一步启动RTOS调度器开始多任务的调度

1.2、小心翼翼,十分谨慎

在main函数中将硬件和RTOS系统先初始化好,然后创建一个启动任务后就启动调度器,然后在启动任务 里面创建各种应用任务,当所有任务都创建成功后,启动任务把自己删除

2、FreeRTOS的启动流程

在系统上电的时候第一个执行的是启动文件里面由汇编编写的复位函数Reset
_Handler。复位函数的最后会调用C库函数__main。__main函数的主要工作是初始化系统的堆和栈,最后调用C中的main函数。

2.1、创建任务xTaskCreate()函数

在main()函数中,可以直接对FreeRTOS进行创建任务操作,因为FreeRTOS会自动帮我们做初始化的事情,如初始化堆内存。

我们自己在main()函数中直接初始化板级外设——BSP_Init(),然后进行任务的创建——xTaskCreate(),在任务创建中,FreeRTOS会帮我们进行一系列的系统初始化,在创建任务的时候,会帮我们初始化堆内存。

2.2、vTaskStartScheduler()函数

在创建完任务的时候需要开启调度器,因为创建仅仅是把任务添加到系统中,还没真正调度,并且空闲任务也没有实现,定时器任务也没有实现,这些都是在开启调度函数中实现的。

3、main函数

在main函数中只是创建并启动一些任务和硬件初始化,而系统初始化这些工作不需要我们实现,因为FreeRTOS在我们使用创建与开启调度的时候就已经偷偷帮我们做完了,如果只是使用FreeRTOS的话无需关注FreeRTOS的API函数里面的实现过程  。

当创建的应用任务的优先级比 AppTaskCreate 任务的优先级高、低或者相等时候,程
序是如何执行的?假如像我们代码一样在临界区创建任务,任务只能在退出临界区的时候
才执行最高优先级任务。假如没使用临界区的话,就会分三种情况: 1、应用任务的优先级
比初始任务的优先级高,那创建完后立马去执行刚刚创建的应用任务,当应用任务被阻塞
时,继续回到初始任务被打断的地方继续往下执行,直到所有应用任务创建完成,最后初
始任务把自己删除,完成自己的使命; 2、应用任务的优先级与初始任务的优先级一样,那
创建完后根据任务的时间片来执行,直到所有应用任务创建完成,最后初始任务把自己删
除,完成自己的使命; 3、应用任务的优先级比初始任务的优先级低,那创建完后任务不会
被执行,如果还有应用任务紧接着创建应用任务,如果应用任务的优先级出现了比初始任
务高或者相等的情况,请参考 1 和 2 的处理方式,直到所有应用任务创建完成,最后初始
任务把自己删除,完成自己的使命。
 

<think>好的,用户想了解FreeRTOS启动流程和相关机制。我需要先回忆一下之前提供的引用内容,特别是引用1、2、3中的信息。用户可能对启动流程中的各个步骤不太清楚,比如硬件初始化、任务创建、调度器启动等。首先,引用1提到main函数中的初始化步骤,包括硬件初始化、RTOS初始化、任务创建和启动调度器。引用2详细说明了vTaskStartScheduler函数的作用,包括启动SysTick和第一个任务。引用3则分步骤讲解了复位函数、动态任务创建和任务调度的过程,还提到了空闲任务和定时器任务的创建。接下来,我需要将这些信息整合成一个清晰的流程。可能分为几个阶段:硬件初始化、RTOS内核初始化、任务创建、调度器启动、任务切换机制。每个阶段需要解释关键函数和步骤,比如如何创建任务,调度器如何启动SysTick,如何切换到第一个任务。 用户可能还会关心动态内存分配,任务控制块(TCB)的初始化,以及中断向量表的设置。需要提到configSUPPORT_DYNAMIC_ALLOCATION宏的作用,TCB结构体的成员赋值,以及向量表地址的配置,如SCB->VTOR的设置。另外,引用3中提到的SVC和PendSV中断的作用,以及SysTick的作用,这些都是任务切换的关键机制。需要解释SVC用于启动第一个任务,PendSV用于上下文切换,SysTick提供时间片轮转。 需要注意的是,用户可能对代码示例感兴趣,比如main函数的结构和任务创建函数的使用。可以引用示例中的伪代码,说明如何创建初始任务,然后启动调度器。 可能还需要提到空闲任务和定时器任务,这些是在调度器启动时自动创建的。用户可能不知道这些后台任务的存在,需要简要说明它们的作用。最后,生成相关问题时要围绕启动流程的细节,比如动态内存配置、任务切换机制、调度器启动后的行为,以及常见问题如启动失败的原因。这样可以帮助用户进一步深入学习。</think>### FreeRTOS启动流程详解 FreeRTOS启动过程分为**硬件初始化**、**内核初始化**、**任务创建**和**调度器启动**四个阶段,其核心机制围绕任务调度与中断控制展开。以下是详细步骤: --- #### 一、硬件初始化阶段 1. **复位处理函数** 系统上后首先执行`Reset_Handler`,完成以下操作: - 初始化堆栈指针(MSP) - 设置中断向量表地址,例如: $$ \text{SCB->VTOR} = \text{FLASH\_BASE} + \text{偏移量} $$ 确保向量表指向正确的内存区域[^3]。 2. **硬件外设初始化** 用户需在`main()`函数中调用`HardWare_Init()`,初始化时钟、GPIO、通信接口等外设。 --- #### 二、内核初始化与任务创建 1. **RTOS内核初始化** 调用`RTOS_init()`(示例中的`RTOD_init`),初始化任务就绪列表、内存管理单元等核心组件。 2. **动态任务创建** - **配置宏定义**:在`FreeRTOSConfig.h`中启用动态内存分配: ```c #define configSUPPORT_DYNAMIC_ALLOCATION 1 ``` - **创建初始任务**:通过`xTaskCreate()`或`vTaskStartScheduler()`前的显式任务创建。例如: ```c xTaskCreate(AppTaskCreate, "InitTask", 128, NULL, 2, NULL); ``` 此任务负责后续其他任务的动态创建[^3]。 3. **任务控制块(TCB)初始化** 内核为每个任务分配TCB结构体,包含优先级、堆栈指针、状态等字段,并将其加入就绪列表。 --- #### 三、调度器启动阶段 1. **启动函数`vTaskStartScheduler()`** 此函数完成以下关键操作: - **启动SysTick定时器**:配置系统节拍(如1ms中断),为时间片轮转提供基础[^2]。 - **创建空闲任务**:优先级为0的后台任务,用于回收已删除任务的内存。 - **启动软件定时器任务**(可选):需配置`configUSE_TIMERS=1`[^3]。 - **触发第一个任务切换**:通过`prvStartFirstTask()`调用SVC中断,切换到最高优先级任务。 2. **SVC中断与任务切换** - **SVC_Handler**:用于启动第一个任务,通过汇编指令加载任务上下文。 - **PendSV_Handler**:在任务切换时触发,完成旧任务堆栈保存与新任务堆栈恢复[^3]。 --- #### 四、任务运行阶段 1. **时间片调度** SysTick中断触发时,若存在同优先级任务,内核按时间片轮转分配CPU资源。 2. **阻塞与唤醒** 任务通过`vTaskDelay()`或信号量等待时主动让出CPU,调度器选择下一个就绪任务。 --- ### 关键代码示例 ```c int main() { HardWare_Init(); // 硬件初始化 xPortInitialize(); // 内核初始化(部分实现依赖硬件) xTaskCreate(Task1, "T1", 512, NULL, 2, NULL); // 显式创建任务 vTaskStartScheduler(); // 启动调度器 while(1); // 调度器正常运行时不会返回 } ``` --- ### 常见问题分析 1. **启动失败原因** - 未正确配置堆栈大小导致溢出 - 中断向量表地址未对齐或指向错误区域 - SysTick未成功初始化 2. **动态内存分配失败** 需检查`configTOTAL_HEAP_SIZE`是否足够,或改用静态内存分配(`xTaskCreateStatic()`)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值