#include "LH_TaskManager.h" /* 文件说明:任务管理器源文件 作者: LiuHao 更新日期:2020年3月27日 模块功能:主要解决MCU裸机运行时,多任务管理,使程序能够很好的模块化设计,便于后期维护。 实现思想:参考了FreeROTOS操作系统时间片调度算法实现 */ volatile LH_TaskList ON_Stack,Running_Stack,Suspend_Stack; TaskList_Items LH_UserTsak[TaskNumber]; int (* Running_TaskFun)(void); void TaskManager_Init(void)//三个任务堆栈进行初始化 { char idx; ON_Stack=0,Running_Stack=0;Suspend_Stack = 0; for(idx=0;idxTask_ID == id) { DISABLE_INTERRUPT__ // 关闭总中断 if(List_Item == Suspend_Stack ) Suspend_Stack = List_Item->LIst_Next; else List_Item1->LIst_Next = List_Item->LIst_Next; List_Item->Task_Time = time ; if(time == 0) Add_WaitList(List_Item) ; else Add_TimingList(List_Item) ; ENABLED_INTERRUPT__ // 打开总中断 return 1; // 返回成功 } List_Item1 = List_Item; List_Item = List_Item->LIst_Next; } return 0; // 失败,未找到相应任务 } char Stop_Tasks(char id) // 将任务挂起 { LH_TaskList List_Item,List_Item1; DISABLE_INTERRUPT__ if(ON_Stack != 0) { List_Item1 = List_Item = ON_Stack; while(List_Item != 0) { if(List_Item->Task_ID == id) { DISABLE_INTERRUPT__ // 关闭总中断 if(List_Item == ON_Stack) ON_Stack = List_Item->LIst_Next ; else List_Item1->LIst_Next = List_Item->LIst_Next ; Add_SuspendList(List_Item) ; ENABLED_INTERRUPT__ // 打开总中断 return 1; // 任务挂起成功,返回1 } List_Item1 = List_Item; List_Item = List_Item->LIst_Next; } } if(Running_Stack != 0) { List_Item1 = List_Item = Running_Stack; while(List_Item != 0) { if(List_Item->Task_ID == id) { DISABLE_INTERRUPT__ // 关闭总中断 if(List_Item == Running_Stack) Running_Stack = List_Item->LIst_Next ; else List_Item1->LIst_Next = List_Item->LIst_Next ; Add_SuspendList(List_Item) ; ENABLED_INTERRUPT__ // 打开总中断 return 2; // 任务挂起成功,返回1 } List_Item1 = List_Item; List_Item = List_Item->LIst_Next; } } ENABLED_INTERRUPT__ // 打开总中断 return 0; } char Delete_Tasks(char id) { // 删除任务 LH_TaskList List_Item,List_Item1; Stop_Tasks(id); DISABLE_INTERRUPT__ List_Item1 = List_Item = Suspend_Stack; while(List_Item != 0) { if(List_Item->Task_ID == id) { if(List_Item == Suspend_Stack ) Suspend_Stack = List_Item->LIst_Next; else List_Item1->LIst_Next = List_Item->LIst_Next; List_Item->Task_ID = 0 ; // 删除Task_ID ENABLED_INTERRUPT__ return 1; // 返回成功 } List_Item1 = List_Item; List_Item = List_Item->LIst_Next; } ENABLED_INTERRUPT__ return 0; // 找不到任务 } // 创建定时器 char UserTimerTask_Create(int (*_Fun)(void),int time) { char i; for(i=0;i 0) { Add_TimingList(&LH_UserTsak[idx]); } else { Add_SuspendList(&LH_UserTsak[idx]); } return 1; } } return 0; } void Add_SuspendList(LH_TaskList LHpStack) // 添加任务到挂起列表 { LH_TaskList List_Item; LHpStack->LIst_Next = 0 ; do { if(Suspend_Stack == 0) { Suspend_Stack = LHpStack; break; } List_Item = Suspend_Stack; // 查找表尾 while(List_Item->LIst_Next !=0) { List_Item = List_Item->LIst_Next; } List_Item->LIst_Next = LHpStack; }while(0); } void Add_TimingList(LH_TaskList LHpStack) // 添加任务到定时区 { LH_TaskList List_Item; LHpStack->LIst_Next = 0; do { if(ON_Stack == 0) { ON_Stack = LHpStack; break; } List_Item = ON_Stack; while(List_Item->LIst_Next !=0) { List_Item = List_Item->LIst_Next; } List_Item->LIst_Next = LHpStack; }while(0); } void TaskManager_Scheduling(void) { LH_TaskList list,list1; list1 = list = ON_Stack; // 两个指针指向前后两个任务,便于删除就绪的任务 while(list != 0) { list->Task_Time --; if(list->Task_Time == 0) { if(list == ON_Stack) ON_Stack = list->LIst_Next; else list1->LIst_Next = list->LIst_Next; Add_WaitList(list); } list1 = list; list = list->LIst_Next; } } void Add_WaitList(LH_TaskList LHpStack) { LH_TaskList list; LHpStack->LIst_Next = 0; // 末端任务标志 list = Running_Stack; if(list == 0) // 等待执行列表为空 { Running_Stack = LHpStack; } else { while(list->LIst_Next != 0) { list = list->LIst_Next; } list->LIst_Next = LHpStack ; } } void TaskManager_Run(void) { int time; static int id = 0; LH_TaskList List_Item; while(Running_Stack != 0) { id = Running_Stack->Task_ID; Running_TaskFun = Running_Stack->_Fun; time = (*Running_TaskFun)() ; if(id == Running_Stack->Task_ID) { if(Running_Stack->Task_ID > 0) { List_Item = Running_Stack->LIst_Next; if(time >0) { Running_Stack->Task_Time = time; Add_TimingList(Running_Stack) ; } else { Add_SuspendList(Running_Stack); } Running_Stack = List_Item ; } else { Running_Stack->Task_ID = 0; Running_Stack->_Fun = 0; Running_Stack = Running_Stack->LIst_Next; } } } }