⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_core.c

📁 模仿ucos ii和RTX Tiny写的一个小操作系统
💻 C
字号:
#include <AT89X52.H>

#include "os_core.h"
#include "main.h"
#include "task_switch.h"
#include "sem.h"
#include "q.h"
#include "uart.h"

//程序控制块
 TCB    OS_TCB[TASK_NUM];
//当前运行任务的优先级
 uint8  OS_Current_ID;
//进入临界段计数器
 uint8  OS_En_Cr_Count;
//任务就绪表
 uint8  OS_TaskRdy_List;
//中断嵌套计数器
 uint8  Int_count;

 uint8  Task_Int_List;
//置位表
uint8 code  OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};


////////////////////////////系统初始化//////////////////////////////////////////////////////
void OS_Init(void)
{  
   uint8 i ; 

   EA=0;                    //关中断

   ET2=1;                   //接受定时器2中断
   T2CON=0x00;         
   T2MOD=0x00;                                  
   RCAP2H=0xB1;
   RCAP2L=0xE0;             //定时时间为10ms  
  
   Int_count=0;			    //中断嵌套为0
   OS_TaskRdy_List=0;       //任务就绪表为0
   OS_Task_Q_List=0;
   OS_En_Cr_Count=0;        //进入临界段为0次

   Task_Int_List=0x00;

   OS_TCB[0].Task_SP=SP+2;	//初始化各任务的堆栈起始地址

   for(i=1;i<TASK_NUM;i++)
    OS_TCB[i].Task_SP=OS_TCB[i-1].Task_SP+(255-OS_TCB[0].Task_SP)/TASK_NUM;

}

///////////////////////////创建一个任务////////////////////////////////////////////////////////
void OS_Task_Create(uint8 Task_Prio,uint8 Task_ID, uint16 Task_PC,uint8  Stack_Bottom) reentrant
{
  OS_ENTER_CRITICAL();
  if(OS_TCB[Task_ID].Status== No_Exist)
 {
   OS_TCB[Task_ID].Status=Exist;              /*任务存在*/
   OS_EXIT_CRITICAL();
   ((uint8 idata *)Stack_Bottom)[0]=Task_PC;        /*将任务入口地址保存在堆栈,压入低8位*/
   ((uint8 idata *)Stack_Bottom)[1]=Task_PC>>8;     /*压入高8位*/

   OS_TCB[Task_ID].Task_SP=Stack_Bottom+1;          /*将该任务的堆栈栈顶地址保存*/
                                  
   OS_TCB[Task_ID].Prio=Task_Prio;            /*任务优先级*/

   OS_TCB[Task_ID].Delay=0;                   /*任务初始不延时*/

   OS_TaskRdy_List|=OSMapTbl[Task_ID];		  /*任务就绪*/

   return ;
 }
  OS_EXIT_CRITICAL();
}

////////////////////////////系统启动///////////////////////////////////////////////////////////
void OS_Start(void)
{

    OS_Current_ID=TASK_NUM-1;

    SP=OS_TCB[OS_Current_ID].Task_SP;   /*修改堆栈指针;使其指向当前任务的堆栈段*/

     TR2=1;             /*启动定时器2*/
     EA=1;              /*开中断*/
}

