571 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			571 lines
		
	
	
		
			17 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:       Mutex functions
 | |
|  *
 | |
|  * -----------------------------------------------------------------------------
 | |
|  */
 | |
| 
 | |
| #include "rtx_lib.h"
 | |
| 
 | |
| 
 | |
| //  OS Runtime Object Memory Usage
 | |
| #if ((defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0)))
 | |
| osRtxObjectMemUsage_t osRtxMutexMemUsage \
 | |
| __attribute__((section(".data.os.mutex.obj"))) =
 | |
| { 0U, 0U, 0U };
 | |
| #endif
 | |
| 
 | |
| 
 | |
| //  ==== Library functions ====
 | |
| 
 | |
| /// Release Mutex list when owner Thread terminates.
 | |
| /// \param[in]  mutex_list      mutex list.
 | |
| void osRtxMutexOwnerRelease (os_mutex_t *mutex_list) {
 | |
|   os_mutex_t  *mutex;
 | |
|   os_mutex_t  *mutex_next;
 | |
|   os_thread_t *thread;
 | |
| 
 | |
|   mutex = mutex_list;
 | |
|   while (mutex != NULL) {
 | |
|     mutex_next = mutex->owner_next;
 | |
|     // Check if Mutex is Robust
 | |
|     if ((mutex->attr & osMutexRobust) != 0U) {
 | |
|       // Clear Lock counter
 | |
|       mutex->lock = 0U;
 | |
|       EvrRtxMutexReleased(mutex, 0U);
 | |
|       // Check if Thread is waiting for a Mutex
 | |
|       if (mutex->thread_list != NULL) {
 | |
|         // Wakeup waiting Thread with highest Priority
 | |
|         thread = osRtxThreadListGet(osRtxObject(mutex));
 | |
|         osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE);
 | |
|         // Thread is the new Mutex owner
 | |
|         mutex->owner_thread = thread;
 | |
|         mutex->owner_prev   = NULL;
 | |
|         mutex->owner_next   = thread->mutex_list;
 | |
|         if (thread->mutex_list != NULL) {
 | |
|           thread->mutex_list->owner_prev = mutex;
 | |
|         }
 | |
|         thread->mutex_list = mutex;
 | |
|         mutex->lock = 1U;
 | |
|         EvrRtxMutexAcquired(mutex, 1U);
 | |
|       }
 | |
|     }
 | |
|     mutex = mutex_next;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /// Restore Mutex owner Thread priority.
 | |
| /// \param[in]  mutex           mutex object.
 | |
| /// \param[in]  thread_wakeup   thread wakeup object.
 | |
| void osRtxMutexOwnerRestore (const os_mutex_t *mutex, const os_thread_t *thread_wakeup) {
 | |
|   const os_mutex_t  *mutex0;
 | |
|         os_thread_t *thread;
 | |
|         os_thread_t *thread0;
 | |
|         int8_t       priority;
 | |
| 
 | |
|   // Restore owner Thread priority
 | |
|   if ((mutex->attr & osMutexPrioInherit) != 0U) {
 | |
|     thread   = mutex->owner_thread;
 | |
|     priority = thread->priority_base;
 | |
|     mutex0   = thread->mutex_list;
 | |
|     // Check Mutexes owned by Thread
 | |
|     do {
 | |
|       // Check Threads waiting for Mutex
 | |
|       thread0 = mutex0->thread_list;
 | |
|       if (thread0 == thread_wakeup) {
 | |
|         // Skip thread that is waken-up
 | |
|         thread0 = thread0->thread_next;
 | |
|       }
 | |
|       if ((thread0 != NULL) && (thread0->priority > priority)) {
 | |
|         // Higher priority Thread is waiting for Mutex
 | |
|         priority = thread0->priority;
 | |
|       }
 | |
|       mutex0 = mutex0->owner_next;
 | |
|     } while (mutex0 != NULL);
 | |
|     if (thread->priority != priority) {
 | |
|       thread->priority = priority;
 | |
|       osRtxThreadListSort(thread);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| //  ==== Service Calls ====
 | |
| 
 | |
| /// Create and Initialize a Mutex object.
 | |
| /// \note API identical to osMutexNew
 | |
| static osMutexId_t svcRtxMutexNew (const osMutexAttr_t *attr) {
 | |
|   os_mutex_t *mutex;
 | |
|   uint32_t    attr_bits;
 | |
|   uint8_t     flags;
 | |
|   const char *name;
 | |
| 
 | |
|   // Process attributes
 | |
|   if (attr != NULL) {
 | |
|     name      = attr->name;
 | |
|     attr_bits = attr->attr_bits;
 | |
|     //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
 | |
|     mutex     = attr->cb_mem;
 | |
|     if (mutex != NULL) {
 | |
|       //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
 | |
|       if ((((uint32_t)mutex & 3U) != 0U) || (attr->cb_size < sizeof(os_mutex_t))) {
 | |
|         EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock);
 | |
|         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|         return NULL;
 | |
|       }
 | |
|     } else {
 | |
|       if (attr->cb_size != 0U) {
 | |
|         EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock);
 | |
|         //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|         return NULL;
 | |
|       }
 | |
|     }
 | |
|   } else {
 | |
|     name      = NULL;
 | |
|     attr_bits = 0U;
 | |
|     mutex     = NULL;
 | |
|   }
 | |
| 
 | |
|   // Allocate object memory if not provided
 | |
|   if (mutex == NULL) {
 | |
|     if (osRtxInfo.mpi.mutex != NULL) {
 | |
|       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | |
|       mutex = osRtxMemoryPoolAlloc(osRtxInfo.mpi.mutex);
 | |
|     } else {
 | |
|       //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
 | |
|       mutex = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_mutex_t), 1U);
 | |
|     }
 | |
| #if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
 | |
|     if (mutex != NULL) {
 | |
|       uint32_t used;
 | |
|       osRtxMutexMemUsage.cnt_alloc++;
 | |
|       used = osRtxMutexMemUsage.cnt_alloc - osRtxMutexMemUsage.cnt_free;
 | |
|       if (osRtxMutexMemUsage.max_used < used) {
 | |
|         osRtxMutexMemUsage.max_used = used;
 | |
|       }
 | |
|     }
 | |
| #endif
 | |
|     flags = osRtxFlagSystemObject;
 | |
|   } else {
 | |
|     flags = 0U;
 | |
|   }
 | |
| 
 | |
|   if (mutex != NULL) {
 | |
|     // Initialize control block
 | |
|     mutex->id           = osRtxIdMutex;
 | |
|     mutex->flags        = flags;
 | |
|     mutex->attr         = (uint8_t)attr_bits;
 | |
|     mutex->name         = name;
 | |
|     mutex->thread_list  = NULL;
 | |
|     mutex->owner_thread = NULL;
 | |
|     mutex->owner_prev   = NULL;
 | |
|     mutex->owner_next   = NULL;
 | |
|     mutex->lock         = 0U;
 | |
| 
 | |
|     EvrRtxMutexCreated(mutex, mutex->name);
 | |
|   } else {
 | |
|     EvrRtxMutexError(NULL, (int32_t)osErrorNoMemory);
 | |
|   }
 | |
| 
 | |
|   return mutex;
 | |
| }
 | |
