diff --git a/trunk/bootrom/build/libraries/os/ARM11/Makefile b/trunk/bootrom/build/libraries/os/ARM11/Makefile index 0c8fac2..cf2d107 100644 --- a/trunk/bootrom/build/libraries/os/ARM11/Makefile +++ b/trunk/bootrom/build/libraries/os/ARM11/Makefile @@ -38,9 +38,10 @@ SRCS = \ os_exception.c \ os_thread.c \ os_context.c \ + os_mutex.c \ + os_message.c \ os_cache.c \ os_printf.c \ - os_mutex.c \ TARGET_LIB = libos$(BROM_LIBSUFFIX).a diff --git a/trunk/bootrom/build/libraries/os/ARM9/Makefile b/trunk/bootrom/build/libraries/os/ARM9/Makefile index b04c8ba..d6de8b3 100644 --- a/trunk/bootrom/build/libraries/os/ARM9/Makefile +++ b/trunk/bootrom/build/libraries/os/ARM9/Makefile @@ -40,8 +40,9 @@ SRCS = \ os_interrupt.c \ os_exception.c \ os_thread.c \ - os_mutex.c \ os_context.c \ + os_mutex.c \ + os_message.c \ os_cache.c \ os_printf.c \ diff --git a/trunk/bootrom/build/libraries/os/common/os_message.c b/trunk/bootrom/build/libraries/os/common/os_message.c new file mode 100644 index 0000000..dfbd5b4 --- /dev/null +++ b/trunk/bootrom/build/libraries/os/common/os_message.c @@ -0,0 +1,221 @@ +/*---------------------------------------------------------------------------* + Project: TwlSDK - OS + File: os_message.c + + Copyright 2003-2008 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + + *---------------------------------------------------------------------------*/ +#include +#include + +/*---------------------------------------------------------------------------* + Name: osInitMessageQueue + + Description: initialize message queue + + Arguments: mq message queue + msgArray buffer for message queue + msgCount max massage size for buffer + + Returns: None + *---------------------------------------------------------------------------*/ +void osInitMessageQueue(OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount) +{ + osInitThreadQueue(&mq->queueSend); + osInitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; +} + +/*---------------------------------------------------------------------------* + Name: osSendMessage + + Description: send message to message queue + + Arguments: mq message queue + msg massage which is sent + flags whether wait or not when queue is full + + Returns: TRUE if send + + *---------------------------------------------------------------------------*/ +BOOL osSendMessage(OSMessageQueue *mq, OSMessage msg, s32 flags) +{ + OSIntrMode enabled; + s32 lastIndex; + + enabled = osDisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) // check for full queue + { + if (!(flags & OS_MESSAGE_BLOCK)) + { + (void)osRestoreInterrupts(enabled); + return FALSE; + } + else + { + // Yield + osSleepThread(&mq->queueSend); + } + } + + // Store message + lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + mq->msgArray[lastIndex] = msg; + mq->usedCount++; + + // Wakeup receiving threads if any + osWakeupThread(&mq->queueReceive); + + (void)osRestoreInterrupts(enabled); + return TRUE; +} + +/*---------------------------------------------------------------------------* + Name: osReceiveMessage + + Description: receive message from message queue + + Arguments: mq message queue + msg massage which is received + flags whether wait or not when queue is empty + + Returns: TRUE if reveice + + *---------------------------------------------------------------------------*/ +BOOL osReceiveMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags) +{ + OSIntrMode enabled; + + enabled = osDisableInterrupts(); + + while (mq->usedCount == 0) // check for empty queue + { + if (!(flags & OS_MESSAGE_BLOCK)) + { + (void)osRestoreInterrupts(enabled); + return FALSE; + } + else + { + // Yield + osSleepThread(&mq->queueReceive); + } + } + + // Copy-out message + if (msg != NULL) + { + *msg = mq->msgArray[mq->firstIndex]; + } + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + + // Wakeup sending threads if any + osWakeupThread(&mq->queueSend); + + (void)osRestoreInterrupts(enabled); + return TRUE; +} + + +/*---------------------------------------------------------------------------* + Name: osJamMessage + + Description: send message to message queue, cutting in the top of the queue + + Arguments: mq message queue + msg massage which is sent + flags whether wait or not when queue is full + + Returns: TRUE if send + + *---------------------------------------------------------------------------*/ +BOOL osJamMessage(OSMessageQueue *mq, OSMessage msg, s32 flags) +{ + OSIntrMode enabled; + + enabled = osDisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) // check for full queue + { + if (!(flags & OS_MESSAGE_BLOCK)) + { + (void)osRestoreInterrupts(enabled); + return FALSE; + } + else + { + // Yield + osSleepThread(&mq->queueSend); + } + } + + // Store message at the front + mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; + mq->msgArray[mq->firstIndex] = msg; + mq->usedCount++; + + // Wakeup receiving threads if any + osWakeupThread(&mq->queueReceive); + + (void)osRestoreInterrupts(enabled); + return TRUE; +} + + +/*---------------------------------------------------------------------------* + Name: osReadMessage + + Description: read message at message queue. no change in queue + not occur to switch threads. + + Arguments: mq message queue + msg massage which is received + flags whether wait or not when queue is empty + + Returns: TRUE if read + + *---------------------------------------------------------------------------*/ +BOOL osReadMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags) +{ + OSIntrMode enabled; + + enabled = osDisableInterrupts(); + + while (mq->usedCount == 0) // check for empty queue + { + if (!(flags & OS_MESSAGE_BLOCK)) + { + (void)osRestoreInterrupts(enabled); + return FALSE; + } + else + { + // Yield + osSleepThread(&mq->queueReceive); + } + } + + // Copy-out message + if (msg != NULL) + { + *msg = mq->msgArray[mq->firstIndex]; + } + + (void)osRestoreInterrupts(enabled); + return TRUE; +} diff --git a/trunk/bootrom/include/brom/os.h b/trunk/bootrom/include/brom/os.h index b3ce2d4..d7b2cef 100644 --- a/trunk/bootrom/include/brom/os.h +++ b/trunk/bootrom/include/brom/os.h @@ -34,6 +34,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/trunk/bootrom/include/brom/os/common/message.h b/trunk/bootrom/include/brom/os/common/message.h new file mode 100644 index 0000000..5735955 --- /dev/null +++ b/trunk/bootrom/include/brom/os/common/message.h @@ -0,0 +1,165 @@ +/*---------------------------------------------------------------------------* + Project: CtrBrom - OS - include + File: message.h + + Copyright 2009 Nintendo. All rights reserved. + + These coded instructions, statements, and computer programs contain + proprietary information of Nintendo of America Inc. and/or Nintendo + Company Ltd., and are protected by Federal copyright law. They may + not be disclosed to third parties or copied or duplicated in any form, + in whole or in part, without the prior written consent of Nintendo. + + $Date:: $ + $Rev$ + $Author$ + *---------------------------------------------------------------------------*/ +#ifndef BROM_OS_MESSAGE_H_ +#define BROM_OS_MESSAGE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +//-------------------------------------------------------------------------------- +//---- type definition about message +typedef struct OSMessageQueue OSMessageQueue; +typedef void *OSMessage; + +//---- structure of message queue +//#pragma warn_padding off +struct OSMessageQueue +{ + OSThreadQueue queueSend; + OSThreadQueue queueReceive; + OSMessage *msgArray; + s32 msgCount; + s32 firstIndex; + s32 usedCount; +}; +//#pragma warn_padding reset + +//---- Flags to turn blocking on/off when sending/receiving message +#define OS_MESSAGE_NOBLOCK 0 +#define OS_MESSAGE_BLOCK 1 + + + +/*---------------------------------------------------------------------------* + Name: osInitMessageQueue + + Description: initialize message queue + + Arguments: mq message queue + msgArray buffer for message queue + msgCount max massage size for buffer + + Returns: None + *---------------------------------------------------------------------------*/ +void osInitMessageQueue(OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount); + + +/*---------------------------------------------------------------------------* + Name: osSendMessage + + Description: send message to message queue + + Arguments: mq message queue + msg massage which is sent + flags whether wait or not when queue is full + + Returns: TRUE if send + + *---------------------------------------------------------------------------*/ +BOOL osSendMessage(OSMessageQueue *mq, OSMessage msg, s32 flags); + + +/*---------------------------------------------------------------------------* + Name: osReceiveMessage + + Description: receive message from message queue + + Arguments: mq message queue + msg massage which is received + flags whether wait or not when queue is empty + + Returns: TRUE if reveice + + *---------------------------------------------------------------------------*/ +BOOL osReceiveMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags); + + +/*---------------------------------------------------------------------------* + Name: osJamMessage + + Description: send message to message queue, cutting in the top of the queue + + Arguments: mq message queue + msg massage which is sent + flags whether wait or not when queue is empty + + Returns: TRUE if send + + *---------------------------------------------------------------------------*/ +BOOL osJamMessage(OSMessageQueue *mq, OSMessage msg, s32 flags); + + +/*---------------------------------------------------------------------------* + Name: osReadMessageMessage + + Description: read message at message queue. no change to queue + not occur to switch threads. + + Arguments: mq message queue + msg massage which is received + flags whether wait or not when queue is empty + + Returns: TRUE if read + + *---------------------------------------------------------------------------*/ +BOOL osReadMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags); + + +/*---------------------------------------------------------------------------* + Name: osGetMessageCount + + Description: get message count of message queue. + + Arguments: mq message queue + + Returns: message count + + *---------------------------------------------------------------------------*/ +static inline s32 osGetMessageCount(OSMessageQueue *mq) +{ + SDK_ASSERT(mq); + return mq->msgCount; +} + + +/*---------------------------------------------------------------------------* + Name: osIsMessageQueueFull + + Description: get whether message queue is full or not + + Arguments: mq message queue + + Returns: TRUE if full + + *---------------------------------------------------------------------------*/ +static inline BOOL osIsMessageQueueFull(OSMessageQueue *mq) +{ + SDK_ASSERT(mq); + return (mq->usedCount >= mq->msgCount); +} + + +//-------------------------------------------------------------------------------- +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/* BROM_OS_MESSAGE_H_ */ +#endif