mailbox.c

来自「一种操作系统源码核」· C语言 代码 · 共 549 行 · 第 1/2 页

C
549
字号
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
/*
*********************************************************************************************************
*                                          Mailbox module implement FILE
*********************************************************************************************************
*/

static MAILBOX_MCB *MailboxTable[MAX_MAILBOX_NUM];//邮箱向量表
static void CleanupMailbox(void *information);//邮箱清除函数
static MAILBOX_MCB *    MailboxFreeList; //可用邮箱列表
/*
*********************************************************************************************************
*              获得一个可用的ID号                       

*********************************************************************************************************
*/
static SIGNED _NewMailboxId()
{
	static UNSIGNED Next_ID;
	UNSIGNED  id;			/* process id to return		*/
	EnLock();
	if ((id=Next_ID++) < MAX_MAILBOX_NUM){
   	    	if (MailboxTable[id] == NULL){
	    	UnLock();
		return(id);
	  	}
	}
	else if(MailboxFreeList){
	   	id=MailboxFreeList->id;
	   	#if ENABLE_MEM
			FreeBuff(MailboxFreeList);
	   	#endif
	    	MailboxFreeList=MailboxFreeList->next;
	    	UnLock();
		return(id);
	}
	UnLock();
	return(ERR_MAILBOX_FULL);

}
/*
*********************************************************************************************************
*                                   创建一个邮箱

*********************************************************************************************************
*/
#if ENABLE_MEM
SIGNED CreateMailbox ()
#else
SIGNED CreateMailbox (MAILBOX_MCB *mailbox_ptr)
#endif
{
	SIGNED mailbox_id;
	INT8 err;
	#if ENABLE_MEM
    	MAILBOX_MCB *mailbox_ptr;
    	#endif
    	mailbox_id=_NewMailboxId();
    	if(mailbox_id<0)
        	return (mailbox_id);
	  
  	#if ENABLE_MEM
		err=AllocBuff(KERNAL.event_pool,&(void *)mailbox_ptr,-1);
    		if(err!=OK)
		return (ERR_NO_MEMORY);
   	#else
    		if(!mailbox_ptr) return  ERR_INVALID_MAILBOX;
    		else  if(MailboxTable[mailbox_ptr->id]==mailbox_ptr) return (mailbox_ptr->id);
    	#endif
    	#if DEBUG
        	DebugLog(CREATE_MAILBOX,mailbox_ptr->id);//在日志中记录操作,时间等信息
    	#endif
   	MailboxTable[mailbox_id]=mailbox_ptr;
    	mailbox_ptr->id=mailbox_id;
	mailbox_ptr->current_protect=NULL;
    	mailbox_ptr->suspend_type=FIFO;
    	mailbox_ptr->task_wait_header=NULL;
    	mailbox_ptr->message_area=NULL;
    	return(mailbox_id);

}
/*
*********************************************************************************************************
*                                      删除一个邮箱

*********************************************************************************************************
*/
INT8 DelMailbox(SIGNED mailbox_id)
{

   	INT8 state,oldstate;
   	MAILBOX_MCB *mailbox_ptr;
   	if (mailbox_id<0 || mailbox_id >=MAX_MAILBOX_NUM) {                                 /* Not allowed to Del idle task     */
        	return (ERR_INVALID_MAILBOX);
       	}
   	mailbox_ptr=MailboxTable[mailbox_id];
   	#if DEBUG
        	DebugLog(DELETE_MAILBOX,mailbox_id);//在日志中记录操作,时间等信息
   	#endif
   	DoProtect(mailbox_ptr);
   	if (mailbox_ptr == NULL)                                 /* Not allowed to Del idle mailbox     */
        	return (ERR_INVALID_MAILBOX);
   	while(mailbox_ptr->task_wait_header){
    		state=_ResumeTask(mailbox_ptr->task_wait_header->task_ptr,EVENT_SUSPEND);
		if(state==TRUE) oldstate =state;
		DelHead(&(void *)(mailbox_ptr->task_wait_header));
      	}
   	#if ENABLE_MEM
       		FreeBuff(mailbox_ptr);
   	#endif
  
   	UnProtect(mailbox_ptr);
   	EnLock();
   	mailbox_ptr->next=MailboxFreeList;
   	MailboxFreeList=mailbox_ptr;
   	MailboxTable[mailbox_id]=NULL;
   	UnLock();
   	if(oldstate==TRUE)
      		_ControlToSystem();
   	return (OK);

}
/*
*********************************************************************************************************
*                                      邮箱参数设置函数

*********************************************************************************************************
*/

