FreeRTOS源码阅读笔记(一)------任务、列表

任务相关源码

1)启动任务调度器    vTaskStartScheduler
    1.创建空闲任务(优先级为0,最低)
    2.创建软件定时器任务(优先级最高)
    3.关闭中断
    4.初始化
    5.调用xPortStartScheduler进入第一个任务
    
2)创建任务    xTaskCreate
    1.申请堆栈内存
    2.申请任务控制块TCB内存
    3.把堆栈地址赋值给控制块的堆栈成员
    4.prvInitialiseNewTask 初始化TCB成员
        pxNewTCB->uxPriority = uxPriority; 保存任务优先级
    5.prvAddNewTaskToReadyList 添加新任务到就绪列表
        进入临界区
        uxCurrentNumberOfTasks++ 记录任务数量
        如果任务是第一个,prvInitialiseTaskLists初始化任务列表
        如果不是第一个,调度器还未启动,比较优先级 pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority
        退出临界区
        如果调度器正在运行,新任务的优先级更大就进行任务切换

3)删除任务    vTaskDelete
    1.进入临界区
    2.获取任务控制块
    3.uxListRemove 从相应的状态列表和事件列表中移除
    4.如果删除的是任务自身,vListInsertEnd 添加到等待删除列表,内存释放将在空闲任务执行
        如果不是自身,当前任务数减1,prvResetNextTaskUnblockTime 更新下一个任务的阻塞超时时间
    5.退出临界区
    6.如果删除的是其他任务,prvDeleteTCB直接释放内存
    7.如果调度器正在运行并且删除自身,需要进行一次任务切换
    
4)挂起任务    vTaskSuspend
    1.进入临界区
    2.uxListRemove 从相应的状态列表和事件列表中移除
    3.vListInsertEnd 插入到挂起态任务列表末尾
    4.退出临界区
    5.调度器正在运行,prvResetNextTaskUnblockTime 更新下一个任务的阻塞超时时间
    6.如果挂起的是任务自身
        调度器在运行,进行一次任务切换
        调度器未运行,判断挂起任务数是否等于任务总数,不等则调用vTaskSwitchContext查找最高优先级任务
        
5)恢复任务    vTaskResume
    1.进入临界区
    2.如果任务在挂起列表,从挂起列表移除,并添加到就绪列表
    3.如果恢复任务的优先级大于当前任务的优先级,进行任务切换
    4.退出临界区
    
6)空闲任务    prvIdleTask
    1.prvCheckTasksWaitingTermination 处理待删除任务列表中的待删除任务
        进入临界区
        uxListRemove 从待删除列表中移除
        退出临界区
        prvDeleteTCB直接释放内存
    2.如果存在与空闲任务相同优先级的任务,则进行任务切换
    
7)恢复任务调度器    xTaskResumeAll
    1.进入临界区,变量uxSchedulerSuspended减1
    2.如果uxSchedulerSuspended减到0且当前任务数大于0
        移除等待就绪列表xPendingReadyList的列表项,直至列表为空
        把等待就绪列表的任务移到就绪列表pxReadyTasksLists
        如果移动的任务优先级大于当前的任务优先级,需要做任务调度
    3.调用xTaskIncrementTick保证正确计算阻塞超时时间
    4.退出临界区

8)相对延时    vTaskDelay
    1.挂起调度器
    2.prvAddCurrentTaskToDelayedList 添加当前任务到阻塞列表
        从就绪列表移除
        如果延时时间设置最大,相当于挂起,添加到挂起列表
        记录阻塞超时时间,并记录在列表项值里
        如果阻塞超时时间溢出,将该任务状态列表项添加到溢出阻塞列表
        如果没溢出,添加到阻塞列表pxDelayedTaskList
            阻塞超时时间小于下一个阻塞超时时间,则更新当前这个时间为下一个阻塞超时时间
    3.恢复调度器
    4.进行一次任务切换

列表相关源码

1)列表初始化    vListInitialise
    1.列表中只有xListEnd,因此pxIndex指向xListEnd
    2.xListEnd的值初始化为最大值,用于列表项升序排序时,排在最后
    3.xListEnd的前一个和后一个列表项都为xListEnd本身
    4.列表项数目为0(不含xListEnd)
    
2)列表项初始化    vListInitialiseItem
    1.列表项不属于任何一个列表,所以为空
    
3)插入列表项到尾部  vListInsertEnd
    1.获取列表pxIndex指向的列表项
    2.建立双向连接
        列表项的下一个为pxIndex,列表项的上一个为pxIndex的上一个
        pxIndex的上一个的下一个为列表项,pxIndex的上一个为列表项
    3.更新列表项的所在列表,列表的列表项数目加一
    
4)插入列表项  vListInsert
    1.获取列表项的值
    2.判断值的大小
        如果等于末尾列表项的大小,则插入到末尾列表项前面
        否则遍历列表,找到插入位置
    3.建立双向连接
    4.更新列表项的所在列表,列表的列表项数目加一
    
5)移除列表项    vListRemove
    1.获取列表项的所在列表
    2.更新连接,移除列表项
    3.如果待移除列表项是列表的pxIndex,pxIndex指向为原pxIndex的上一个
    4.列表项所在列表设置为NULL,列表的列表项数目减一

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值