| 
 | |
| /// Get name of a Mutex object.
 | |
| /// \note API identical to osMutexGetName
 | |
| static const char *svcRtxMutexGetName (osMutexId_t mutex_id) {
 | |
|   os_mutex_t *mutex = osRtxMutexId(mutex_id);
 | |
| 
 | |
|   // Check parameters
 | |
|   if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
 | |
|     EvrRtxMutexGetName(mutex, NULL);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   EvrRtxMutexGetName(mutex, mutex->name);
 | |
| 
 | |
|   return mutex->name;
 | |
| }
 | |
| 
 | |
| /// Acquire a Mutex or timeout if it is locked.
 | |
| /// \note API identical to osMutexAcquire
 | |
| static osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
 | |
|   os_mutex_t  *mutex = osRtxMutexId(mutex_id);
 | |
|   os_thread_t *thread;
 | |
|   osStatus_t   status;
 | |
| 
 | |
|   // Check running thread
 | |
|   thread = osRtxThreadGetRunning();
 | |
|   if (thread == NULL) {
 | |
|     EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return osError;
 | |
|   }
 | |
| 
 | |
|   // Check parameters
 | |
|   if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
 | |
|     EvrRtxMutexError(mutex, (int32_t)osErrorParameter);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return osErrorParameter;
 | |
