949 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			949 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * Copyright (c) 2013-2019 Arm Limited. All rights reserved. | ||
|  |  * | ||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||
|  |  * | ||
|  |  * Licensed under the Apache License, Version 2.0 (the License); you may | ||
|  |  * not use this file except in compliance with the License. | ||
|  |  * You may obtain a copy of the License at | ||
|  |  * | ||
|  |  * www.apache.org/licenses/LICENSE-2.0 | ||
|  |  * | ||
|  |  * Unless required by applicable law or agreed to in writing, software | ||
|  |  * distributed under the License is distributed on an AS IS BASIS, WITHOUT | ||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
|  |  * See the License for the specific language governing permissions and | ||
|  |  * limitations under the License. | ||
|  |  * | ||
|  |  * ----------------------------------------------------------------------------- | ||
|  |  * | ||
|  |  * Project:     CMSIS-RTOS RTX | ||
|  |  * Title:       Message Queue functions | ||
|  |  * | ||
|  |  * ----------------------------------------------------------------------------- | ||
|  |  */ | ||
|  | 
 | ||
|  | #include "rtx_lib.h"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //  OS Runtime Object Memory Usage
 | ||
|  | #if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
 | ||
|  | osRtxObjectMemUsage_t osRtxMessageQueueMemUsage \ | ||
|  | __attribute__((section(".data.os.msgqueue.obj"))) = | ||
|  | { 0U, 0U, 0U }; | ||
|  | #endif
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== Helper functions ====
 | ||
|  | 
 | ||
|  | /// Put a Message into Queue sorted by Priority (Highest at Head).
 | ||
|  | /// \param[in]  mq              message queue object.
 | ||
|  | /// \param[in]  msg             message object.
 | ||
