| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- /*
- ************************************************************************************************************************
- * uC/OS-III
- * The Real-Time Kernel
- *
- * (c) Copyright 2009-2011; Micrium, Inc.; Weston, FL
- * All rights reserved. Protected by international copyright laws.
- *
- * MESSAGE HANDLING SERVICES
- *
- * File : OS_MSG.C
- * By : JJL
- * Version : V3.02.00
- *
- * LICENSING TERMS:
- * ---------------
- * uC/OS-III is provided in source form for FREE short-term evaluation, for educational use or
- * for peaceful research. If you plan or intend to use uC/OS-III in a commercial application/
- * product then, you need to contact Micrium to properly license uC/OS-III for its use in your
- * application/product. We provide ALL the source code for your convenience and to help you
- * experience uC/OS-III. The fact that the source is provided does NOT mean that you can use
- * it commercially without paying a licensing fee.
- *
- * Knowledge of the source code may NOT be used to develop a similar product.
- *
- * Please help us continue to provide the embedded community with the finest software available.
- * Your honesty is greatly appreciated.
- *
- * You can contact us at www.micrium.com, or by phone at +1 (954) 217-2036.
- ************************************************************************************************************************
- */
- #include <os.h>
- #ifdef VSC_INCLUDE_SOURCE_FILE_NAMES
- const CPU_CHAR *os_msg__c = "$Id: $";
- #endif
- #if OS_MSG_EN > 0u
- /*
- ************************************************************************************************************************
- * EXTEND THE POOL OF 'OS_MSG'
- *
- * Description: This function is called by your application to add OS_MSGs to the free list of OS_MSGs
- *
- * Arguments : p_msg is a pointer to the base address of an array of OS_MSG and should be declared as follows:
- *
- * OS_MSG MyNewMsgTbl[size];
- *
- * size is the size of the above array
- *
- * p_err is a pointer to a variable that will contain an error code returned by this function.
- *
- * OS_ERR_MSG_POOL_NULL_PTR
- * OS_ERR_MSG_POOL_EMPTY
- * OS_ERR_NONE
- *
- * Returns : none
- ************************************************************************************************************************
- */
- void OSMsgPoolExtend (OS_MSG *p_msg,
- OS_MSG_QTY size,
- OS_ERR *p_err)
- {
- #ifdef OS_SAFETY_CRITICAL
- if (p_err == (OS_ERR *)0) {
- OS_SAFETY_CRITICAL_EXCEPTION();
- return;
- }
- #endif
- #if OS_CFG_ARG_CHK_EN > 0u
- if (p_msg == (OS_MSG *)0) {
- *p_err = OS_ERR_MSG_POOL_NULL_PTR;
- return;
- }
- if (size == (OS_MSG_QTY)0) {
- *p_err = OS_ERR_MSG_POOL_EMPTY;
- return;
- }
- #endif
- OS_MsgPoolCreate(p_msg, /* Create the singly linked list */
- size);
- p_msg[size - 1u].NextPtr = OSMsgPool.NextPtr; /* Link last OS_MSG of new list to current pool */
- OSMsgPool.NextPtr = p_msg;
- OSMsgPool.NbrFree += size; /* All new OS_MSGs are now available */
- *p_err = OS_ERR_NONE;
- }
- /*$PAGE*/
- /*
- ************************************************************************************************************************
- * CREATE A LINKED LIST OF 'OS_MSG'
- *
- * Description: This function is called to create a singly linked list of OS_MSGs which is used as a pool of available
- * OS_MSGs to be used for sending messages.
- *
- * Arguments : p_msg is a pointer to the base address of an array of OS_MSG and should be declared as follows:
- * -----
- * OS_MSG MyMsgTbl[size];
- *
- * size is the size of the above array
- *
- * Returns : none
- *
- * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
- ************************************************************************************************************************
- */
- void OS_MsgPoolCreate (OS_MSG *p_msg,
- OS_MSG_QTY size)
- {
- OS_MSG *p_msg1;
- OS_MSG *p_msg2;
- OS_MSG_QTY i;
- OS_MSG_QTY loops;
- p_msg1 = p_msg;
- p_msg2 = p_msg;
- p_msg2++;
- loops = size - 1u;
- for (i = 0u; i < loops; i++) { /* Init. list of free OS_MSGs */
- p_msg1->NextPtr = p_msg2;
- p_msg1->MsgPtr = (void *)0;
- p_msg1->MsgSize = (OS_MSG_SIZE)0u;
- p_msg1->MsgTS = (CPU_TS )0u;
- p_msg1++;
- p_msg2++;
- }
- p_msg1->NextPtr = (OS_MSG *)0; /* Last OS_MSG */
- p_msg1->MsgPtr = (void *)0;
- p_msg1->MsgSize = (OS_MSG_SIZE)0u;
- p_msg1->MsgTS = (CPU_TS )0u;
- }
- /*$PAGE*/
- /*
- ************************************************************************************************************************
- * INITIALIZE THE POOL OF 'OS_MSG'
- *
- * Description: This function is called by OSInit() to initialize the free list of OS_MSGs.
- *
- * Argument(s): p_err is a pointer to a variable that will contain an error code returned by this function.
- *
- * OS_ERR_MSG_POOL_NULL_PTR
- * OS_ERR_MSG_POOL_EMPTY
- * OS_ERR_NONE
- *
- * Returns : none
- *
- * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
- ************************************************************************************************************************
- */
- void OS_MsgPoolInit (OS_ERR *p_err)
- {
- #ifdef OS_SAFETY_CRITICAL
- if (p_err == (OS_ERR *)0) {
- OS_SAFETY_CRITICAL_EXCEPTION();
- return;
- }
- #endif
- #if OS_CFG_ARG_CHK_EN > 0u
- if (OSCfg_MsgPoolBasePtr == (OS_MSG *)0) {
- *p_err = OS_ERR_MSG_POOL_NULL_PTR;
- return;
- }
- if (OSCfg_MsgPoolSize == (OS_MSG_QTY)0) {
- *p_err = OS_ERR_MSG_POOL_EMPTY;
- return;
- }
- #endif
- OS_MsgPoolCreate(OSCfg_MsgPoolBasePtr,
- OSCfg_MsgPoolSize);
- OSMsgPool.NextPtr = OSCfg_MsgPoolBasePtr;
- OSMsgPool.NbrFree = OSCfg_MsgPoolSize;
- OSMsgPool.NbrUsed = (OS_MSG_QTY)0;
- *p_err = OS_ERR_NONE;
- }
- /*$PAGE*/
- /*
- ************************************************************************************************************************
- * RESET MESSAGE QUEUE ENTRIES PEAK TRACKING
- *
- * Description: This function clear the peak detection mechanism of the message queue
- *
- * Arguments : p_msg_q is a pointer to the OS_MSG_Q structure
- * -------
- *
- * Returns : none
- *
- * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
- ************************************************************************************************************************
- */
- void OS_MsgQEntriesPeakReset (OS_MSG_Q *p_msg_q)
- {
- CPU_SR_ALLOC();
- CPU_CRITICAL_ENTER();
- p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
- CPU_CRITICAL_EXIT();
- }
- /*$PAGE*/
- /*
- ************************************************************************************************************************
- * RELEASE ALL MESSAGE IN MESSAGE QUEUE
- *
- * Description: This function returns all the messages in a message queue to the free list.
- *
- * Arguments : p_msg_q is a pointer to the OS_MSG_Q structure containing messages to free.
- * -------
- *
- * Returns : the number of OS_MSGs returned to the free list
- *
- * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
- ************************************************************************************************************************
- */
- OS_MSG_QTY OS_MsgQFreeAll (OS_MSG_Q *p_msg_q)
- {
- OS_MSG *p_msg;
- OS_MSG_QTY qty;
- qty = p_msg_q->NbrEntries; /* Get the number of OS_MSGs being freed */
- if (p_msg_q->NbrEntries > (OS_MSG_QTY)0) {
- p_msg = p_msg_q->InPtr; /* Point to end of message chain */
- p_msg->NextPtr = OSMsgPool.NextPtr;
- OSMsgPool.NextPtr = p_msg_q->OutPtr; /* Point to beginning of message chain */
- OSMsgPool.NbrUsed -= p_msg_q->NbrEntries; /* Update statistics for free list of messages */
- OSMsgPool.NbrFree += p_msg_q->NbrEntries;
- p_msg_q->NbrEntries = (OS_MSG_QTY)0; /* Flush the message queue */
- p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
- p_msg_q->InPtr = (OS_MSG *)0;
- p_msg_q->OutPtr = (OS_MSG *)0;
- }
- return (qty);
- }
- /*$PAGE*/
- /*
- ************************************************************************************************************************
- * INITIALIZE A MESSAGE QUEUE
- *
- * Description: This function is called to initialize a message queue
- *
- * Arguments : p_msg_q is a pointer to the message queue to initialize
- * -------
- *
- * max is the maximum number of entries that a message queue can have.
- *
- * Returns : none
- *
- * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
- ************************************************************************************************************************
- */
- void OS_MsgQInit (OS_MSG_Q *p_msg_q,
- OS_MSG_QTY size)
- {
- p_msg_q->NbrEntriesSize = (OS_MSG_QTY)size;
- p_msg_q->NbrEntries = (OS_MSG_QTY)0;
- p_msg_q->NbrEntriesMax = (OS_MSG_QTY)0;
- p_msg_q->InPtr = (OS_MSG *)0;
- p_msg_q->OutPtr = (OS_MSG *)0;
- }
- /*$PAGE*/
- /*
- ************************************************************************************************************************
- * RETRIEVE MESSAGE FROM MESSAGE QUEUE
- *
- * Description: This function retrieves a message from a message queue
- *
- * Arguments : p_msg_q is a pointer to the message queue where we want to extract the message from
- * -------
- *
- * p_msg_size is a pointer to where the size (in bytes) of the message will be placed
- *
- * p_ts is a pointer to where the time stamp will be placed
- *
- * p_err is a pointer to an error code that will be returned from this call.
- *
- * OS_ERR_Q_EMPTY
- * OS_ERR_NONE
- *
- * Returns : The message (a pointer)
- *
- * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
- ************************************************************************************************************************
- */
- void *OS_MsgQGet (OS_MSG_Q *p_msg_q,
- OS_MSG_SIZE *p_msg_size,
- CPU_TS *p_ts,
- OS_ERR *p_err)
- {
- OS_MSG *p_msg;
- void *p_void;
- #ifdef OS_SAFETY_CRITICAL
- if (p_err == (OS_ERR *)0) {
- OS_SAFETY_CRITICAL_EXCEPTION();
- return ((void *)0);
- }
- #endif
- if (p_msg_q->NbrEntries == (OS_MSG_QTY)0) {
- *p_msg_size = (OS_MSG_SIZE)0;
- if (p_ts != (CPU_TS *)0) {
- *p_ts = (CPU_TS )0;
- }
- *p_err = OS_ERR_Q_EMPTY;
- return ((void *)0);
- }
- p_msg = p_msg_q->OutPtr;
- p_void = p_msg->MsgPtr;
- *p_msg_size = p_msg->MsgSize;
- if (p_ts != (CPU_TS *)0) {
- *p_ts = p_msg->MsgTS;
- }
- p_msg_q->OutPtr = p_msg->NextPtr;
- if (p_msg_q->OutPtr == (OS_MSG *)0) {
- p_msg_q->InPtr = (OS_MSG *)0;
- p_msg_q->NbrEntries = (OS_MSG_QTY)0;
- } else {
- p_msg_q->NbrEntries--;
- }
- p_msg->NextPtr = OSMsgPool.NextPtr; /* Return message control block to free list */
- OSMsgPool.NextPtr = p_msg;
- OSMsgPool.NbrFree++;
- OSMsgPool.NbrUsed--;
- *p_err = OS_ERR_NONE;
- return (p_void);
- }
- /*
- ************************************************************************************************************************
- * DEPOSIT MESSAGE IN MESSAGE QUEUE
- *
- * Description: This function places a message in a message queue
- *
- * Arguments : p_msg_q is a pointer to the OS_TCB of the task to post the message to
- * -------
- *
- * p_void is a pointer to the message to send.
- *
- * msg_size is the size of the message (in bytes)
- *
- * opt specifies whether the message will be posted in FIFO or LIFO order
- *
- * OS_OPT_POST_FIFO
- * OS_OPT_POST_LIFO
- *
- * ts is a timestamp as to when the message was posted
- *
- * p_err is a pointer to a variable that will contain an error code returned by this function.
- *
- * OS_ERR_Q_MAX if the queue is full
- * OS_ERR_MSG_POOL_EMPTY if we no longer have any OS_MSG to use
- * OS_ERR_NONE the message was deposited in the queue
- *
- * Returns : none
- *
- * Note(s) : 1) This function is INTERNAL to uC/OS-III and your application MUST NOT call it.
- ************************************************************************************************************************
- */
- void OS_MsgQPut (OS_MSG_Q *p_msg_q,
- void *p_void,
- OS_MSG_SIZE msg_size,
- OS_OPT opt,
- CPU_TS ts,
- OS_ERR *p_err)
- {
- OS_MSG *p_msg;
- OS_MSG *p_msg_in;
- #ifdef OS_SAFETY_CRITICAL
- if (p_err == (OS_ERR *)0) {
- OS_SAFETY_CRITICAL_EXCEPTION();
- return;
- }
- #endif
- if (p_msg_q->NbrEntries >= p_msg_q->NbrEntriesSize) {
- *p_err = OS_ERR_Q_MAX; /* Message queue cannot accept any more messages */
- return;
- }
- if (OSMsgPool.NbrFree == (OS_MSG_QTY)0) {
- *p_err = OS_ERR_MSG_POOL_EMPTY; /* No more OS_MSG to use */
- return;
- }
- p_msg = OSMsgPool.NextPtr; /* Remove message control block from free list */
- OSMsgPool.NextPtr = p_msg->NextPtr;
- OSMsgPool.NbrFree--;
- OSMsgPool.NbrUsed++;
- if (p_msg_q->NbrEntries == (OS_MSG_QTY)0) { /* Is this first message placed in the queue? */
- p_msg_q->InPtr = p_msg; /* Yes */
- p_msg_q->OutPtr = p_msg;
- p_msg_q->NbrEntries = (OS_MSG_QTY)1;
- } else {
- if ((opt & OS_OPT_POST_LIFO) == OS_OPT_POST_FIFO) { /* Assume FIFO if not LIFO */
- p_msg_in = p_msg_q->InPtr; /* FIFO */
- p_msg_in->NextPtr = p_msg;
- p_msg->NextPtr = (OS_MSG *)0;
- p_msg_q->InPtr = p_msg;
- } else {
- p_msg->NextPtr = p_msg_q->OutPtr; /* LIFO */
- p_msg_q->OutPtr = p_msg;
- }
- p_msg_q->NbrEntries++;
- }
- if (p_msg_q->NbrEntries > p_msg_q->NbrEntriesMax) {
- p_msg_q->NbrEntriesMax = p_msg_q->NbrEntries;
- }
- p_msg->MsgPtr = p_void; /* Deposit message in the message queue entry */
- p_msg->MsgSize = msg_size;
- p_msg->MsgTS = ts;
- *p_err = OS_ERR_NONE;
- }
- #endif
|