|   }
 | |
| 
 | |
|   // Check if Mutex is not locked
 | |
|   if (mutex->lock == 0U) {
 | |
|     // Acquire Mutex
 | |
|     mutex->owner_thread = thread;
 | |
|     mutex->owner_prev   = NULL;
 | |
|     mutex->owner_next   = thread->mutex_list;
 | |
|     if (thread->mutex_list != NULL) {
 | |
|       thread->mutex_list->owner_prev = mutex;
 | |
|     }
 | |
|     thread->mutex_list = mutex;
 | |
|     mutex->lock = 1U;
 | |
|     EvrRtxMutexAcquired(mutex, mutex->lock);
 | |
|     status = osOK;
 | |
|   } else {
 | |
|     // Check if Mutex is recursive and running Thread is the owner
 | |
|     if (((mutex->attr & osMutexRecursive) != 0U) && (mutex->owner_thread == thread)) {
 | |
|       // Try to increment lock counter
 | |
|       if (mutex->lock == osRtxMutexLockLimit) {
 | |
|         EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit);
 | |
|         status = osErrorResource;
 | |
|       } else {
 | |
|         mutex->lock++;
 | |
|         EvrRtxMutexAcquired(mutex, mutex->lock);
 | |
|         status = osOK;
 | |
|       }
 | |
|     } else {
 | |
|       // Check if timeout is specified
 | |
|       if (timeout != 0U) {
 | |
|         // Check if Priority inheritance protocol is enabled
 | |
|         if ((mutex->attr & osMutexPrioInherit) != 0U) {
 | |
|           // Raise priority of owner Thread if lower than priority of running Thread
 | |
|           if (mutex->owner_thread->priority < thread->priority) {
 | |
|             mutex->owner_thread->priority = thread->priority;
 | |
|             osRtxThreadListSort(mutex->owner_thread);
 | |
|           }
 | |
|         }
 | |
|         EvrRtxMutexAcquirePending(mutex, timeout);
 | |
|         // Suspend current Thread
 | |
|         if (osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout)) {
 | |
|           osRtxThreadListPut(osRtxObject(mutex), thread);
 | |
|         } else {
 | |
|           EvrRtxMutexAcquireTimeout(mutex);
 | |
|         }
 | |
|         status = osErrorTimeout;
 | |
|       } else {
 | |
|         EvrRtxMutexNotAcquired(mutex);
 | |
|         status = osErrorResource;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /// Release a Mutex that was acquired by osMutexAcquire.
 | |
| /// \note API identical to osMutexRelease
 | |
| static osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) {
 | |
|         os_mutex_t  *mutex = osRtxMutexId(mutex_id);
 | |
|   const os_mutex_t  *mutex0;
 | |
|         os_thread_t *thread;
 | |
|         int8_t       priority;
 | |
| 
 | |
|   // Check running thread
 | |
|   thread = osRtxThreadGetRunning();
 | |
|   if (thread == NULL) {
 | |
|     EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return osError;
 | |
|   }
 | |
| 
 | |
|   // Check parameters
 | |
|   if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
 | |
|     EvrRtxMutexError(mutex, (int32_t)osErrorParameter);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return osErrorParameter;
 | |
|   }
 | |