////////////////////////////系统时钟处理函数//////////////////////////////////////////////////
 void  OS_TimeTick(void)
{
    uint8 i;		
	for(i=0;i<TASK_NUM;i++)        /*处理所有延时*/
  {
       if(OS_TCB[i].Delay)         /*如果任务需要延时*/
      {
          OS_TCB[i].Delay--;       /*延时时间减1*/
        if(OS_TCB[i].Delay==0)     /*如果延时时间到*/
        {
           OSSendSignal(i);	   /*中断中发信号,任务就绪*/
        }  
      }	
  }
}
////////////////////////////////查找下一任务//////////////////////////////////////////////////
void  OS_Find_Next_Task(void)
{

   uint8 tempPrio,i;  
    
    tempPrio=OS_TCB[OS_Current_ID].Prio; 	

    for(i=0;i<TASK_NUM-1;i++)
    { 
	  if((OS_TaskRdy_List&OSMapTbl[i])&&(OS_TCB[i].Prio<tempPrio)) 
     {
	  goto bb;     
     }
	}

    for(i=OS_Current_ID;i<TASK_NUM-1;i++)
    { 
	  if((OS_TaskRdy_List&OSMapTbl[i])&&(OS_TCB[i].Prio==tempPrio)&&i!=OS_Current_ID) 
     {
	  goto bb;     
     }
	}

	if(i==TASK_NUM-1)
   {
	 for(i=0;i<TASK_NUM-1;i++)
	{
	  if(OS_TaskRdy_List&OSMapTbl[i]) 
     {
	  break;       
     }
	}
   }

bb:    OS_Current_ID=i;

}

///////////////////////////定时器2中断服务函数/////////////////////////////////////////////////
#pragma disable        /* 除非最高优先级中断,否则,必须加上这一句 */
void Timer2ISR(void) interrupt 5 
{
       TF2=0;        /*清中断标志TF2*/
       Enter_Int();
#if EN_TIMER_SHARING > 0
       OS_TimeTick();              /* 调用系统时钟处理函数 */
#else
       OSSendSignal(TIME_ISR_TASK_ID);   /* 唤醒ID为TIME_ISR_TASK_ID的任务*/
#endif
       Exit_Int();
}


///////////////////////////任务中给指定任务发送信号///////////////////////////////////////////
 void OSSendSignal(uint8 TaskId) 
{
	if (TaskId < TASK_NUM)
   {
	  OS_ENTER_CRITICAL();
      OS_TaskRdy_List|=OSMapTbl[TaskId ];/*任务就绪*/
      OS_EXIT_CRITICAL();
	  if (Int_count==0)   /*不在中断中*/
     {  
        OSSched(); /*开始任务切换*/
	  }
   }
}
//////////////////////////清除指定任务信号////////////////////////////////////////////////////
void OSClearSignal(uint8 TaskId) 
{
     if(TaskId <TASK_NUM)
    {
        OS_ENTER_CRITICAL();
        OS_TaskRdy_List &= ~OSMapTbl[TaskId];  /*任务不就绪*/
        OS_EXIT_CRITICAL();
	   if(TaskId==OS_Current_ID && Int_count==0) /*挂起自身并不在中断中*/
      {  
	     OSSched();  /*开始任务切换*/
	   }
	}	  
}
//////////////////////////挂起指定任务////////////////////////////////////////////////////////
void OSTaskSuspend(uint8 TaskId)
{
    if (TaskId <TASK_NUM)
   {
       OS_TCB[TaskId].Delay = 0;  /*没有超时处理*/
       OSClearSignal(TaskId);	  /*清除指定任务信号*/
   }
}
/////////////////////////系统等待函数//////////////////////////////////////////////////////////									    
uint8 OSWait(uint8 typ, uint8 ticks)   
{
         OS_TCB[OS_Current_ID].Delay = ticks;  /*设置超时时间*/ 
    switch(typ)
    {
    case K_SIG:                                /*等待信号,即挂起自身*/
		OSTaskSuspend(OS_Current_ID);
        return SIG_EVENT;
    case K_TMO: 
	    SP++;	 
	    *((uint8 data * data *)SP) = ticks;    
        OSClearSignal(OS_Current_ID);		   /*等待超时,即延时一段时间*/
		SP--;	 
	    ticks = (uint8 data *)(*((uint8 data *)SP));
	    if(ticks&&OS_TCB[OS_Current_ID].Delay==0)   /*超时*/
	    {  
         return  TMO_EVENT;
	    }
		 return  SIG_EVENT;
    default:
        OS_TCB[OS_Current_ID].Delay = 0;
        return NOT_OK;
    }
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -