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

📄 event.c

📁 一种操作系统源码核
💻 C
字号:
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
/*
*********************************************************************************************************
*                                          event module implement FILE
*********************************************************************************************************
*/

static EVENT_ECB *EventTable[MAX_EVENT_NUM];//事件向量表
static void CleanupEvent(void *information); //事件组清除函数
static EVENT_ECB *    EventFreeList;        //可用事件组列表
/*
*********************************************************************************************************
*              获得一个可用的ID号                       

*********************************************************************************************************
*/
static SIGNED _NewEventId()
{
	static UNSIGNED Next_ID;
	UNSIGNED  id;			/* process id to return		*/
        EnLock();
	if ((id=Next_ID++) < MAX_EVENT_NUM){
	    	if (EventTable[id] == NULL){
	        	UnLock();
			return(id);
	    	}
	}
	else if(EventFreeList){
	    	id=EventFreeList->id;
	    	#if ENABLE_MEM
			FreeBuff(EventFreeList);
	    	#endif
	    	EventFreeList=EventFreeList->next;
	    	UnLock();
	    	return(id);
	}
	UnLock();
	return(NO_EVENT_SPACE);

}
/*
*********************************************************************************************************
*                                      CREATE A event Group

*********************************************************************************************************
*/
#if ENABLE_MEM
SIGNED  CreateEventGroup()
#else
SIGNED CreateEventGroup(EVENT_ECB *event_ptr)
#endif
{
   	SIGNED event_id;
   	SIGNED err;
	#if ENABLE_MEM
		EVENT_ECB *event_ptr;
      		err=AllocBuff(KERNAL.event_pool,&(void *)event_ptr,-1);
		if(err!=OK)
			return (ERR_NO_MEMORY);
   	#else
      		if(!event_ptr) return  ERR_INVALID_GROUP;
      		else  if(EventTable[event_ptr->id]==event_ptr)
          		return (event_ptr->id);
	#endif
	event_id=_NewEventId();
	if(event_id<0)
		return (event_id);
      	#if DEBUG
		DebugLog(CREATE_EVENT_GROUP,event_ptr->event_id);//在日志中记录操作,时间等信息
   	#endif
   	EventTable[event_id]=event_ptr;
   	event_ptr->id=event_id;
   	event_ptr->current_protect=NULL;
   	event_ptr->current_events=0;
   	event_ptr->task_wait_header=NULL;
   	return(event_id);

}
/*
*********************************************************************************************************
*                                      删除一个事件组

*********************************************************************************************************
*/
STATUS DelEventGroup(SIGNED event_id)
{
     	STATUS state,oldstate;
     	EVENT_ECB *event_ptr;
     	if (event_id<0 || event_id >MAX_EVENT_NUM) {                                 /* Not allowed to Del idle task     */
		return (ERR_INVALID_EVENT);
        }
     	event_ptr=EventTable[event_id];
       	#if DEBUG
        	DebugLog(DELETE_EVENT_GROUP,event_id);//在日志中记录操作,时间等信息
     	#endif
     	DoProtect(event_ptr);
     	if (event_ptr == NULL)                                 /* Not allowed to Del idle event     */
        	return (ERR_INVALID_GROUP);
     	while(event_ptr->task_wait_header){
        	state=_ResumeTask(event_ptr->task_wait_header->task_ptr,EVENT_SUSPEND);
		if(state==TRUE) oldstate =state;
   	   	DelHead(&(void *)(event_ptr->task_wait_header));
     	}
     	UnProtect(event_ptr);
     	EnLock();
     	event_ptr->next=EventFreeList;
     	EventFreeList=event_ptr;
     	EventTable[event_id]=NULL;
     	UnLock();
     	if(oldstate==TRUE)
        	_ControlToSystem();
     	return (OK);

}
/*
*********************************************************************************************************
*                                     设置事件,事件是一组事件标志(一个事件标志对应一位)的与或组合

*********************************************************************************************************
*/
STATUS SetEvents(SIGNED event_id,UNSIGNED events, INT8U operation)
{
   	WAIT_QUEUE *linknode;
   	TASK_TCB * task_ptr;
   	STATUS status,oldstate;
   	UNSIGNED flags;
   	EVENT_ECB *event_ptr;
   	flags=FALSE;
   	if (event_id<0 || event_id >MAX_EVENT_NUM) {                                 /* Not allowed to Del idle task     */
        	return (ERR_INVALID_EVENT);
    	}
   	event_ptr=EventTable[event_id];
   	if (operation!=AND && operation!=OR){
      		return (ERR_INVALID_OPERATION);
    	}
    	#if DEBUG
      		DebugLog(SET_EVENTS,event_id);//在日志中记录操作,时间等信息
   	#endif
   	DoProtect(event_ptr);
   	if (event_ptr == NULL)                                  /* Not allowed to Del idle event     */
      		return (ERR_INVALID_GROUP);
   	if (operation==AND)
      		(event_ptr->current_events) &= events;
   	else if (operation==OR)
      		(event_ptr->current_events) |= events;
   	if(event_ptr->task_wait_header){//有任务等待信号灯释放,恢复任务
      		linknode=event_ptr->task_wait_header;
      		do{
          		task_ptr=linknode->task_ptr;
     	  		if (linknode->event_operation==AND)  {
	     			if(linknode->event_requested_events==event_ptr->current_events)
	        			flags=TRUE;
	     		}
	     		else if (linknode->event_operation==OR)
				flags=(linknode->event_requested_events) & (event_ptr->current_events);
     	     		if (flags){
				linknode->event_return_status=FINISHED;
				status=_ResumeTask(task_ptr,EVENT_SUSPEND);
				if (status==TRUE) oldstate =status;
              		}
	    	 	linknode=(WAIT_QUEUE *)(linknode->next);
      		}while(linknode!=event_ptr->task_wait_header);
      		UnProtect(event_ptr);
      		if (oldstate==TRUE) _ControlToSystem();
  	}
  	else
      		UnProtect(event_ptr);
     	return (OK);
}
/*
*********************************************************************************************************
*                                 看一个事件组上是否发生请求的事件和获得当前的事件,不能满足时,任务可以挂起等待

*********************************************************************************************************
*/
STATUS RecvEvents(SIGNED event_id, UNSIGNED *requested_events,INT8U operation,SIGNED suspend)
{
   	WAIT_QUEUE *task_suspend;	
   	TASK_TCB *task_ptr;
   	STATUS status;
   	UNSIGNED flags;
   	EVENT_ECB *event_ptr;
   	#if WAIT_QUEUE_ALLOC_MODE
   		task_suspend=WaitQueueFreeList;
      		WaitQueueFreeList=WaitQueueFreeList->queue_ptr;	
      		
   	#else
      		WAIT_QUEUE  event_wait_queue;
      		task_suspend=&event_wait_queue;
   	#endif      
   	if (event_id<0 || event_id >MAX_EVENT_NUM) {                                 /* Not allowed to Del idle task     */
      		return (ERR_INVALID_EVENT);
      	}
   	event_ptr=EventTable[event_id];
   	flags=FALSE;
   	if (requested_events==NULL)
      		return (ERR_INVALID_POINTER);
   	if (operation!=AND && operation!=OR){
      		return (ERR_INVALID_OPERATION);
      	}
    	#if DEBUG
      		DebugLog(RECV_EVENTS,event_id);//在日志中记录操作,时间等信息
   	#endif
   	DoProtect(event_ptr);
   	if (event_ptr == NULL) 
      		return (ERR_INVALID_GROUP);
   	if (operation==AND){
      		if (*requested_events==event_ptr->current_events)
	 		flags=TRUE;
    	}
   	else if (operation==OR)
      		flags=*requested_events & (event_ptr->current_events);
   	if(!flags){   //事件请求不能满足
      		if(suspend!=NO_SUSPEND){//任务挂起
	  		if (((TASK_TCB *)KERNAL.current_thread)->type!=TASK){
	     			UnProtect(event_ptr);
	     			return(ERR_INVALID_SUSPEND);
	   		}
	   		event_ptr->tasks_waiting++;
	   		task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
	   		task_suspend->event_requested_events=*requested_events;
	   		task_suspend->event_operation=operation;
	   		task_suspend->event_return_status=EVENT_SUSPEND;
	   		AddList(&(void *)(event_ptr->task_wait_header),task_suspend,0);
	   		UnProtect(event_ptr);
	   		_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupEvent,event_ptr,suspend);
           		_ControlToSystem();
           		Enlock(); 
           		#if WAIT_QUEUE_ALLOC_MODE
 				task_suspend->queue_ptr=WaitQueueFreeList;
 				WaitQueueFreeList=task_suspend;
 			#endif
 			if(event_ptr==NULL){
	   			Unlock(); 
	      			return(ERR_GROUP_DELETED);
	    		}
	   		if (task_suspend->event_return_status!=FINISHED){
	      			*requested_events=event_ptr->current_events;
              			Unlock(); 
	      			return(ERR_TIMEOUT);
	    		}
	   		event_ptr->tasks_waiting--;
	   		DelList(&(void *)(event_ptr->task_wait_header),task_suspend);
	   		(event_ptr->current_events) &= ~ (*requested_events);
	   		Unlock(); 
	   		
	   		
	  	 	return (OK);

       		}// if(suspend!=NO_SUSPEND){//任务挂起
       		else{
	  		UnProtect(event_ptr);
	  		return (ERR_NOT_PRESENT);
       		}
    	}
    	else{
      		(event_ptr->current_events) &= ~ (*requested_events);
      		UnProtect(event_ptr);
      		return (OK);
   	}

}
/*
*********************************************************************************************************
*                                    在一个事件组上的挂起结构上的某个任务恢复或删除时,清除相应等待列表上的项

*********************************************************************************************************
*/
static void CleanupEvent(void *information)
{
    	EVENT_ECB *event_ptr;
    	TASK_TCB *task_ptr;
    	WAIT_QUEUE *linknode;
    	event_ptr=(EVENT_ECB *)information;
    	UnProtect(event_ptr);
    	EnLock();
    	linknode=event_ptr->task_wait_header;
    	do{
        	task_ptr=linknode->task_ptr;
        	if (task_ptr==((TASK_TCB *)KERNAL.current_thread)){
           		event_ptr->tasks_waiting--;
	   		DelList(&(void *)(event_ptr->task_wait_header),linknode);
	   		#if WAIT_QUEUE_ALLOC_MODE
   				linknode->queue_ptr=WaitQueueFreeList;
 				WaitQueueFreeList=linknode;
      			#endif
		}
        	linknode=(WAIT_QUEUE *)(linknode->next);
		if (linknode==NULL) break;
      	}while(linknode!=event_ptr->task_wait_header);

   	UnLock();
}

/*
*********************************************************************************************************
*                              列出系统中存在的事件组信息

*********************************************************************************************************
*/
STATUS ListEventGroups(SIGNED event_id,EVENT_DATA **event_lst)
{
     	EVENT_ECB *event_ptr;
     	UNSIGNED i;
     	if (event_id+1<0 || event_id >MAX_EVENT_NUM) {                                 /* Not allowed to Del idle task     */
        	return (ERR_INVALID_EVENT);
        }
        
        if(event_id>=0){
     		event_ptr=EventTable[event_id];
       		DoProtect(event_ptr);
     		if (event_ptr == NULL)                                  /* Not allowed to Del idle task     */
        		return (ERR_INVALID_GROUP);
		(*event_lst)->tasks_waiting=event_ptr->tasks_waiting;
		(*event_lst)->current_events= event_ptr->current_events;
		(*event_lst)->task_id=(event_ptr->task_wait_header)->task_ptr->id;
		UnProtect(event_ptr);
		return (OK);
	}
	else{
		for(i=0;i<MAX_EVENT_NUM;i++){
			event_ptr=EventTable[i];
			DoProtect(event_ptr);
			if (event_ptr){                                  /* Not allowed to Del idle task     */
			       (*event_lst)->tasks_waiting=event_ptr->tasks_waiting;
			       (*event_lst)->current_events= event_ptr->current_events;
			       (*event_lst)->task_id=(event_ptr->task_wait_header)->task_ptr->id;
			       (event_lst)++;
     			}     			
     			UnProtect(event_ptr);
     		}	
     		return (OK);	
     	}		

}

/*
*********************************************************************************************************
*                            事件模块的初始化

*********************************************************************************************************
*/
void EventInit(void)
{
   	UNSIGNED i;
   	for(i=0;i<MAX_EVENT_NUM;i++)
     		EventTable[i]=NULL;

}
 

⌨️ 快捷键说明

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