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

📄 pg_sem.c

📁 一个移植到凌阳单片机spce061a上面的实时操作系统
💻 C
字号:
///////////////////////////////////////////////////////////////
//
//
//   PGOS : A Portable,Configable Embedded System Kernel
//
//             
//
//   This is an open source project under GPL lincence  
//
//        Version 0.9.0 ---- Development Snopshot
//
//   File name : pg_sem.c : Semaphores service implemention   
//   History :
//
//          2005-07-24  First build by X.K. @ PGOS Team  
//          
/////////////////////////////////////////////////////////////////

#include <stdlib.h>
#include "pgos.h"


#if  PG_SEM_SUPPORT == 1

pgSEMLIST*  pgos_sem_list ;
pgSEMLIST*  pgos_sem_list_head ;
BYTE  pgos_sem_num ;

extern  BYTE  task_cur_id ;
extern  BYTE  task_cur_prio ;

pgSEMTASK*  pgos_sem_initk()
{
      pgSEMTASK*  Temp ;

      Temp = ( pgSEMTASK * )malloc( sizeof( pgSEMTASK ) ) ;
      if( !Temp )
	  	   return NULL ;
      Temp->state = TASK_SEM_NOTUSE ;
      return Temp ;
}

pgSEMTKLIST*  pgos_sem_initklist()
{
     pgSEMTKLIST*  TempList ;
     pgSEMTKLIST*  TempHead ;
	 
     BYTE  index ;	 

     TempList = ( pgSEMTKLIST * )malloc( sizeof( pgSEMTKLIST ) ) ;
     if( !TempList )
	    	return NULL ;
     TempList->pSem = pgos_sem_initk() ;
     if( !TempList->pSem )
	 	    return NULL ;
     TempHead  = TempList ;
     index = 0;
     for( ; index < MAXSEMWAIT ; index ++ )
     {
        TempList->next = ( pgSEMTKLIST * )malloc( sizeof( pgSEMTKLIST ) ) ;
	      if( !TempList->next )
			     return NULL ;
	      TempList->next ->pSem = pgos_sem_initk() ;
	      if( !TempList->next ->pSem )
			     return NULL ;
	      TempList = TempList->next ;
     }
     	 
     return TempHead ;
}

pgSEMLIST*   pgos_sem_inilist()
{ 
     pgSEMLIST*  TempList ;
     pgSEMLIST*  TempHead ;

     BYTE  index ;	 

     TempList = ( pgSEMLIST * )malloc( sizeof( pgSEMLIST ) ) ;
     if( !TempList )
	 	    return NULL ;
	 
     TempList->list = pgos_sem_initklist() ;
     if( !TempList->list )
	 	    return NULL ;
     TempList->state = SEM_NOTUSE ;
     TempList->tasknum = 0x00;	 
     TempHead  = TempList ;
     index = 0;
     for( ; index < MAXSEM ; index ++ )
     {
        TempList->next = ( pgSEMLIST * )malloc( sizeof( pgSEMLIST ) ) ;
	      if( !TempList->next )
			    return NULL ;
	      TempList->next ->list = pgos_sem_initklist() ;
	      if( !TempList->next ->list )
			    return NULL ;
	      TempList->next->state = SEM_NOTUSE ;
	      TempList->next->tasknum = 0x00 ;	
	      TempList = TempList->next ;
     }
     	 
     return TempHead ;
}


PGOS_STATUS  pgos_sem_addtask( pgSEMTKLIST* list, BYTE id, BYTE mode )
{
     BYTE  index ;
     pgSEMTKLIST*  pList ;
	 
     pList = list ;
     index = 1;	 
     for( ; ; )
     {
          if( pList->pSem->state == TASK_SEM_NOTUSE )
          {
              pList->pSem->id = id ;
		if( mode == TASK_FIRST )
		   pList->pSem->state = TASK_SEM_USING ;
		else
		   pList->pSem->state = TASK_SEM_SUSPEND ;
#if  PG_SEM_PRIO == 1
              pList->pSem->prio = pgos_tk_lookup( id )->prio ;
#endif // SEM_PRIO
		return PGOS_SUCCESS ;
          }
	   index++ ;
	   if( index > MAXSEMWAIT )
	   	 return  PGOS_FAIL_HD ;
	   pList = pList->next ;
     }

     return PGOS_FAIL_HD ;
}
     
PGOS_STATUS  pgos_sem_init()
{
    pgos_sem_list =  pgos_sem_inilist() ;
    if( !pgos_sem_list )
	 	   return PGOS_FAIL_MEM ;
    pgos_sem_list_head = pgos_sem_list ;
    pgos_sem_num = 0x00 ;
    return PGOS_SUCCESS ;
}

PGOS_STATUS  pgos_sem_cre( WORD SemNum )
{    	
    pgos_int_disable() ;
    if( pgos_sem_num + 1 <= MAXSEM  )
    {
    	  pgos_sem_list->Sem = SemNum ;
	  pgos_sem_list->state = SEM_USE ;
	  pgos_sem_list->tasknum = 0 ;
	  pgos_sem_list = pgos_sem_list->next ;
	  pgos_sem_num++ ;
	  pgos_int_enable() ;
	  return  PGOS_SUCCESS ;
    }
    
    pgos_int_enable() ;
    return PGOS_FAIL_NM ;
}

PGOS_STATUS  pgos_sem_wait( WORD SemNum )
{
     pgSEMLIST*  pList ;
     pgTASK*  pTask ;

     pgos_int_disable() ;		 
     pList = pgos_sem_list_head ;

    for( ; pList->state != SEM_NOTUSE ; pList = pList->next )
    {
          if( pList->Sem == SemNum )
          {
                if( pList->tasknum == 0x00 )
                {
                   if(  pgos_sem_addtask( pList->list, task_cur_id, TASK_FIRST ) != PGOS_SUCCESS )
			                 return PGOS_FAIL_NM ;
			             pList->tasknum++ ;		 
			             return  PGOS_SUCCESS ;
                }

		            if( pgos_sem_addtask( pList->list, task_cur_id, TASK_APPEND ) != PGOS_SUCCESS )
		  	          return PGOS_FAIL_NM ;
		            pList->tasknum ++ ;
		            pTask = pgos_tk_lookup( task_cur_id ) ;
		            pTask->state = PG_SUSPEND ;
		            pgos_int_enable() ;
		            pgos_tk_switch() ;
		            return PGOS_SUCCESS ;
          }
    }
    pgos_int_enable() ;
    return  PGOS_FAIL_HD ;
}


PGOS_STATUS  pgos_sem_post( WORD SemNum )
{
   pgSEMLIST*  pSemList ;
	 pgSEMTKLIST*  pSEMTkList ;
   pgTASK*   pTask ;
#if PG_SEM_PRIO == 1
   pgSEMTKLIST*  pSEMTkListNxt ;
   BYTE  id ;
	 BYTE  prio ;  	
#endif
   pgos_int_disable() ;
	 
	 if( pgos_sem_num == 0 )
	 {
	     pgos_int_enable() ;
	 	   return  PGOS_FAIL_NM ;
	 }

	 pSemList = pgos_sem_list_head ;

	 for( ; pSemList->Sem != SemNum ; pSemList = pSemList->next )  ;
	 pSEMTkList = pSemList->list ;
	 if( pSemList->tasknum == 0 )
	 {
	       pgos_int_enable() ;
	       return  PGOS_FAIL_HD ;
	 }
	 for( ; pSEMTkList->pSem->state != TASK_SEM_USING ; pSEMTkList = pSEMTkList->next ) ;
	 pSEMTkList->pSem->state = TASK_SEM_NOTUSE ;
	 pSEMTkList = pSemList->list ;
	 pSemList->tasknum -- ;
	 if( pSemList->tasknum == 0 )
	 	  return PGOS_SUCCESS ;
#if  PG_SEM_FIFO == 1
	 for( ; pSEMTkList->pSem->state != TASK_SEM_SUSPEND ; pSEMTkList = pSEMTkList->next ) ;
        pSEMTkList->pSem->state = TASK_SEM_USING ;
	 pTask = pgos_tk_lookup( pSEMTkList->pSem->id ) ;
#else // SEM_FIFO
#if PG_SEM_PRIO == 1
        pSEMTkListNxt = pSEMTkList ;
        prio = 0 ;
	 for( ; pSEMTkList ; pSEMTkList = pSEMTkList->next )
	 {
	       if( pSEMTkList->pSem->state == TASK_SEM_SUSPEND )
	       {
	           if( pSEMTkList->pSem->prio > prio  )
	           {
	                 prio = pSEMTkList->pSem->prio ;
		               id = pSEMTkList->pSem->id ;
		               pSEMTkListNxt = pSEMTkList ;	  
	           }
	       }
	 }
   pSEMTkList->pSem->state = TASK_SEM_USING ;
	 pTask = pgos_tk_lookup( id ) ;
#endif // SEM_PRIO
#endif // SEM( FIFO&PRIO )
   pTask->state = PG_READY ;
	 if(  pTask->prio > task_cur_prio )
	 {
	 	      pgos_int_enable() ;
	        pgos_tk_switch() ;
	 }
   pgos_int_enable() ;
   return  PGOS_SUCCESS ;
}
	 
#endif // SEM_SUPPORT

⌨️ 快捷键说明

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