#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;idx<TaskNumber;idx++)
   {
	      LH_UserTsak[idx].Task_ID = 0;       
				LH_UserTsak[idx].LIst_Next = 0;
		    LH_UserTsak[idx]._Fun=0;
   }
}

char Start_Tasks(char id,int time)  //  ������������
{  
	  LH_TaskList List_Item,List_Item1;
      List_Item1 = List_Item = Suspend_Stack;
	  while(List_Item != 0)
	 {	
           if(List_Item->Task_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<TaskNumber;i++)    //  Ѱ�ҵ�ǰ�����Ƿ��Ѿ�������ʱ��
	 {
		  if(LH_UserTsak[i]._Fun == _Fun)  
			{
					LH_UserTsak[i].Task_Time=time;//�ظ�������ֵ�µĶ�ʱʱ��
					return 0;  //  �Ѿ�������ֱ���˳�
			}
	 } 
	 for(i=0;i<TaskNumber;i++)          
	 {  
       if(LH_UserTsak[i].Task_ID == 0)
	   {  		 
				 LH_UserTsak[i].Task_ID   = -1;      
                 LH_UserTsak[i]._Fun  = _Fun;
				 LH_UserTsak[i].Task_Time = time;
				 LH_UserTsak[i].LIst_Next = 0;		
				 Add_TimingList(&LH_UserTsak[i]);	  
				 return 1;  
       }
   } 
   return 0;
}

/*
�������ܣ���������
���������idΪ�����  _FunΪ������  time Ϊ�Ƿ���Ҫ��ʱ
*/
char UserTask_Create(char id,int (*_Fun)(void),int time)
{
	 char idx;
	 for(idx=0;idx<TaskNumber;idx++)   //  �鿴Task_ID�Ƿ�ΪΨһ
	  {
       if(LH_UserTsak[idx].Task_ID == id)
				  return 0;        //   ����0ʧ��
    }
	 for(idx=0;idx<TaskNumber;idx++)        //  Ѱ�ҿ�����ջ
	 {  
      if(LH_UserTsak[idx].Task_ID == 0)
			{  
				 LH_UserTsak[idx].Task_ID   = id;
                 LH_UserTsak[idx]._Fun  = _Fun;
				 LH_UserTsak[idx].Task_Time = time;
				 LH_UserTsak[idx].LIst_Next = 0;
				 
					 if(time > 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;
					}
			  }
     }    
}