红叶何时落水
开启任务调度器
流程
1.建立空闲任务
2.开启软件定时器
3.调用xPortStartScheduler()设置pendsv和滴答定时器中断,并开启第一个任务
具体流程
1.建立空闲任务 xTaskCreate();
(1). 创建一个pxStack指针,分配相应大小的空间,堆栈空间*4字节
(2). pxNewTCB, 给任务结构体分配空间,与堆栈空间挨着,但不重叠
(3). 结构体与堆栈连接起来, pxNewTCB->pxStack = pxStack;//以上是空间分配
(4). 初始化任务 prvInitialiseNewTask();//以下是任务参数的初始化
1). 初始化任务的堆栈栈顶指针pxTopOfStack == 栈顶(pxStack + size)
2). 把任务名字存储起来
3). 检测优先级是否超过最大值,超过的话,设置为最大值,并且赋值给结构体pxNewTCB->uxPriority = uxPriority;
4). 是否开启互斥,开启的话,保存原始优先级
5). 初始化任务结构体中的两个链表项,
将列表项中的任务指向指针指向自己,
并将xEventListItem项值初始化 == configMAX_PRIORITIES - uxPriority
//???这样的话,优先级越高,在列表中越靠前,就越先执行(当然只限于第一次执行)
6). 各种特殊功能初始化
7). 初始化线程本地存储指针pxPortInitialiseStack();
pxPortInitialiseStack_1. pxTopOfStack--;xPSR入栈
pxPortInitialiseStack_2. pxTopOfStack--;PC = 任务函数指针 入栈
保存各种寄存器以及函数参数啥的
最后返回栈顶指针
以上就是保存任务的运行环境
8). 返回句柄 *pxCreatedTask = ( TaskHandle_t ) pxNewTCB;
(5). 将任务添加到就绪列表中 prvAddNewTaskToReadyList();
具体操作看列表运行原理
(6). return xReturn;
2.开启软件定时器
3.调用xPortStartScheduler()设置pendsv和滴答定时器中断
(1). 配置两个中断的优先级为15
(2). vPortSetupTimerInterrupt();设置滴答定时器计时间隔
(3). prvStartFirstTask();开启第一个任务
1). VTOR 寄存器的地址 0XE000ED08 赋值给R0, 获取向量表的起始地址0X08000000
2). 从向量表中获取MSP的值,并将MSP复位,即不再使用MSP
3). 打开中断,调用SVC服务例程 vPortSVCHandler();
SVC_1. 获取当前任务的任务栈顶指针
SVC_2. 将任务里的运行环境出栈,设置PSP
SVC_3. 设置线程模式,退出中断,开始运行第一个任务
删除任务 vTaskDelete 句柄不会被置空 确实不会
taskYIELD() 任务切换。
taskENTER_CRITICAL() 进入临界区,用于任务中。
taskEXIT_CRITICAL() 退出临界区,用于任务中。
taskENTER_CRITICAL_FROM_ISR() 进入临界区,用于中断服务函数中。
taskEXIT_CRITICAL_FROM_ISR() 退出临界区,用于中断服务函数中。
taskDISABLE_INTERRUPTS() 关闭中断。
taskENABLE_INTERRUPTS() 打开中断。
vTaskStartScheduler() 开启任务调度器。
vTaskEndScheduler() 关闭任务调度器。
vTaskSuspendAll() 挂起任务调度器。
xTaskResumeAll() 恢复任务调度器。
vTaskStepTick() 设置系统节拍值。
vTaskSuspendAll() 挂起任务调度器。
调度器挂起是支持嵌套的。使用函数 xTaskResumeAll()可以恢复任务调度器,
调用了几次 vTaskSuspendAll()挂起调度器,同样的也得调用几次 xTaskResumeAll()才会最终恢复任务调度器。
uxTaskPriorityGet() 查询某个任务的优先级。
vTaskPrioritySet() 改变某个任务的任务优先级。
uxTaskGetSystemState() 获取系统中任务状态。
vTaskGetInfo() 获取某个任务信息。
xTaskGetApplicationTaskTag() 获取某个任务的标签(Tag)值。
xTaskGetCurrentTaskHandle() 获取当前正在运行的任务的任务句柄。
xTaskGetHandle() 根据任务名字查找某个任务的句柄
xTaskGetIdleTaskHandle() 获取空闲任务的任务句柄。
uxTaskGetStackHighWaterMark()获取任务的堆栈的历史剩余最小值,FreeRTOS 中叫做“高水位线”
eTaskGetState() 获取某个任务的壮态,这个壮态是 eTaskState 类型。
pcTaskGetName() 获取某个任务的任务名字。
xTaskGetTickCount() 获取系统时间计数器值。
xTaskGetTickCountFromISR() 在中断服务函数中获取时间计数器值
xTaskGetSchedulerState() 获取任务调度器的壮态,开启或未开启。
uxTaskGetNumberOfTasks() 获取当前系统中存在的任务数量。
vTaskList()以一种表格的形式输出当前系统中所有任务的详细信息。
vTaskGetRunTimeStats() 获取每个任务的运行时间。
vTaskSetApplicationTaskTag() 设置任务标签(Tag)值。
SetThreadLocalStoragePointer() 设置线程本地存储指针
GetThreadLocalStoragePointer() 获取线程本地存储指针