| 
 | |
|   // Check if Mutex is not locked
 | |
|   if (mutex->lock == 0U) {
 | |
|     EvrRtxMutexError(mutex, osRtxErrorMutexNotLocked);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return osErrorResource;
 | |
|   }
 | |
| 
 | |
|   // Check if running Thread is not the owner
 | |
|   if (mutex->owner_thread != thread) {
 | |
|     EvrRtxMutexError(mutex, osRtxErrorMutexNotOwned);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return osErrorResource;
 | |
|   }
 | |
| 
 | |
|   // Decrement Lock counter
 | |
|   mutex->lock--;
 | |
|   EvrRtxMutexReleased(mutex, mutex->lock);
 | |
| 
 | |
|   // Check Lock counter
 | |
|   if (mutex->lock == 0U) {
 | |
| 
 | |
|     // Remove Mutex from Thread owner list
 | |
|     if (mutex->owner_next != NULL) {
 | |
|       mutex->owner_next->owner_prev = mutex->owner_prev;
 | |
|     }
 | |
|     if (mutex->owner_prev != NULL) {
 | |
|       mutex->owner_prev->owner_next = mutex->owner_next;
 | |
|     } else {
 | |
|       thread->mutex_list = mutex->owner_next;
 | |
|     }
 | |
| 
 | |
|     // Restore running Thread priority
 | |
|     if ((mutex->attr & osMutexPrioInherit) != 0U) {
 | |
|       priority = thread->priority_base;
 | |
|       mutex0   = thread->mutex_list;
 | |
|       // Check mutexes owned by running Thread
 | |
|       while (mutex0 != NULL) {
 | |
|         if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
 | |
|           // Higher priority Thread is waiting for Mutex
 | |
|           priority = mutex0->thread_list->priority;
 | |
|         }
 | |
|         mutex0 = mutex0->owner_next;
 | |
|       }
 | |
|       thread->priority = priority;
 | |
|     }
 | |
| 
 | |
|     // Check if Thread is waiting for a Mutex
 | |
|     if (mutex->thread_list != NULL) {
 | |
|       // Wakeup waiting Thread with highest Priority
 | |
|       thread = osRtxThreadListGet(osRtxObject(mutex));
 | |
|       osRtxThreadWaitExit(thread, (uint32_t)osOK, FALSE);
 | |
|       // Thread is the new Mutex owner
 | |
|       mutex->owner_thread = thread;
 | |
|       mutex->owner_prev   = NULL;
 | |
|       mutex->owner_next   = thread->mutex_list;
 | |
|       if (thread->mutex_list != NULL) {
 | |
|         thread->mutex_list->owner_prev = mutex;
 | |
|       }
 | |
|       thread->mutex_list = mutex;
 | |
|       mutex->lock = 1U;
 | |
|       EvrRtxMutexAcquired(mutex, 1U);
 | |
|     }
 | |
| 
 | |
|     osRtxThreadDispatch(NULL);
 | |
|   }
 | |
| 
 | |
|   return osOK;
 | |
| }
 | |
| 
 | |
| /// Get Thread which owns a Mutex object.
 | |
| /// \note API identical to osMutexGetOwner
 | |