|  | static void MessageQueuePut (os_message_queue_t *mq, os_message_t *msg) { | ||
|  | #if (EXCLUSIVE_ACCESS == 0)
 | ||
|  |   uint32_t      primask = __get_PRIMASK(); | ||
|  | #endif
 | ||
|  |   os_message_t *prev, *next; | ||
|  | 
 | ||
|  |   if (mq->msg_last != NULL) { | ||
|  |     prev = mq->msg_last; | ||
|  |     next = NULL; | ||
|  |     while ((prev != NULL) && (prev->priority < msg->priority)) { | ||
|  |       next = prev; | ||
|  |       prev = prev->prev; | ||
|  |     } | ||
|  |     msg->prev = prev; | ||
|  |     msg->next = next; | ||
|  |     if (prev != NULL) { | ||
|  |       prev->next = msg; | ||
|  |     } else { | ||
|  |       mq->msg_first = msg; | ||
|  |     } | ||
|  |     if (next != NULL) { | ||
|  |       next->prev = msg; | ||
|  |     } else { | ||
|  |       mq->msg_last = msg; | ||
|  |     } | ||
|  |   } else { | ||
|  |     msg->prev = NULL; | ||
|  |     msg->next = NULL; | ||
|  |     mq->msg_first= msg; | ||
|  |     mq->msg_last = msg; | ||
|  |   } | ||
|  | 
 | ||
|  | #if (EXCLUSIVE_ACCESS == 0)
 | ||
|  |   __disable_irq(); | ||
|  | 
 | ||
|  |   mq->msg_count++; | ||
|  | 
 | ||
|  |   if (primask == 0U) { | ||
|  |     __enable_irq(); | ||
|  |   } | ||
|  | #else
 | ||
|  |   (void)atomic_inc32(&mq->msg_count); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | /// Get a Message from Queue with Highest Priority.
 | ||
|  | /// \param[in]  mq              message queue object.
 | ||
|  | /// \return message object or NULL.
 | ||
|  | static os_message_t *MessageQueueGet (os_message_queue_t *mq) { | ||
|  | #if (EXCLUSIVE_ACCESS == 0)
 | ||
|  |   uint32_t      primask = __get_PRIMASK(); | ||
|  | #endif
 | ||
|  |   os_message_t *msg; | ||
|  |   uint32_t      count; | ||
|  |   uint8_t       flags; | ||
|  | 
 | ||
|  | #if (EXCLUSIVE_ACCESS == 0)
 | ||
|  |   __disable_irq(); | ||
|  | 
 | ||
|  |   count = mq->msg_count; | ||
|  |   if (count != 0U) { | ||
|  |     mq->msg_count--; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (primask == 0U) { | ||
|  |     __enable_irq(); | ||
|  |   } | ||
|  | #else
 | ||
|  |   count = atomic_dec32_nz(&mq->msg_count); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |   if (count != 0U) { | ||
|  |     msg = mq->msg_first; | ||
|  | 
 | ||
|  |     while (msg != NULL) { | ||
|  | #if (EXCLUSIVE_ACCESS == 0)
 | ||
|  |       __disable_irq(); | ||
|  | 
 | ||
|  |       flags = msg->flags; | ||
|  |       msg->flags = 1U; | ||
|  | 
 | ||
|  |       if (primask == 0U) { | ||
|  |         __enable_irq(); | ||
|  |       } | ||
|  | #else
 | ||
|  |       flags = atomic_wr8(&msg->flags, 1U); | ||
|  | #endif
 | ||
|  |       if (flags == 0U) { | ||
|  |         break; | ||
|  |       } | ||
|  |       msg = msg->next; | ||
|  |     } | ||
|  |   } else { | ||
|  |     msg = NULL; | ||
|  |   } | ||
|  | 
 | ||
|  |   return msg; | ||
|  | } | ||
|  | 
 | ||
|  | /// Remove a Message from Queue
 | ||
|  | /// \param[in]  mq              message queue object.
 | ||
|  | /// \param[in]  msg             message object.
 | ||
|  | static void MessageQueueRemove (os_message_queue_t *mq, const os_message_t *msg) { | ||
|  | 
 | ||
|  |   if (msg->prev != NULL) { | ||
|  |     msg->prev->next = msg->next; | ||
|  |   } else { | ||
|  |     mq->msg_first = msg->next; | ||
|  |   } | ||
|  |   if (msg->next != NULL) { | ||
|  |     msg->next->prev = msg->prev; | ||
|  |   } else { | ||
|  |     mq->msg_last = msg->prev; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== Post ISR processing ====
 | ||
|  | 
 | ||
|  | /// Message Queue post ISR processing.
 | ||
|  | /// \param[in]  msg             message object.
 | ||
|  | static void osRtxMessageQueuePostProcess (os_message_t *msg) { | ||
|  |   os_message_queue_t *mq; | ||
|  |   os_message_t       *msg0; | ||
|  |   os_thread_t        *thread; | ||
|  |   const uint32_t     *reg; | ||
|  |   const void         *ptr_src; | ||
|  |         void         *ptr_dst; | ||
|  | 
 | ||
|  |   if (msg->flags != 0U) { | ||
|  |     // Remove Message
 | ||
|  |     //lint -e{9079} -e{9087} "cast between pointers to different object types"
 | ||
|  |     mq = *((os_message_queue_t **)(void *)&msg[1]); | ||
|  |     MessageQueueRemove(mq, msg); | ||
|  |     // Free memory
 | ||
|  |     msg->id = osRtxIdInvalid; | ||
|  |     (void)osRtxMemoryPoolFree(&mq->mp_info, msg); | ||
|  |     // Check if Thread is waiting to send a Message
 | ||
|  |     if (mq->thread_list != NULL) { | ||
|  |       // Try to allocate memory
 | ||
|  |       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | ||
|  |       msg0 = osRtxMemoryPoolAlloc(&mq->mp_info); | ||
|  |       if (msg0 != NULL) { | ||
|  |         // Wakeup waiting Thread with highest Priority
 | ||
|  |         thread = osRtxThreadListGet(osRtxObject(mq)); | ||
|  |         osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); | ||
|  |         // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio)
 | ||
|  |         reg = osRtxThreadRegPtr(thread); | ||
|  |         //lint -e{923} "cast from unsigned int to pointer"
 | ||
|  |         ptr_src = (const void *)reg[2]; | ||
|  |         memcpy(&msg0[1], ptr_src, mq->msg_size); | ||
|  |         // Store Message into Queue
 | ||
|  |         msg0->id       = osRtxIdMessage; | ||
|  |         msg0->flags    = 0U; | ||
|  |         msg0->priority = (uint8_t)reg[3]; | ||
|  |         MessageQueuePut(mq, msg0); | ||
|  |         EvrRtxMessageQueueInserted(mq, ptr_src); | ||
|  |       } | ||
|  |     } | ||
|  |   } else { | ||
|  |     // New Message
 | ||
|  |     //lint -e{9079} -e{9087} "cast between pointers to different object types"
 | ||
|  |     mq = (void *)msg->next; | ||
|  |     //lint -e{9087} "cast between pointers to different object types"
 | ||
|  |     ptr_src = (const void *)msg->prev; | ||
|  |     // Check if Thread is waiting to receive a Message
 | ||
|  |     if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) { | ||
|  |       EvrRtxMessageQueueInserted(mq, ptr_src); | ||
|  |       // Wakeup waiting Thread with highest Priority
 | ||
|  |       thread = osRtxThreadListGet(osRtxObject(mq)); | ||
|  |       osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); | ||
|  |       // Copy Message (R2: void *msg_ptr, R3: uint8_t *msg_prio)
 | ||
|  |       reg = osRtxThreadRegPtr(thread); | ||
|  |       //lint -e{923} "cast from unsigned int to pointer"
 | ||
|  |       ptr_dst = (void *)reg[2]; | ||
|  |       memcpy(ptr_dst, &msg[1], mq->msg_size); | ||
|  |       if (reg[3] != 0U) { | ||
|  |         //lint -e{923} -e{9078} "cast from unsigned int to pointer"
 | ||
|  |         *((uint8_t *)reg[3]) = msg->priority; | ||
|  |       } | ||
|  |       EvrRtxMessageQueueRetrieved(mq, ptr_dst); | ||
|  |       // Free memory
 | ||
|  |       msg->id = osRtxIdInvalid; | ||
|  |       (void)osRtxMemoryPoolFree(&mq->mp_info, msg); | ||
|  |     } else { | ||
|  |       EvrRtxMessageQueueInserted(mq, ptr_src); | ||
|  |       MessageQueuePut(mq, msg); | ||
|  |     } | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== Service Calls ====
 | ||
|  | 
 | ||
|  | /// Create and Initialize a Message Queue object.
 | ||
|  | /// \note API identical to osMessageQueueNew
 | ||
|  | static osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { | ||
|  |   os_message_queue_t *mq; | ||
|  |   void               *mq_mem; | ||
|  |   uint32_t            mq_size; | ||
|  |   uint32_t            block_size; | ||
|  |   uint32_t            size; | ||
|  |   uint8_t             flags; | ||
|  |   const char         *name; | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((msg_count == 0U) || (msg_size  == 0U)) { | ||
|  |     EvrRtxMessageQueueError(NULL, (int32_t)osErrorParameter); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return NULL; | ||
|  |   } | ||
|  |   block_size = ((msg_size + 3U) & ~3UL) + sizeof(os_message_t); | ||
|  |   if ((__CLZ(msg_count) + __CLZ(block_size)) < 32U) { | ||
|  |     EvrRtxMessageQueueError(NULL, (int32_t)osErrorParameter); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return NULL; | ||
|  |   } | ||
|  | 
 | ||
|  |   size = msg_count * block_size; | ||
|  | 
 | ||
|  |   // Process attributes
 | ||
|  |   if (attr != NULL) { | ||
|  |     name    = attr->name; | ||
|  |     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
 | ||
|  |     mq      = attr->cb_mem; | ||
|  |     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
 | ||
|  |     mq_mem  = attr->mq_mem; | ||
|  |     mq_size = attr->mq_size; | ||
|  |     if (mq != NULL) { | ||
|  |       //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
 | ||
|  |       if ((((uint32_t)mq & 3U) != 0U) || (attr->cb_size < sizeof(os_message_queue_t))) { | ||
|  |         EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock); | ||
|  |         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |         return NULL; | ||
|  |       } | ||
|  |     } else { | ||
|  |       if (attr->cb_size != 0U) { | ||
|  |         EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock); | ||
|  |         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |         return NULL; | ||
|  |       } | ||
|  |     } | ||
|  |     if (mq_mem != NULL) { | ||
|  |       //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
 | ||
|  |       if ((((uint32_t)mq_mem & 3U) != 0U) || (mq_size < size)) { | ||
|  |         EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory); | ||
|  |         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |         return NULL; | ||
|  |       } | ||
|  |     } else { | ||
|  |       if (mq_size != 0U) { | ||
|  |         EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory); | ||
|  |         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |         return NULL; | ||
|  |       } | ||
|  |     } | ||
|  |   } else { | ||
|  |     name   = NULL; | ||
|  |     mq     = NULL; | ||
|  |     mq_mem = NULL; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Allocate object memory if not provided
 | ||
|  |   if (mq == NULL) { | ||
|  |     if (osRtxInfo.mpi.message_queue != NULL) { | ||
|  |       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | ||
|  |       mq = osRtxMemoryPoolAlloc(osRtxInfo.mpi.message_queue); | ||
|  |     } else { | ||
|  |       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | ||
|  |       mq = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_message_queue_t), 1U); | ||
|  |     } | ||
|  | #if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
 | ||
|  |     if (mq != NULL) { | ||
|  |       uint32_t used; | ||
|  |       osRtxMessageQueueMemUsage.cnt_alloc++; | ||
|  |       used = osRtxMessageQueueMemUsage.cnt_alloc - osRtxMessageQueueMemUsage.cnt_free; | ||
|  |       if (osRtxMessageQueueMemUsage.max_used < used) { | ||
|  |         osRtxMessageQueueMemUsage.max_used = used; | ||
|  |       } | ||
|  |     } | ||
|  | #endif
 | ||
|  |     flags = osRtxFlagSystemObject; | ||
|  |   } else { | ||
|  |     flags = 0U; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Allocate data memory if not provided
 | ||
|  |   if ((mq != NULL) && (mq_mem == NULL)) { | ||
|  |     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | ||
|  |     mq_mem = osRtxMemoryAlloc(osRtxInfo.mem.mq_data, size, 0U); | ||
|  |     if (mq_mem == NULL) { | ||
|  |       if ((flags & osRtxFlagSystemObject) != 0U) { | ||
|  |         if (osRtxInfo.mpi.message_queue != NULL) { | ||
|  |           (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq); | ||
|  |         } else { | ||
|  |           (void)osRtxMemoryFree(osRtxInfo.mem.common, mq); | ||
|  |         } | ||
|  | #if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
 | ||
|  |         osRtxMessageQueueMemUsage.cnt_free++; | ||
|  | #endif
 | ||
|  |       } | ||
|  |       mq = NULL; | ||
|  |     } else { | ||
|  |       memset(mq_mem, 0, size); | ||
|  |     } | ||
|  |     flags |= osRtxFlagSystemMemory; | ||
|  |   } | ||
|  | 
 | ||
|  |   if (mq != NULL) { | ||
|  |     // Initialize control block
 | ||
|  |     mq->id          = osRtxIdMessageQueue; | ||
|  |     mq->flags       = flags; | ||
|  |     mq->name        = name; | ||
|  |     mq->thread_list = NULL; | ||
|  |     mq->msg_size    = msg_size; | ||
|  |     mq->msg_count   = 0U; | ||
|  |     mq->msg_first   = NULL; | ||
|  |     mq->msg_last    = NULL; | ||
|  |     (void)osRtxMemoryPoolInit(&mq->mp_info, msg_count, block_size, mq_mem); | ||
|  | 
 | ||
|  |     // Register post ISR processing function
 | ||
|  |     osRtxInfo.post_process.message = osRtxMessageQueuePostProcess; | ||
|  | 
 | ||
|  |     EvrRtxMessageQueueCreated(mq, mq->name); | ||
|  |   } else { | ||
|  |     EvrRtxMessageQueueError(NULL, (int32_t)osErrorNoMemory); | ||
|  |   } | ||
|  | 
 | ||
|  |   return mq; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get name of a Message Queue object.
 | ||
|  | /// \note API identical to osMessageQueueGetName
 | ||
|  | static const char *svcRtxMessageQueueGetName (osMessageQueueId_t mq_id) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { | ||
|  |     EvrRtxMessageQueueGetName(mq, NULL); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return NULL; | ||
|  |   } | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueGetName(mq, mq->name); | ||
|  | 
 | ||
|  |   return mq->name; | ||
|  | } | ||
|  | 
 | ||
|  | /// Put a Message into a Queue or timeout if Queue is full.
 | ||
|  | /// \note API identical to osMessageQueuePut
 | ||
|  | static osStatus_t svcRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  |   os_message_t       *msg; | ||
|  |   os_thread_t        *thread; | ||
|  |   uint32_t           *reg; | ||
|  |   void               *ptr; | ||
|  |   osStatus_t          status; | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) { | ||
|  |     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osErrorParameter; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Check if Thread is waiting to receive a Message
 | ||
|  |   if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) { | ||
|  |     EvrRtxMessageQueueInserted(mq, msg_ptr); | ||
|  |     // Wakeup waiting Thread with highest Priority
 | ||
|  |     thread = osRtxThreadListGet(osRtxObject(mq)); | ||
|  |     osRtxThreadWaitExit(thread, (uint32_t)osOK, TRUE); | ||
|  |     // Copy Message (R2: void *msg_ptr, R3: uint8_t *msg_prio)
 | ||
|  |     reg = osRtxThreadRegPtr(thread); | ||
|  |     //lint -e{923} "cast from unsigned int to pointer"
 | ||
|  |     ptr = (void *)reg[2]; | ||
|  |     memcpy(ptr, msg_ptr, mq->msg_size); | ||
|  |     if (reg[3] != 0U) { | ||
|  |       //lint -e{923} -e{9078} "cast from unsigned int to pointer"
 | ||
|  |       *((uint8_t *)reg[3]) = msg_prio; | ||
|  |     } | ||
|  |     EvrRtxMessageQueueRetrieved(mq, ptr); | ||
|  |     status = osOK; | ||
|  |   } else { | ||
|  |     // Try to allocate memory
 | ||
|  |     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | ||
|  |     msg = osRtxMemoryPoolAlloc(&mq->mp_info); | ||
|  |     if (msg != NULL) { | ||
|  |       // Copy Message
 | ||
|  |       memcpy(&msg[1], msg_ptr, mq->msg_size); | ||
|  |       // Put Message into Queue
 | ||
|  |       msg->id       = osRtxIdMessage; | ||
|  |       msg->flags    = 0U; | ||
|  |       msg->priority = msg_prio; | ||
|  |       MessageQueuePut(mq, msg); | ||
|  |       EvrRtxMessageQueueInserted(mq, msg_ptr); | ||
|  |       status = osOK; | ||
|  |     } else { | ||
|  |       // No memory available
 | ||
|  |       if (timeout != 0U) { | ||
|  |         EvrRtxMessageQueuePutPending(mq, msg_ptr, timeout); | ||
|  |         // Suspend current Thread
 | ||
|  |         if (osRtxThreadWaitEnter(osRtxThreadWaitingMessagePut, timeout)) { | ||
|  |           osRtxThreadListPut(osRtxObject(mq), osRtxThreadGetRunning()); | ||
|  |           // Save arguments (R2: const void *msg_ptr, R3: uint8_t msg_prio)
 | ||
|  |           //lint -e{923} -e{9078} "cast from unsigned int to pointer"
 | ||
|  |           reg = (uint32_t *)(__get_PSP()); | ||
|  |           //lint -e{923} -e{9078} "cast from pointer to unsigned int"
 | ||
|  |           reg[2] = (uint32_t)msg_ptr; | ||
|  |           //lint -e{923} -e{9078} "cast from pointer to unsigned int"
 | ||
|  |           reg[3] = (uint32_t)msg_prio; | ||
|  |         } else { | ||
|  |           EvrRtxMessageQueuePutTimeout(mq); | ||
|  |         } | ||
|  |         status = osErrorTimeout; | ||
|  |       } else { | ||
|  |         EvrRtxMessageQueueNotInserted(mq, msg_ptr); | ||
|  |         status = osErrorResource; | ||
|  |       } | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get a Message from a Queue or timeout if Queue is empty.
 | ||
|  | /// \note API identical to osMessageQueueGet
 | ||
|  | static osStatus_t svcRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  |   os_message_t       *msg; | ||
|  |   os_thread_t        *thread; | ||
|  |   uint32_t           *reg; | ||
|  |   const void         *ptr; | ||
|  |   osStatus_t          status; | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) { | ||
|  |     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osErrorParameter; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Get Message from Queue
 | ||
|  |   msg = MessageQueueGet(mq); | ||
|  |   if (msg != NULL) { | ||
|  |     MessageQueueRemove(mq, msg); | ||
|  |     // Copy Message
 | ||
|  |     memcpy(msg_ptr, &msg[1], mq->msg_size); | ||
|  |     if (msg_prio != NULL) { | ||
|  |       *msg_prio = msg->priority; | ||
|  |     } | ||
|  |     EvrRtxMessageQueueRetrieved(mq, msg_ptr); | ||
|  |     // Free memory
 | ||
|  |     msg->id = osRtxIdInvalid; | ||
|  |     (void)osRtxMemoryPoolFree(&mq->mp_info, msg); | ||
|  |     // Check if Thread is waiting to send a Message
 | ||
|  |     if (mq->thread_list != NULL) { | ||
|  |       // Try to allocate memory
 | ||
|  |       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | ||
|  |       msg = osRtxMemoryPoolAlloc(&mq->mp_info); | ||
|  |       if (msg != NULL) { | ||
|  |         // Wakeup waiting Thread with highest Priority
 | ||
|  |         thread = osRtxThreadListGet(osRtxObject(mq)); | ||
|  |         osRtxThreadWaitExit(thread, (uint32_t)osOK, TRUE); | ||
|  |         // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio)
 | ||
|  |         reg = osRtxThreadRegPtr(thread); | ||
|  |         //lint -e{923} "cast from unsigned int to pointer"
 | ||
|  |         ptr = (const void *)reg[2]; | ||
|  |         memcpy(&msg[1], ptr, mq->msg_size); | ||
|  |         // Store Message into Queue
 | ||
|  |         msg->id       = osRtxIdMessage; | ||
|  |         msg->flags    = 0U; | ||
|  |         msg->priority = (uint8_t)reg[3]; | ||
|  |         MessageQueuePut(mq, msg); | ||
|  |         EvrRtxMessageQueueInserted(mq, ptr); | ||
|  |       } | ||
|  |     } | ||
|  |     status = osOK; | ||
|  |   } else { | ||
|  |     // No Message available
 | ||
|  |     if (timeout != 0U) { | ||
|  |       EvrRtxMessageQueueGetPending(mq, msg_ptr, timeout); | ||
|  |       // Suspend current Thread
 | ||
|  |       if (osRtxThreadWaitEnter(osRtxThreadWaitingMessageGet, timeout)) { | ||
|  |         osRtxThreadListPut(osRtxObject(mq), osRtxThreadGetRunning()); | ||
|  |         // Save arguments (R2: void *msg_ptr, R3: uint8_t *msg_prio)
 | ||
|  |         //lint -e{923} -e{9078} "cast from unsigned int to pointer"
 | ||
|  |         reg = (uint32_t *)(__get_PSP()); | ||
|  |         //lint -e{923} -e{9078} "cast from pointer to unsigned int"
 | ||
|  |         reg[2] = (uint32_t)msg_ptr; | ||
|  |         //lint -e{923} -e{9078} "cast from pointer to unsigned int"
 | ||
|  |         reg[3] = (uint32_t)msg_prio; | ||
|  |       } else { | ||
|  |         EvrRtxMessageQueueGetTimeout(mq); | ||
|  |       } | ||
|  |       status = osErrorTimeout; | ||
|  |     } else { | ||
|  |       EvrRtxMessageQueueNotRetrieved(mq, msg_ptr); | ||
|  |       status = osErrorResource; | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get maximum number of messages in a Message Queue.
 | ||
|  | /// \note API identical to osMessageQueueGetCapacity
 | ||
|  | static uint32_t svcRtxMessageQueueGetCapacity (osMessageQueueId_t mq_id) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { | ||
|  |     EvrRtxMessageQueueGetCapacity(mq, 0U); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return 0U; | ||
|  |   } | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueGetCapacity(mq, mq->mp_info.max_blocks); | ||
|  | 
 | ||
|  |   return mq->mp_info.max_blocks; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get maximum message size in a Memory Pool.
 | ||
|  | /// \note API identical to osMessageQueueGetMsgSize
 | ||
|  | static uint32_t svcRtxMessageQueueGetMsgSize (osMessageQueueId_t mq_id) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { | ||
|  |     EvrRtxMessageQueueGetMsgSize(mq, 0U); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return 0U; | ||
|  |   } | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueGetMsgSize(mq, mq->msg_size); | ||
|  | 
 | ||
|  |   return mq->msg_size; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get number of queued messages in a Message Queue.
 | ||
|  | /// \note API identical to osMessageQueueGetCount
 | ||
|  | static uint32_t svcRtxMessageQueueGetCount (osMessageQueueId_t mq_id) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { | ||
|  |     EvrRtxMessageQueueGetCount(mq, 0U); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return 0U; | ||
|  |   } | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueGetCount(mq, mq->msg_count); | ||
|  | 
 | ||
|  |   return mq->msg_count; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get number of available slots for messages in a Message Queue.
 | ||
|  | /// \note API identical to osMessageQueueGetSpace
 | ||
|  | static uint32_t svcRtxMessageQueueGetSpace (osMessageQueueId_t mq_id) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { | ||
|  |     EvrRtxMessageQueueGetSpace(mq, 0U); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return 0U; | ||
|  |   } | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueGetSpace(mq, mq->mp_info.max_blocks - mq->msg_count); | ||
|  | 
 | ||
|  |   return (mq->mp_info.max_blocks - mq->msg_count); | ||
|  | } | ||
|  | 
 | ||
|  | /// Reset a Message Queue to initial empty state.
 | ||
|  | /// \note API identical to osMessageQueueReset
 | ||
|  | static osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  |   os_message_t       *msg; | ||
|  |   os_thread_t        *thread; | ||
|  |   const uint32_t     *reg; | ||
|  |   const void         *ptr; | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { | ||
|  |     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osErrorParameter; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Remove Messages from Queue
 | ||
|  |   for (;;) { | ||
|  |     // Get Message from Queue
 | ||
|  |     msg = MessageQueueGet(mq); | ||
|  |     if (msg == NULL) { | ||
|  |       break; | ||
|  |     } | ||
|  |     MessageQueueRemove(mq, msg); | ||
|  |     EvrRtxMessageQueueRetrieved(mq, NULL); | ||
|  |     // Free memory
 | ||
|  |     msg->id = osRtxIdInvalid; | ||
|  |     (void)osRtxMemoryPoolFree(&mq->mp_info, msg); | ||
|  |   } | ||
|  | 
 | ||
|  |   // Check if Threads are waiting to send Messages
 | ||
|  |   if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) { | ||
|  |     do { | ||
|  |       // Try to allocate memory
 | ||
|  |       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | ||
|  |       msg = osRtxMemoryPoolAlloc(&mq->mp_info); | ||
|  |       if (msg != NULL) { | ||
|  |         // Wakeup waiting Thread with highest Priority
 | ||
|  |         thread = osRtxThreadListGet(osRtxObject(mq)); | ||
|  |         osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE); | ||
|  |         // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio)
 | ||
|  |         reg = osRtxThreadRegPtr(thread); | ||
|  |         //lint -e{923} "cast from unsigned int to pointer"
 | ||
|  |         ptr = (const void *)reg[2]; | ||
|  |         memcpy(&msg[1], ptr, mq->msg_size); | ||
|  |         // Store Message into Queue
 | ||
|  |         msg->id       = osRtxIdMessage; | ||
|  |         msg->flags    = 0U; | ||
|  |         msg->priority = (uint8_t)reg[3]; | ||
|  |         MessageQueuePut(mq, msg); | ||
|  |         EvrRtxMessageQueueInserted(mq, ptr); | ||
|  |       } | ||
|  |     } while ((msg != NULL) && (mq->thread_list != NULL)); | ||
|  |     osRtxThreadDispatch(NULL); | ||
|  |   } | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueResetDone(mq); | ||
|  | 
 | ||
|  |   return osOK; | ||
|  | } | ||
|  | 
 | ||
|  | /// Delete a Message Queue object.
 | ||
|  | /// \note API identical to osMessageQueueDelete
 | ||
|  | static osStatus_t svcRtxMessageQueueDelete (osMessageQueueId_t mq_id) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  |   os_thread_t        *thread; | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) { | ||
|  |     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osErrorParameter; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Unblock waiting threads
 | ||
|  |   if (mq->thread_list != NULL) { | ||
|  |     do { | ||
|  |       thread = osRtxThreadListGet(osRtxObject(mq)); | ||
|  |       osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE); | ||
|  |     } while (mq->thread_list != NULL); | ||
|  |     osRtxThreadDispatch(NULL); | ||
|  |   } | ||
|  | 
 | ||
|  |   // Mark object as invalid
 | ||
|  |   mq->id = osRtxIdInvalid; | ||
|  | 
 | ||
|  |   // Free data memory
 | ||
|  |   if ((mq->flags & osRtxFlagSystemMemory) != 0U) { | ||
|  |     (void)osRtxMemoryFree(osRtxInfo.mem.mq_data, mq->mp_info.block_base); | ||
|  |   } | ||
|  | 
 | ||
|  |   // Free object memory
 | ||
|  |   if ((mq->flags & osRtxFlagSystemObject) != 0U) { | ||
|  |     if (osRtxInfo.mpi.message_queue != NULL) { | ||
|  |       (void)osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq); | ||
|  |     } else { | ||
|  |       (void)osRtxMemoryFree(osRtxInfo.mem.common, mq); | ||
|  |     } | ||
|  | #if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
 | ||
|  |     osRtxMessageQueueMemUsage.cnt_free++; | ||
|  | #endif
 | ||
|  |   } | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueDestroyed(mq); | ||
|  | 
 | ||
|  |   return osOK; | ||
|  | } | ||
|  | 
 | ||
|  | //  Service Calls definitions
 | ||
|  | //lint ++flb "Library Begin" [MISRA Note 11]
 | ||
|  | SVC0_3(MessageQueueNew,         osMessageQueueId_t, uint32_t, uint32_t, const osMessageQueueAttr_t *) | ||
|  | SVC0_1(MessageQueueGetName,     const char *,       osMessageQueueId_t) | ||
|  | SVC0_4(MessageQueuePut,         osStatus_t,         osMessageQueueId_t, const void *, uint8_t,   uint32_t) | ||
|  | SVC0_4(MessageQueueGet,         osStatus_t,         osMessageQueueId_t,       void *, uint8_t *, uint32_t) | ||
|  | SVC0_1(MessageQueueGetCapacity, uint32_t,           osMessageQueueId_t) | ||
|  | SVC0_1(MessageQueueGetMsgSize,  uint32_t,           osMessageQueueId_t) | ||
|  | SVC0_1(MessageQueueGetCount,    uint32_t,           osMessageQueueId_t) | ||
|  | SVC0_1(MessageQueueGetSpace,    uint32_t,           osMessageQueueId_t) | ||
|  | SVC0_1(MessageQueueReset,       osStatus_t,         osMessageQueueId_t) | ||
|  | SVC0_1(MessageQueueDelete,      osStatus_t,         osMessageQueueId_t) | ||
|  | //lint --flb "Library End"
 | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== ISR Calls ====
 | ||
