?? emos_mbox.c
字號:
/****************************************************************************
*
* (c) Copyright 2001,2008, EMB system, All Rights Reserved.
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF EMB SYSTEM, INC.
* The copyright notice above does not evidence any actual or intended
* publication of such source code.
*
* Subsystem: EMOS
* File: emos_mbox.c
* Author: zenf zhao
* Description: embedded software system MBOX managenent
*
****************************************************************************/
#include "emos_inc.h"
#include "emos_cfg.h"
#include "emos_core.h"
#if EMOS_MBOX_EN
/*********************************************************************************************************
* CREATE A MESSAGE MAILBOX
* Description: This function creates a message mailbox if free event control blocks are available.
* Arguments : msg is a pointer to a message that you wish to deposit in the mailbox. If
* you set this value to the NULL pointer (i.e. (void *)0) then the mailbox
* will be considered empty.
* Returns : != (void *)0 is a pointer to the event control clock (EMOS_EVENT) associated with the
* created mailbox
* == (void *)0 if no event control blocks were available
**********************************************************************************************************/
EMOS_EVENT_T* emosMboxCreate (void *msg)
{
EMOS_EVENT_T* pevent;
if(msg == NULL) return NULL;
EMOS_ENTER_CRITICAL();
pevent = gEmosEventFreeList; /* Get next free event control block */
if (gEmosEventFreeList != (EMOS_EVENT_T*)0)
{
/* See if pool of free ECB pool was empty*/
gEmosEventFreeList = (EMOS_EVENT_T*)gEmosEventFreeList->osEventPtr;
}
EMOS_EXIT_CRITICAL();
if (pevent != (EMOS_EVENT_T*)0)
{
pevent->osEventType = EMOS_EVENT_TYPE_MBOX;
pevent->osEventPtr = msg; /* Deposit message in event control block */
emosEventWaitListInit(pevent);
}
/* Return pointer to event control block, notes one event ID only can contain
one MBox message*/
return (pevent);
}
/*********************************************************************************************************
* ACCEPT MESSAGE FROM MAILBOX
* Description: This function checks the mailbox to see if a message is available. Unlike emosMboxPend(),
* emosMboxAccept() does not suspend the calling task if a message is not available.
* Arguments : pevent is a pointer to the event control block
* Returns : != (void *)0 is the message in the mailbox if one is available. The mailbox is cleared
* so the next time emosMboxAccept() is called, the mailbox will be empty.
* == (void *)0 if the mailbox is empty or if you didn't pass the proper event pointer.
**********************************************************************************************************/
void *emosMboxAccept (EMOS_EVENT_T *pevent)
{
void *msg;
if(NULL == pevent) return NULL;
EMOS_ENTER_CRITICAL();
if (pevent->osEventType != EMOS_EVENT_TYPE_MBOX)
{
/* Validate event block type*/
EMOS_EXIT_CRITICAL();
return ((void *)0);
}
msg = pevent->osEventPtr;
if (msg != (void *)0)
{
/* See if there is already a message*/
pevent->osEventPtr = (void *)0; /* Clear the mailbox*/
}
EMOS_EXIT_CRITICAL();
return (msg); /* Return the message received (or NULL*/
}
/*********************************************************************************************************
* PEND ON MAILBOX FOR A MESSAGE
* Description: This function waits for a message to be sent to a mailbox
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will
* wait for a message to arrive at the mailbox up to the amount of time
* specified by this argument. If you specify 0, however, your task will wait
* forever at the specified mailbox or, until a message arrives.
* err is a pointer to where an error message will be deposited. Possible error
* messages are:
* EMOS_NO_ERR The call was successful and your task received a message.
* EMOS_TIMEOUT A message was not received within the specified timeout
* EMOS_ERR_EVENT_TYPE Invalid event type
* EMOS_ERR_PEND_ISR If you called this function from an ISR and the result
* would lead to a suspension.
* Returns : != (void *)0 is a pointer to the message received
* == (void *)0 if no message was received or you didn't pass the proper pointer to the
* event control block.
**********************************************************************************************************/
void *emosMboxPend (EMOS_EVENT_T* pevent, uint16 timeout, uint8 *err)
{
void *msg;
EMOS_ENTER_CRITICAL();
if (pevent->osEventType != EMOS_EVENT_TYPE_MBOX)
{
/* Validate event block type */
EMOS_EXIT_CRITICAL();
*err = EMOS_ERR_EVENT_TYPE;
return ((void *)0);
}
/*check, whether a msg has pended on the pevent, one pevent only contains
max one msg, this is the condition for MBox*/
msg = pevent->osEventPtr;
if (msg != (void *)0)
{
/* See if there is already a message,
Clear the mailbox and return no error*/
pevent->osEventPtr = (void *)0;
EMOS_EXIT_CRITICAL();
*err = EMOS_NO_ERR;
}
else if (gEmosIntNesting > 0)
{
/* See if called from ISR*/
EMOS_EXIT_CRITICAL(); /*can't PEND from an ISR*/
*err = EMOS_ERR_PEND_ISR;
}
else
{
/* Message not available now, task will pend on mbox to wait*/
gEmosTCBCur->osTCBStat |= EMOS_STAT_MBOX;
gEmosTCBCur->osTCBDly = timeout; /*Load timeout in TCB*/
/*Suspend task on the pevent until event or timeout occurs,
the task will be deleted from the system active scheduler task array table*/
emosEventTaskWait(pevent);
EMOS_EXIT_CRITICAL();
/*Find next highest priority task ready to run*/
emosSched();
/*scheduler return, no other higher task or timeout,
continue check if mbox available, if there is a msg, set to rdy*/
EMOS_ENTER_CRITICAL();
if ((msg = gEmosTCBCur->osTCBMsg) != (void *)0)
{
/* See if we were given the message*/
gEmosTCBCur->osTCBMsg = (void *)0; /* Yes, clear message received*/
gEmosTCBCur->osTCBStat = EMOS_STAT_RDY;
gEmosTCBCur->osTCBEventPtr = (EMOS_EVENT_T*)0; /* No longer waiting for even*/
EMOS_EXIT_CRITICAL();
*err = EMOS_NO_ERR;
}
else if (gEmosTCBCur->osTCBStat & EMOS_STAT_MBOX)
{
/* If status is not EMOS_STAT_RDY, timed out */
emosEventTo(pevent); /* Make task ready*/
EMOS_EXIT_CRITICAL();
msg = (void *)0; /* Set message contents to NULL*/
*err = EMOS_TIMEOUT; /* Indicate that a timeout occured*/
}
else
{
msg = pevent->osEventPtr; /* Message received */
pevent->osEventPtr = (void *)0; /* Clear the mailbox */
gEmosTCBCur->osTCBEventPtr = (EMOS_EVENT_T*)0;
EMOS_EXIT_CRITICAL();
*err = EMOS_NO_ERR;
}
}
return (msg); /* Return the message received (or NULL) */
}
/*********************************************************************************************************
* POST MESSAGE TO A MAILBOX
* Description: This function sends a message to a mailbox
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
* msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
* Returns : EMOS_NO_ERR The call was successful and the message was sent
* EMOS_MBOX_FULL If the mailbox already contains a message. You can can only send one
* message at a time and thus, the message MUST be consumed before you are
* allowed to send another one.
* EMOS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox.
**********************************************************************************************************/
uint8 emosMboxPost (EMOS_EVENT_T* pevent, void *msg)
{
EMOS_ENTER_CRITICAL();
if (pevent->osEventType != EMOS_EVENT_TYPE_MBOX)
{
/* Validate event block type */
EMOS_EXIT_CRITICAL();
return (EMOS_ERR_EVENT_TYPE);
}
/*if more than one task is pended on this pevent */
if (pevent->osEventGrp)
{
/* See if any task pending on mailbox, cause mulple task may use the
same pevent, so Ready the highest priority task waiting on event*/
emosEventTaskRdy(pevent, msg, EMOS_STAT_MBOX);
EMOS_EXIT_CRITICAL();
emosSched(); /* Find highest priority task ready to run */
return (EMOS_NO_ERR);
}
else
{
if (pevent->osEventPtr != (void *)0)
{
/* Make sure mailbox doesn't already have a msg */
EMOS_EXIT_CRITICAL();
return (EMOS_MBOX_FULL);
}
else
{
pevent->osEventPtr = msg; /* Place message in mailbox */
EMOS_EXIT_CRITICAL();
return (EMOS_NO_ERR);
}
}
}
/*********************************************************************************************************
* QUERY A MESSAGE MAILBOX
* Description: This function obtains information about a message mailbox.
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
* pdata is a pointer to a structure that will contain information about the message
* mailbox.
* Returns : EMOS_NO_ERR The call was successful and the message was sent
* EMOS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox.
**********************************************************************************************************/
uint8 emosMboxQuery (EMOS_EVENT_T*pevent, EMOS_MBOX_DATA_T *pdata)
{
uint8 i;
uint8 *psrc;
uint8 *pdest;
EMOS_ENTER_CRITICAL();
if (pevent->osEventType != EMOS_EVENT_TYPE_MBOX)
{
/* Validate event block type */
EMOS_EXIT_CRITICAL();
return (EMOS_ERR_EVENT_TYPE);
}
/* Copy message mailbox wait list */
pdata->osEventGrp = pevent->osEventGrp;
psrc = &pevent->osEventTbl[0];
pdest = &pdata->osEventTbl[0];
for (i = 0; i < EMOS_EVENT_TBL_SIZE; i++)
{
*pdest++ = *psrc++;
}
/* Get message from mailbox */
pdata->osMsg = pevent->osEventPtr;
EMOS_EXIT_CRITICAL();
return (EMOS_NO_ERR);
}
#endif
/*
* Please add "$" around "Id" and "Log".
* $Id$
* $Log$
*
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -