/* Begin Function:_Sys_Pipe_Init *********************************************
Description : The initialization function for the system pipe module.
Input       : None.
Output      : None.
Return      : None.
******************************************************************************/
void _Sys_Pipe_Init(void)
{
#if(ENABLE_PIPE==TRUE)
    cnt_t Pipe_Cnt;
    /* Initialize the two lists */
    Sys_Create_List(&Pipe_Empty_List_Head);
    Sys_Create_List(&Pipe_List_Head);
    /* Clear the whole control block array */
    Sys_Memset((ptr_int_t)Pipe_CB,0,MAX_PIPES*sizeof(struct Pipe));

    /* Put all the pipe control blocks in the empty ones */
    for(Pipe_Cnt=0;Pipe_Cnt<MAX_PIPES;Pipe_Cnt++)
    {
        /* -1 means that the two side of the pipe is not opened */
        Pipe_CB[Pipe_Cnt].Opener_PID[0]=PIPECLOSE;
        Pipe_CB[Pipe_Cnt].Opener_PID[1]=PIPECLOSE;
        
        Pipe_CB[Pipe_Cnt].Pipe_ID=Pipe_Cnt;
        /* Put all of them in the empty list */
        Sys_List_Insert_Node(&(Pipe_CB[Pipe_Cnt].Head),&Pipe_Empty_List_Head,Pipe_Empty_List_Head.Next);
    }
    
    /* Clear the statistical variable */
    Pipe_In_Sys=0;
#endif    
}
/* Begin Function:_Sys_Timer_Init *********************************************
Description : Initialize the system timer module.
Input       : None.
Output      : None.
Return      : None.
******************************************************************************/
void _Sys_Timer_Init(void)									   
{
#if(ENABLE_TIMER==TRUE)	
   cnt_t Tim_Cnt;
    
   /* Initialize the lists */
   Sys_Create_List(&Tim_List_Head);
   Sys_Create_List(&Tim_Empty_List_Head);
    
   Sys_Create_List(&Tim_Running_List_Head);
   Sys_Create_List(&Tim_Stop_List_Head);
   Sys_Create_List(&Tim_Reload_List_Head);
    
   Sys_Create_List(&Proc_Delay_List_Head);
    
   /* Clear the control block */
   Sys_Memset((ptr_int_t)Tim_CB,0,MAX_TIMS*sizeof(struct Timer));
   Sys_Memset((ptr_int_t)PCB_Proc_Delay,0,MAX_PROC_NUM*sizeof(struct PCB_Timer));
    
   /* Put the blocks into the empty list */
   for(Tim_Cnt=0;Tim_Cnt<MAX_TIMS;Tim_Cnt++)
   {
       Tim_CB[Tim_Cnt].Timer_ID=Tim_Cnt;
       Sys_List_Insert_Node(&(Tim_CB[Tim_Cnt].Head),&Tim_Empty_List_Head,Tim_Empty_List_Head.Next);
   }
   
   /* Put the blocks into the empty list */
   for(Tim_Cnt=0;Tim_Cnt<MAX_PROC_NUM;Tim_Cnt++)
   {
       PCB_Proc_Delay[Tim_Cnt].PID=Tim_Cnt;
   }
   
   /* Clear the statistical variable */
   Timer_In_Sys=0;
#endif
}
/*Begin Function:_Sys_Scheduler_Init*******************************************
Description : The system scheduler initialization function.
Input       : None.
Output      : None.
Return      : None.
******************************************************************************/
void  _Sys_Scheduler_Init(void)
{      
    cnt_t Count;
    
    /* Systemis still booting */
    System_Status.Kernel.Boot_Done=FALSE;
    
    /* Clear the statistic variable for the kernel */
    Sys_Memset((ptr_int_t)(&System_Status),0,sizeof(struct Sys_Status_Struct));
    
    /* Initialize the system clock.*/  
    _Sys_Systick_Init(MIN_TIMESLICE_TICK);                                             

    /* Initialize the priority list. We do this to facilitate bidirectional search.
     * We can get the pointer to this priority level when we have the priority level
     * number, and vice versa.
     */
    for(Count=0;Count<MAX_PRIO_NUM;Count++)
    {
        Prio_List[Count].Priority=Count;
        Prio_List[Count].Proc_Num=0;
        Sys_Create_List((struct List_Head*)&(Prio_List[Count].Running_List));
    }

    Sys_Create_List((struct List_Head*)(&Prio_List_Head));

    /* Initialize the list for each possible task slot */
    for(Count=0;Count<MAX_PROC_NUM;Count++)
    {
        PCB[Count].Status.Sleep_Count=1;
        PCB[Count].Status.Status_Lock_Count=0;
        Sys_Create_List((struct List_Head*)(&(PCB[Count].Head))); 
    }
    
    /* Clear the pending system scheduling count */
    Pend_Sched_Cnt=0;
}
/*Begin Function:_Sys_Memory_Init**********************************************
Description : Initiate Memory Pages In A Certain Area.
Input       : u32 Start -The Start Address Of The Area.
			  u32 End -The End Address Of The Area.
Output      : Void.
******************************************************************************/
void _Sys_Memory_Init(u32 Start,u32 End)
{	
	Sys_Memset((u8*)Start,0,End-Start+1);				                       //The Sys_Memset Is Based On Byte.If It Is Based On Word,It Will Cause A HardFault Implicitly When Used To Clear The Last Byte Of The Memory.
}
/*********Begin Function:_Sys_RAMFS_Low_Level_Format********
Description : Low-Level Format The Filesystem At The Assigned Address.For System Use.
Input       : u32 Absolute_Start_Address -The Absolute Start Address Of The Filesystem
              To Be Created.
Output      : Void.   
***********************************************************/
void _Sys_RAMFS_Low_Level_Format_FS(u32* Absolute_Start_Address)
{
	Sys_Memset(Absolute_Start_Address,0,sizeof(struct _RAMFS_MFT)*MAX_FILE_IN_FS+sizeof(struct RAMFS_FILE_BLOCK)*MAX_BLOCK_NUMBER);
}