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 + -
显示快捷键?