| static osThreadId_t svcRtxMutexGetOwner (osMutexId_t mutex_id) {
 | |
|   os_mutex_t *mutex = osRtxMutexId(mutex_id);
 | |
| 
 | |
|   // Check parameters
 | |
|   if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
 | |
|     EvrRtxMutexGetOwner(mutex, NULL);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   // Check if Mutex is not locked
 | |
|   if (mutex->lock == 0U) {
 | |
|     EvrRtxMutexGetOwner(mutex, NULL);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   EvrRtxMutexGetOwner(mutex, mutex->owner_thread);
 | |
| 
 | |
|   return mutex->owner_thread;
 | |
| }
 | |
| 
 | |
| /// Delete a Mutex object.
 | |
| /// \note API identical to osMutexDelete
 | |
| static osStatus_t svcRtxMutexDelete (osMutexId_t mutex_id) {
 | |
|         os_mutex_t  *mutex = osRtxMutexId(mutex_id);
 | |
|   const os_mutex_t  *mutex0;
 | |
|         os_thread_t *thread;
 | |
|         int8_t       priority;
 | |
| 
 | |
|   // Check parameters
 | |
|   if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
 | |
|     EvrRtxMutexError(mutex, (int32_t)osErrorParameter);
 | |
|     //lint -e{904} "Return statement before end of function" [MISRA Note 1]
 | |
|     return osErrorParameter;
 | |
|   }
 | |
| 
 | |
|   // Check if Mutex is locked
 | |
|   if (mutex->lock != 0U) {
 | |
| 
 | |
|     thread = mutex->owner_thread;
 | |
| 
 | |
|     // Remove Mutex from Thread owner list
 | |
|     if (mutex->owner_next != NULL) {
 | |
|       mutex->owner_next->owner_prev = mutex->owner_prev;
 | |
|     }
 | |
|     if (mutex->owner_prev != NULL) {
 | |
|       mutex->owner_prev->owner_next = mutex->owner_next;
 | |
|     } else {
 | |
|       thread->mutex_list = mutex->owner_next;
 | |
|     }
 | |
| 
 | |
|     // Restore owner Thread priority
 | |
|     if ((mutex->attr & osMutexPrioInherit) != 0U) {
 | |
|       priority = thread->priority_base;
 | |
|       mutex0   = thread->mutex_list;
 | |
|       // Check Mutexes owned by Thread
 | |
|       while (mutex0 != NULL) {
 | |
|         if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
 | |
|           // Higher priority Thread is waiting for Mutex
 | |
|           priority = mutex0->thread_list->priority;
 | |
|         }
 | |
|         mutex0 = mutex0->owner_next;
 | |
|       }
 | |
|       if (thread->priority != priority) {
 | |
|         thread->priority = priority;
 | |
|         osRtxThreadListSort(thread);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     // Unblock waiting threads
 | |
|     while (mutex->thread_list != NULL) {
 | |
|       thread = osRtxThreadListGet(osRtxObject(mutex));
 | |
|       osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
 | |
|     }
 | |
| 
 | |
|     osRtxThreadDispatch(NULL);
 | |
|   }
 | |
| 
 | |
|   // Mark object as invalid
 | |
|   mutex->id = osRtxIdInvalid;
 | |
| 
 | |
|   // Free object memory
 | |
|   if ((mutex->flags & osRtxFlagSystemObject) != 0U) {
 | |
|     if (osRtxInfo.mpi.mutex != NULL) {
 | |
|       (void)osRtxMemoryPoolFree(osRtxInfo.mpi.mutex, mutex);
 | |
|     } else {
 | |
|       (void)osRtxMemoryFree(osRtxInfo.mem.common, mutex);
 | |
|     }
 | |
| #if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
 | |
|     osRtxMutexMemUsage.cnt_free++;
 | |
| #endif
 | |
|   }
 | |
| 
 | |
|   EvrRtxMutexDestroyed(mutex);
 | |
| 
 | |
|   return osOK;
 | |
| }
 | |
| 
 | |
| //  Service Calls definitions
 | |
| //lint ++flb "Library Begin" [MISRA Note 11]
 | |
| SVC0_1(MutexNew,      osMutexId_t,  const osMutexAttr_t *)
 | |
| SVC0_1(MutexGetName,  const char *, osMutexId_t)
 | |
| SVC0_2(MutexAcquire,  osStatus_t,   osMutexId_t, uint32_t)
 | |
| SVC0_1(MutexRelease,  osStatus_t,   osMutexId_t)
 | |
| SVC0_1(MutexGetOwner, osThreadId_t, osMutexId_t)
 | |
| SVC0_1(MutexDelete,   osStatus_t,   osMutexId_t)
 | |
| //lint --flb "Library End"
 | |
| 
 | |
| 
 | |
| //  ==== Public API ====
 | |
| 
 | |
| /// Create and Initialize a Mutex object.
 | |
| osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
 | |
|   osMutexId_t mutex_id;
 | |
| 
 | |
|   EvrRtxMutexNew(attr);
 | |
|   if (IsIrqMode() || IsIrqMasked()) {
 | |
|     EvrRtxMutexError(NULL, (int32_t)osErrorISR);
 | |
|     mutex_id = NULL;
 | |
|   } else {
 | |
|     mutex_id = __svcMutexNew(attr);
 | |
|   }
 | |
|   return mutex_id;
 | |
| }
 | |
