本文是《ALIENTEK STM32F429 FreeRTOS 开发教程》第九章学习笔记
第一章笔记–FreeRTOS简介与源码下载
第二章笔记–FreeRTOS在STM32F4上移植
第三章笔记-FreeRTOS系统配置
第四章笔记-FreeRTOS中断分析
第四章笔记补充-FreeRTOS临界段代码
第五章笔记-FreeRTOS任务基础
第六章笔记-FreeRTOS任务API函数的使用
第七章笔记-FreeRTOS列表和列表项
第八章笔记-1-FreeRTOS任务创建
第八章笔记-2-FreeRTOS任务调度器开启
一、FreeRTOS任务切换场合
- 可以执行的一个系统调用
- 系统能够滴答定时器(SysTick)中断
1.1 执行系统调用
执行系统调用即执行FreeRTOS系统提供的相关API函数,比如任务切换函数taskYIELD(),或是有些调用了taskYIELD()函数的API函数。
taskYIELD()源码:
#define taskYIELD() portYIELD()
#define portYIELD()
{
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
__dsb( portSY_FULL_READ_WRITE );
__isb( portSY_FULL_READ_WRITE );
}
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT:
#define portNVIC_INT_CTRL_REG ( * ( ( volatile uint32_t * ) 0xe000ed04 ) )
#define portNVIC_PENDSVSET_BIT ( 1UL << 28UL )
中断控制及状态寄存器ICSR(地址:0xE000_ED04),向ICSR的第28位写入1悬起PendSV(启动PendSV中断)
__dsb( portSY_FULL_READ_WRITE );__isb( portSY_FULL_READ_WRITE ): dsb和isb 完成数据同步隔离和指令同步隔离 完成作用是保证之前存储器访问操作和指令都执行完(个人认为是要确保开启了PendSV)
1.2 系统滴答定时器(SysTick)中断
FreeRTOS中滴答定时器(SysTick)中断服务函数中也会进行任务切换
滴答定时器中断服务函数:
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
HAL_IncTick();
}
void xPortSysTickHandler( void )
{
vPortRaiseBASEPRI();
{
if( xTaskIncrementTick() != pdFALSE )
{
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
vPortClearBASEPRIFromISR();
}
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED):判断系统是否运行
vPortRaiseBASEPRI():关闭中断
if( xTaskIncrementTick() != pdFALSE ):增加时钟计数器xTickCount的值,如果不出错则期待能够PendSV中断
vPortClearBASEPRIFromISR():开启中断
二、PendSV中断服务函数
#define xPortPendSVHandler PendSV_Handler
__asm void xPortPendSVHandler( void )
{
extern uxCriticalNesting;
extern pxCurrentTCB;
extern vTaskSwitc