INT8 SysMailCtl(SIGNED mailbox_id,INT8U cmd,INT8U param)
{
       	STATUS ret;
       	MAILBOX_MCB *mailbox_ptr;
       	if (mailbox_id<0 || mailbox_id >=MAX_MAILBOX_NUM) {                                 /* Not allowed to Del idle task     */
        	return (ERR_INVALID_MAILBOX);
        }
       	mailbox_ptr=MailboxTable[mailbox_id];
     	#if DEBUG
           	DebugLog(SYS_MAILBOX_CTL,mailbox_id);//在日志中记录操作,时间等信息
       	#endif
       	DoProtect(mailbox_ptr);
       	if (mailbox_ptr == NULL)
	  	return (ERR_INVALID_MAILBOX); /* Not allowed is idle task     */
       	switch(cmd){
	   	case SUSPEND_TYPE:
	      		mailbox_ptr->suspend_type=param;
	      		ret=OK;
	      		break;
	   	default:
	      		ret=ERR_INVALID_CMD;
	      		break;
       	}
       	UnProtect(mailbox_ptr);
       	return(ret);
}
static INT8 _AddWaitQueue(MAILBOX_MCB *mailbox_ptr,SIGNED suspend)
{
     	WAIT_QUEUE *task_suspend;
     	#if WAIT_QUEUE_ALLOC_MODE	
        	task_suspend=WaitQueueFreeList;
          	WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
     	#else
          	WAIT_QUEUE  queue_wait_queue;
          	task_suspend=&queue_wait_queue;
          	
     	#endif    
     	if(suspend!=NO_SUSPEND){ //任务等待
          	if((((TASK_TCB *)KERNAL.current_thread)->type) !=TASK){
	   		UnProtect(mailbox_ptr);
	   		return(ERR_INVALID_SUSPEND);
           	}
           	mailbox_ptr->tasks_waiting++;
           	task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
	   	task_suspend->priority=GetPriority(((TASK_TCB *)KERNAL.current_thread)->id);
	   	AddList(&(void *)(mailbox_ptr->task_wait_header),task_suspend,mailbox_ptr->suspend_type);
	   	UnProtect(mailbox_ptr);
	   	_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupMailbox,mailbox_ptr,suspend);
           	_ControlToSystem();
           	Enlock(); 
           	#if WAIT_QUEUE_ALLOC_MODE
 			task_suspend->queue_ptr=WaitQueueFreeList;
 			WaitQueueFreeList=task_suspend;
 		#endif
           	if(mailbox_ptr==NULL){
	       		Unlock();
	       		return(ERR_MAILBOX_DELETED);
	       	}	
           	if (mailbox_ptr->message_area){
               		Unlock();
               		return(ERR_TIMEOUT);
            	}
            	if(mailbox_ptr->task_wait_header==NULL){
               		Unlock();
               		return(ERR_MAILBOX_RESET);
             	}
	    	else {//邮箱消息被另一个任务接收导致邮箱为空,该任务放消息到邮箱
	      
               		mailbox_ptr->tasks_waiting--;
	       		DelList(&(void *)(mailbox_ptr->task_wait_header),task_suspend);
	       		Unlock();
	       		
	       		
	       		return (OK);
             	}
	   
     	}
     	else{
            	UnProtect(mailbox_ptr);
	    	return (ERR_MAILBOX_FULL);
     	}
}     

	
/*
*********************************************************************************************************
*                                     SEND A MESSAGE TO A MAILBOX

*********************************************************************************************************
*/
INT8 SendToMailbox(SIGNED mailbox_id, void *message, SIGNED suspend)
{
 
   	TASK_TCB *task_ptr;
   	INT8 status;
   	MAILBOX_MCB *mailbox_ptr;
   	INT8 ret=OK;
   	if (message == NULL)                                 /* Not allowed to Del idle mailbox     */
        	return (ERR_INVALID_POINTER);  
   	if (mailbox_id<0 || mailbox_id >=MAX_MAILBOX_NUM) {                                 /* Not allowed to Del idle task     */
        	return (ERR_INVALID_MAILBOX);
        }
   	mailbox_ptr=MailboxTable[mailbox_id];
  	#if DEBUG
        	DebugLog(SENDTO_MAILBOX,mailbox_id);//在日志中记录操作,时间等信息
   	#endif
   	DoProtect(mailbox_ptr);
   	if (mailbox_ptr == NULL)                                  /* Not allowed to Del idle mailbox     */
        	return (ERR_INVALID_MAILBOX);
   	if(mailbox_ptr->message_area==NULL){
        	if( mailbox_ptr->task_wait_header){//有任务等待接收消息,恢复任务,消息放入邮箱中的任务的挂起结构的消息域
           		mailbox_ptr->task_wait_header->mail_message=message;
           		task_ptr=(mailbox_ptr->task_wait_header)->task_ptr;
 	   		UnProtect(mailbox_ptr);
	   		status=_ResumeTask(task_ptr,EVENT_SUSPEND);
           		if (status==TRUE)
               		_ControlToSystem();
        	}
        	else{ //邮箱空且无任务在等待,消息放入邮箱,置消息存在标志
           		mailbox_ptr->message_area=message;
           		UnProtect(mailbox_ptr);
           
        	}
       
    	}
    	else{   //邮箱满
        	ret=_AddWaitQueue(mailbox_ptr,suspend);
        	if(ret==OK)
             		mailbox_ptr->message_area=message;
    	}
    	return (ret);


}
/*
*********************************************************************************************************
*    
              广播一条消息到邮箱,当前在邮箱上等待接收消息的任务都接收到该消息并恢复
*********************************************************************************************************
*/
INT8 BroadToMailbox(SIGNED mailbox_id, void *message, SIGNED suspend)
{
     	WAIT_QUEUE *linknode;
       	TASK_TCB *task_ptr;

⌨️ 快捷键说明

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