1.开启任务调度器
1.1 vTaskStartScheduler()
作用:启动任务调度器
实现功能:1)创建空闲任务、2)若能使能定时器,创建定时器任务、3)关闭中断、防止任务任务调度器开启之前或中断中,受中断干扰,4)初始哈全局变量,将运行标志设置为已运行,5)初始化任务时间统计功能的时基定时器、6)调用函数xPortStartSchedule()
1.2 xPortStartSchedule()
作用:启动与硬件架构相关配置,启动第一个任务函数内部实现
1)配置PenSV和Systick的中断优先级为最低优先级
2)调研函数xPortSetupTimerInterrupt()配置Systick
3)初始化临界区嵌套计数为0
4)调用函数prvStartFirstTask()启动第一个任务
2.启动第一个任务
2.1 prvStartFirstTask()
作用:初始化启动第一个任务前的环境,主要重新设置MSP(主堆栈指针)指针,并使能全局中断。
MSP:是向量表的第一个元素,主要用于中断
2.1 vPortSVCHandler() SVC中断服务函数
1)通过pxCurrentTCB获取优先级最高的就绪状态任务的任务栈地址
2)通过栈顶地址,通过栈顶地址将栈中内容出栈到CPU寄存器中,然后设置PSP指针
3)出栈(恢复现场),方向从下往上
压栈(保存现场),从高到低
3 任务切换
本质:CPU寄存器的切换
任务从A切换到B步骤:
1)暂停任务A的执行,将任务A的寄存器保存到任务堆栈中,保存现场
2)将任务B的各个寄存器恢复到CPU寄存器上,较恢复现场
这个过程称为上下文切换
4.1其他知识总结
4 .1PendSV中断是如何触发
1、滴答定时器中断调用
2、执行FreeRTOS提供的相关API函数:portYIELD()
本质:通过向中断控制和状态寄存器 ICSR 的bit28 写入 1 挂起 PendSV 来启动 PendSV 中断
4 .2查找最高优先级任务
vTaskSwitchContext( ) /查找最高优先级/
taskSELECT_HIGHEST_PRIORITY_TASK( ) /* 通过这个函数完成 *