Main Page   Modules   Data Structures   File List   Globals  

message.c

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2002, 2003, Oliver Tscherwitschke
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice,
00009    this list of conditions and the following disclaimer.
00010 2. Redistributions in binary form must reproduce the above copyright notice,
00011    this list of conditions and the following disclaimer in the documentation
00012    and/or other materials provided with the distribution.
00013 3. The name of the author may not be used to endorse or promote products
00014    derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
00017 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
00019 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00021 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
00022 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
00023 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00025 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00041 #include <string.h>
00042 #include <avr/interrupt.h>
00043 
00044 #include "otos_cfg.h"
00045 #include "otos_def.h"
00046 #include "types.h"
00047 #include "memory.h"
00048 #include "task.h"
00049 #include "message.h"
00050 #include "time.h"
00051 
00052 
00053 
00063 OtosMessageQueue* otosCreateMessageQueue(uint8_t size)
00064 {
00065     OtosMessageQueue* pQ;
00066 
00067 
00068     /* allocate memory */
00069     pQ = otosAllocate(sizeof (OtosMessageQueue) + size * sizeof (OtosMessage));
00070     if (pQ == NULL)
00071         return NULL;
00072 
00073     /* init queue */
00074     pQ->size = size;
00075     pQ->in = 0;
00076     pQ->out = 0;
00077     pQ->count = 0;
00078 
00079     return pQ;
00080 }
00081 
00082 
00083 
00101 uint8_t otosSendMessage(OtosMessageQueue* pQueue, OtosMessage* pMsg)
00102 {
00103     OtosTask*   pTmp;
00104     OtosTask*   pNextTask;
00105     uint8_t     dispatch;
00106 
00107 
00108     dispatch = ISR_NOT_ACTIVE();   /* call dispatcher only if not called from an isr */
00109     cli();
00110 
00111     /* message queue full? */
00112     if (pQueue->count == pQueue->size)
00113     {
00114         sei();
00115         return MESSAGE_QUEUE_FULL;
00116     }
00117 
00118     /* copy message in queue */
00119     memcpy(&pQueue->msg[pQueue->in], pMsg, sizeof (OtosMessage));
00120     MQUEUE_INC_IN(pQueue);
00121 
00122     /* if there is a task waiting on this queue wake it */
00123     pTmp = g_pBlockedQueue;
00124     while (pTmp != NULL)
00125     {
00126         pNextTask = pTmp->pNext;            /* remember next task, because after wakeup it is not valid any more */
00127 
00128         if (pTmp->pWaitMsgQueue == pQueue)  /* if task waits on this queue */
00129         {
00130             pTmp->pWaitMsgQueue = NULL;     /* task doesn't wait for a message anymore */
00131             pTmp->sleepTicks = 0;           /* deactivate sleep counter */
00132             otosWakeup(pTmp);
00133         }
00134 
00135         pTmp = pNextTask;
00136     }
00137 
00138     if (dispatch)
00139         otosScheduler(SCHED_NORM);
00140     else
00141         g_performDispatch = TRUE;
00142 
00143     return MESSAGE_SUCCESS;
00144 }
00145 
00146 
00168 uint8_t otosReceiveMessage(OtosMessageQueue* pQueue, OtosMessage* pMsg, uint32_t timeout)
00169 {
00170     cli();
00171 
00172     /* if there is a message in the queue, read it */
00173     if (pQueue->count > 0)
00174     {
00175         memcpy(pMsg, &pQueue->msg[pQueue->out], sizeof (OtosMessage));
00176         MQUEUE_INC_OUT(pQueue);
00177         sei();
00178         return MESSAGE_SUCCESS;
00179     }
00180 
00181     if (timeout == 0)                           /* don't wait */
00182     {
00183         sei();
00184         return MESSAGE_QUEUE_EMPTY;
00185     }
00186     else                                        /* wait */
00187     {
00188         g_pRunningTask->pWaitMsgQueue = pQueue; /* mark that this task waits for a message on this queue */
00189         g_pRunningTask->sleepTicks = (timeout == INFINITE) ? 0 : timeout;   /* ticks to wait */
00190         otosBlock();
00191         cli();
00192         if (g_pRunningTask->pWaitMsgQueue)      /* otosSendMessage must clear this value to indicate message reception */
00193         {
00194             g_pRunningTask->pWaitMsgQueue = NULL;
00195             sei();
00196             return MESSAGE_TIMEOUT;
00197         }
00198         else
00199         {
00200             memcpy(pMsg, &pQueue->msg[pQueue->out], sizeof (OtosMessage));
00201             MQUEUE_INC_OUT(pQueue);
00202             sei();
00203             return MESSAGE_SUCCESS;
00204         }
00205     }
00206 }
00207 
00208 

Generated on Sat Jan 25 18:41:43 2003 for otOS by doxygen1.3-rc2