Cortex-m3进阶

1,FreeRTOS详解

1:FreeRTOS任务调度器开启

vTaskStartScheduler

1、创建空闲任务

2、如果使能了软件定时器,创建软件定时器

3、关中断

4、初始化一些静态全局变量

5、xPortStartScheduler


xPortStartScheduler

1、设置PendSV和Systick中断优先级

2、初始化嘀嗒定时器,中断周期,中断使能,systick使能

3、如果MCU有FPU的话,开启FPU

4、如果使用FPU的话,开启惰性压栈

5、prvStartFirstTask,开启第一个任务

6、SVC 0;引起SVC中断


2:FreeRTOS任务创建

xTaskCreate()

1、申请堆栈内存

2、申请任务控制块内存

3、调用prvInitialiseNewTask()初始化任务


prvInitialiseNewTask()

1、初始化堆栈为0xa5,可选功能

2、获取栈顶,保存在pxTopOfStack。

3、保存任务名字,到pxNewTCB->pcTaskName

4、保存任务优先级到pxNewTCB->uxPriority

5、初始化两个列表项xStateListItem和xEventListItem

6、初始化各种任务控制块成员变量

7、调用pxPortInitialiseStack(),初始化堆栈

8、保存/记录任务句柄,其实就是任务控制块。


prvAddNewTaskToReadyList()

1、uxCurrentNumberOfTasks加一,记录系统中有多少个任务

2、如果创建的是第一个任务,初始化相关列表,使用函数uxCurrentNumberOfTasks()

3、调用prvAddTaskToReadyList,将任务添加到就序列表中

4、如果新创建的任务优先级比当前任务优先级高,那么调用taskYIELD_IF_USING_PREEMPTION()进行任务切换


prvAddTaskToReadyList()

1、将uxTopReadyPriority相应的bit置1,表示相应优先级有就序任务

2、将新创建的任务添加到对应的就序列表中去,末尾插入。比如优先级5,pxReadyTasksLists[5]


3:任务删除、挂起和恢复过程

任务删除

vTaskDelete(TaskHandle_t xTaskToDelete)

1、根据任务句柄获取任务控制块,如果任务句柄为NULL,表示删除任务自身

2、将要删除的任务从就序列表中移除,并且如果相应的优先级下只有这一个任务那么复位相应的优先级位

3、如果任务等待某些事件的话那就将此任务从相应的时间列表中移除

4、如果删除的是任务自身,那么将任务添加到列表xTasksWaitingTermination中。任务堆栈,控制块的内存释放在空闲任务中完成

5、uxCurrentNumberOfTasks减一,表示当前系统任务减一。如果删的不是任务自身

6、释放任务控制块和任务堆栈内存

7、如果删除的是任务自身,最后需要主动发起任务切换


任务挂起

void vTaskSuspend(TaskHandle_t xTaskToSuspend)

1、根据任务句柄获取任务控制块,如果任务句柄为NULL,表示删除任务自身

2、将要挂起的任务从相应的状态列表和事件中移除

3、将要挂起的任务添加到挂起任务列表xSuspendedTaskList里面去

4、如果挂起的是任务自身,而且任务调度器正在运行,那么需要进行一次任务切换


任务恢复

void vTaskResume(TaskHandle_t xTaskToResume)

1、判断要恢复的任务是否为挂起任务?

2、将要恢复的任务从挂起任务列表xSuspendTaskList移除

3、调用函数prvAddTaskToReadyList()将任务添加到就序列表中。

4、如果刚刚恢复的任务优先级比当前正在运行的任务优先级高,那么进行一次任务切换。


4:FreeRTOS任务切换

PendSV异常

1、任务切换具体过程是在PendSV中断服务函数里面

2、如何一起PendSV中断,ICSR寄存器bit28置1。

3、关于PendSV具体的内容,建议大家参考权威指南相关章节


任务切换场合

1、执行系统调用如:taskYILED(),vTaskDelay()->portYIELD_WIRHIN_API()->portYIELD()

2、systick中断服务函数


PendSV_Handler()或xPortPendSVHandler()

1、判断是否使用FPU。如果使用的话将S16-S31入栈。EXC_RETURN当处理异常的时候bit4会被CONTROL的FPCA位替代。判断EXC_RETURN的bit4是否为1,如果为1需要保存浮点寄存器。

2、R4-R11 R14入栈

3、关闭中断

4、调用vTaskSwitchContext,获取下一个要运行任务

5、打开中断

6、获取要切换的任务的栈顶指针

7、R4-R11,R14出栈

8、判断是否使用FPU,如果使用的话S16-S31出栈

9、任务切换完成


2,按键事件

stm8用定时器中断代替轮询读取GPIO监听cortex-m3主板是否休眠

猜你喜欢

转载自blog.csdn.net/u012332571/article/details/79374067
今日推荐