|  | 
 | ||
|  | /// Put a Message into a Queue or timeout if Queue is full.
 | ||
|  | /// \note API identical to osMessageQueuePut
 | ||
|  | __STATIC_INLINE | ||
|  | osStatus_t isrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  |   os_message_t       *msg; | ||
|  |   osStatus_t          status; | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) { | ||
|  |     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osErrorParameter; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Try to allocate memory
 | ||
|  |   //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | ||
|  |   msg = osRtxMemoryPoolAlloc(&mq->mp_info); | ||
|  |   if (msg != NULL) { | ||
|  |     // Copy Message
 | ||
|  |     memcpy(&msg[1], msg_ptr, mq->msg_size); | ||
|  |     msg->id       = osRtxIdMessage; | ||
|  |     msg->flags    = 0U; | ||
|  |     msg->priority = msg_prio; | ||
|  |     // Register post ISR processing
 | ||
|  |     //lint -e{9079} -e{9087} "cast between pointers to different object types"
 | ||
|  |     *((const void **)(void *)&msg->prev) = msg_ptr; | ||
|  |     //lint -e{9079} -e{9087} "cast between pointers to different object types"
 | ||
|  |     *(      (void **)        &msg->next) = mq; | ||
|  |     osRtxPostProcess(osRtxObject(msg)); | ||
|  |     EvrRtxMessageQueueInsertPending(mq, msg_ptr); | ||
|  |     status = osOK; | ||
|  |   } else { | ||
|  |     // No memory available
 | ||
|  |     EvrRtxMessageQueueNotInserted(mq, msg_ptr); | ||
|  |     status = osErrorResource; | ||
|  |   } | ||
|  | 
 | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get a Message from a Queue or timeout if Queue is empty.
 | ||
|  | /// \note API identical to osMessageQueueGet
 | ||
|  | __STATIC_INLINE | ||
|  | osStatus_t isrRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { | ||
|  |   os_message_queue_t *mq = osRtxMessageQueueId(mq_id); | ||
|  |   os_message_t       *msg; | ||
|  |   osStatus_t          status; | ||
|  | 
 | ||
|  |   // Check parameters
 | ||
|  |   if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) { | ||
|  |     EvrRtxMessageQueueError(mq, (int32_t)osErrorParameter); | ||
|  |     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | ||
|  |     return osErrorParameter; | ||
|  |   } | ||
|  | 
 | ||
|  |   // Get Message from Queue
 | ||
|  |   msg = MessageQueueGet(mq); | ||
|  |   if (msg != NULL) { | ||
|  |     // Copy Message
 | ||
|  |     memcpy(msg_ptr, &msg[1], mq->msg_size); | ||
|  |     if (msg_prio != NULL) { | ||
|  |       *msg_prio = msg->priority; | ||
|  |     } | ||
|  |     // Register post ISR processing
 | ||
|  |     //lint -e{9079} -e{9087} "cast between pointers to different object types"
 | ||
|  |     *((os_message_queue_t **)(void *)&msg[1]) = mq; | ||
|  |     osRtxPostProcess(osRtxObject(msg)); | ||
|  |     EvrRtxMessageQueueRetrieved(mq, msg_ptr); | ||
|  |     status = osOK; | ||
|  |   } else { | ||
|  |     // No Message available
 | ||
|  |     EvrRtxMessageQueueNotRetrieved(mq, msg_ptr); | ||
|  |     status = osErrorResource; | ||
|  |   } | ||
|  | 
 | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | //  ==== Public API ====
 | ||
|  | 
 | ||
|  | /// Create and Initialize a Message Queue object.
 | ||
|  | osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) { | ||
|  |   osMessageQueueId_t mq_id; | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueNew(msg_count, msg_size, attr); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxMessageQueueError(NULL, (int32_t)osErrorISR); | ||
|  |     mq_id = NULL; | ||
|  |   } else { | ||
|  |     mq_id = __svcMessageQueueNew(msg_count, msg_size, attr); | ||
|  |   } | ||
|  |   return mq_id; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get name of a Message Queue object.
 | ||