| 
 | |
| /// Get name of a Mutex object.
 | |
| const char *osMutexGetName (osMutexId_t mutex_id) {
 | |
|   const char *name;
 | |
| 
 | |
|   if (IsIrqMode() || IsIrqMasked()) {
 | |
|     EvrRtxMutexGetName(mutex_id, NULL);
 | |
|     name = NULL;
 | |
|   } else {
 | |
|     name = __svcMutexGetName(mutex_id);
 | |
|   }
 | |
|   return name;
 | |
| }
 | |
| 
 | |
| /// Acquire a Mutex or timeout if it is locked.
 | |
| osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
 | |
|   osStatus_t status;
 | |
| 
 | |
|   EvrRtxMutexAcquire(mutex_id, timeout);
 | |
|   if (IsIrqMode() || IsIrqMasked()) {
 | |
|     EvrRtxMutexError(mutex_id, (int32_t)osErrorISR);
 | |
|     status = osErrorISR;
 | |
|   } else {
 | |
|     status = __svcMutexAcquire(mutex_id, timeout);
 | |
|   }
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /// Release a Mutex that was acquired by \ref osMutexAcquire.
 | |
| osStatus_t osMutexRelease (osMutexId_t mutex_id) {
 | |
|   osStatus_t status;
 | |
| 
 | |
|   EvrRtxMutexRelease(mutex_id);
 | |
|   if (IsIrqMode() || IsIrqMasked()) {
 | |
|     EvrRtxMutexError(mutex_id, (int32_t)osErrorISR);
 | |
|     status = osErrorISR;
 | |
|   } else {
 | |
|     status = __svcMutexRelease(mutex_id);
 | |
|   }
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /// Get Thread which owns a Mutex object.
 | |
| osThreadId_t osMutexGetOwner (osMutexId_t mutex_id) {
 | |
|   osThreadId_t thread;
 | |
| 
 | |
|   if (IsIrqMode() || IsIrqMasked()) {
 | |
|     EvrRtxMutexGetOwner(mutex_id, NULL);
 | |
|     thread = NULL;
 | |
|   } else {
 | |
|     thread = __svcMutexGetOwner(mutex_id);
 | |
|   }
 | |
|   return thread;
 | |
| }
 | |
| 
 | |
| /// Delete a Mutex object.
 | |
| osStatus_t osMutexDelete (osMutexId_t mutex_id) {
 | |
|   osStatus_t status;
 | |
| 
 | |
|   EvrRtxMutexDelete(mutex_id);
 | |
|   if (IsIrqMode() || IsIrqMasked()) {
 | |
|     EvrRtxMutexError(mutex_id, (int32_t)osErrorISR);
 | |
|     status = osErrorISR;
 | |
|   } else {
 | |
|     status = __svcMutexDelete(mutex_id);
 | |
|   }
 | |
|   return status;
 | |
| }
 | 
