【嵌入式——FreeRTOS】启动任务调度器

开启任务调度器

用于启动任务调度器,任务调度器启动后,FreeRTOS便会开始进行任务调度。

//启动任务,开启调度
vTaskStartScheduler();


xTaskCreate((TaskFunction_t)start_thread,
            (const char *)"Initialize all task",
            (uint16_t)START_THREAD_STKSZ,
            (void *)NULL,
            (UBaseType_t)(START_THREAD_PRIO),
            (TaskHandle_t *)&start_tid);

vTaskStartScheduler();

vTaskStartScheduler()

内部实现

  1. 创建空闲任务;
  2. 如果使能软件定时器,则创建定时器任务;
  3. 关闭中断,防止调度器开启之前或过程中受中断干扰,会在运行第一个任务时打开中断;
  4. 初始化全局变量,并将任务调度器的运行标志设置为已运行;
  5. 初始化任务运行时间统计功能的时基定时器;
  6. 调用函数xPortStartScheduler()。

xPortStartScheduler()

该函数用于完成启动任务调度器中与硬件架构相关的配置部分,以及启动第一个任务。
内部实现

  1. 检测用户在FreeRTOSConfig.h文件中对中断的相关配置是否有误;
  2. 配置PendSV和SysTick的中断优先级为最低优先级;
  3. 调用函数vPortSetupTimerInterrupt()配置SysTick;
  4. 初始化临界区嵌套计数器为0;
  5. 调用函数prvEnableVFP()使能FPU;
  6. 调用函数prvStartFirstTask()启动第一个任务。

prvStartFirstTask()

  1. 复位MSP初始值;
  2. 使能中断;
  3. 触发SVC中断
    1. 获取当前优先级最高的任务控制块pxCurrentTCB
    2. 将该任务的寄存器值出栈至CPU寄存器中
    3. 设置PSP
    4. 返回R14,执行第一个任务函数

启动第一个任务

prvStartFirstTask()用于初始化启动第一个任务前的环境,主要是重新设置MSP指针,并使能全局中断。

MSP指针:程序在运行过程中需要一定的栈空间来保存局部变量等一些信息,当有信息保存到栈中时,MCU会自动更新SP指针,ARM Cortex-M内核提供了两个栈空间;

主堆栈指针(MSP):由OS内核、异常服务例程以及所有需要特权访问的应用程序代码来使用;
进程堆栈指针(PSP):用于常规的应用程序代码(不处于异常服务例程中时)。
在FreeRTOS中,中断使用MSP,中断以外使用PSP。
使用时间片调度需要把宏configUSE_TIME_SLICING和configUSE_PREEMPTION置为1

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值