|  | const char *osMessageQueueGetName (osMessageQueueId_t mq_id) { | ||
|  |   const char *name; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxMessageQueueGetName(mq_id, NULL); | ||
|  |     name = NULL; | ||
|  |   } else { | ||
|  |     name = __svcMessageQueueGetName(mq_id); | ||
|  |   } | ||
|  |   return name; | ||
|  | } | ||
|  | 
 | ||
|  | /// Put a Message into a Queue or timeout if Queue is full.
 | ||
|  | osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) { | ||
|  |   osStatus_t status; | ||
|  | 
 | ||
|  |   EvrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     status = isrRtxMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); | ||
|  |   } else { | ||
|  |     status =  __svcMessageQueuePut(mq_id, msg_ptr, msg_prio, timeout); | ||
|  |   } | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get a Message from a Queue or timeout if Queue is empty.
 | ||
|  | osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) { | ||
|  |   osStatus_t status; | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     status = isrRtxMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); | ||
|  |   } else { | ||
|  |     status =  __svcMessageQueueGet(mq_id, msg_ptr, msg_prio, timeout); | ||
|  |   } | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get maximum number of messages in a Message Queue.
 | ||
|  | uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id) { | ||
|  |   uint32_t capacity; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     capacity = svcRtxMessageQueueGetCapacity(mq_id); | ||
|  |   } else { | ||
|  |     capacity =  __svcMessageQueueGetCapacity(mq_id); | ||
|  |   } | ||
|  |   return capacity; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get maximum message size in a Memory Pool.
 | ||
