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

📄 sem.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"

/////////////////信号量定义////////////////////////////////////////////////////
SemBlk Sem[MAX_SEM];


/////////////////////////////初始化信号量//////////////////////////////////////
void OSSemCreat(uint8 Index,uint8  Count) reentrant 
{ 
  if(Index<MAX_SEM)			     //存在该信号量
 {
  Sem[Index].OSTaskPendTbl=0; 	    //等待信号量的任务列表
  Sem[Index].OSEventCount=Count; 	//信号量 
  }
} 


/////////////////////////任务等待信号量////////////////////////////////////////
uint8 OSTaskSemPend(uint8 Index,uint8 Timeout) reentrant 
{ 
   if(Index<MAX_SEM)			//存在该信号量
 {

   if(Sem[Index].OSEventCount)       //信号量有效 
   {  
	  Sem[Index].OSEventCount -- ;   //减一            
   } 
   else 									
   {                     
      Sem[Index].OSTaskPendTbl|=OSMapTbl[OS_Current_ID];    //加入信号的任务等待表
bb:       	              
      if(OSWait(K_TMO,Timeout)==TMO_EVENT)   //超时
	  {    
	     Sem[Index].OSTaskPendTbl &= ~OSMapTbl[OS_Current_ID];  //从等待表中去除 
	     return SEM_TMO;						    //返时超时
	  }

	  if(Sem[Index].OSTaskPendTbl&OSMapTbl[OS_Current_ID]) //等待表中还有该任务
	     goto bb;					      //不是因为有信号而恢复
   }
   	   return SEM_OK; 		 	//信号量有效  					   				 				
  }	
	   return NOT_OK;
}
										  
///////////////////////////////任务发送信号量///////////////////////////////////
void OSSemPost(uint8 Index) reentrant 
{ 	 
    uint8 i,tempPrio=255; 

    if(Index<MAX_SEM)			      //存在该信号量
  {

     for(i=0;i<TASK_NUM;i++)                      //查找优先级最高的任务
    {
      if(Sem[Index].OSTaskPendTbl&OSMapTbl[i]&&OS_TCB[i].Prio<tempPrio)    
      {
	    tempPrio=OS_TCB[i].Prio;
      }
     }

     for(i=0;i<TASK_NUM;i++)
    { 
       if(Sem[Index].OSTaskPendTbl&OSMapTbl[i]&&OS_TCB[i].Prio==tempPrio)    
      {
		 break;
      }
	}

     if(i < TASK_NUM)                            //如果有任务需要
    { 
	  OS_ENTER_CRITICAL();	                //进入临界区 	
      Sem[Index].OSTaskPendTbl &= ~OSMapTbl[i]; //从等待表中去除 
	  OS_EXIT_CRITICAL();	                //退出临界区 
      OSSendSignal(i);
    } 										   
    else 					//没有任务需要
    { 
      Sem[Index].OSEventCount++;           //使信号量加一
    } 

  }
}



⌨️ 快捷键说明

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