|  | uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id) { | ||
|  |   uint32_t msg_size; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     msg_size = svcRtxMessageQueueGetMsgSize(mq_id); | ||
|  |   } else { | ||
|  |     msg_size =  __svcMessageQueueGetMsgSize(mq_id); | ||
|  |   } | ||
|  |   return msg_size; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get number of queued messages in a Message Queue.
 | ||
|  | uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id) { | ||
|  |   uint32_t count; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     count = svcRtxMessageQueueGetCount(mq_id); | ||
|  |   } else { | ||
|  |     count =  __svcMessageQueueGetCount(mq_id); | ||
|  |   } | ||
|  |   return count; | ||
|  | } | ||
|  | 
 | ||
|  | /// Get number of available slots for messages in a Message Queue.
 | ||
|  | uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id) { | ||
|  |   uint32_t space; | ||
|  | 
 | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     space = svcRtxMessageQueueGetSpace(mq_id); | ||
|  |   } else { | ||
|  |     space =  __svcMessageQueueGetSpace(mq_id); | ||
|  |   } | ||
|  |   return space; | ||
|  | } | ||
|  | 
 | ||
|  | /// Reset a Message Queue to initial empty state.
 | ||
|  | osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id) { | ||
|  |   osStatus_t status; | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueReset(mq_id); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxMessageQueueError(mq_id, (int32_t)osErrorISR); | ||
|  |     status = osErrorISR; | ||
|  |   } else { | ||
|  |     status = __svcMessageQueueReset(mq_id); | ||
|  |   } | ||
|  |   return status; | ||
|  | } | ||
|  | 
 | ||
|  | /// Delete a Message Queue object.
 | ||
|  | osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id) { | ||
|  |   osStatus_t status; | ||
|  | 
 | ||
|  |   EvrRtxMessageQueueDelete(mq_id); | ||
|  |   if (IsIrqMode() || IsIrqMasked()) { | ||
|  |     EvrRtxMessageQueueError(mq_id, (int32_t)osErrorISR); | ||
|  |     status = osErrorISR; | ||
|  |   } else { | ||
|  |     status = __svcMessageQueueDelete(mq_id); | ||
|  |   } | ||
|  |   return status; | ||
|  | } |