1 /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- 2 * 3 * Copyright (c) 2014-2015 Datalight, Inc. 4 * All Rights Reserved Worldwide. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; use version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 /* Businesses and individuals that for commercial or other reasons cannot 21 * comply with the terms of the GPLv2 license may obtain a commercial license 22 * before incorporating Reliance Edge into proprietary software for 23 * distribution in any form. Visit http://www.datalight.com/reliance-edge for 24 * more information. 25 */ 26 27 /** @file 28 * @brief Implements a synchronization object to provide mutual exclusion. 29 */ 30 #include <FreeRTOS.h> 31 #include <semphr.h> 32 33 #include <redfs.h> 34 #include <redosdeviations.h> 35 36 #if REDCONF_TASK_COUNT > 1U 37 38 39 static SemaphoreHandle_t xMutex; 40 #if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) 41 static StaticSemaphore_t xMutexBuffer; 42 #endif 43 44 45 /** @brief Initialize the mutex. 46 * 47 * After initialization, the mutex is in the released state. 48 * 49 * The behavior of calling this function when the mutex is still initialized 50 * is undefined. 51 * 52 * @return A negated ::REDSTATUS code indicating the operation result. 53 * 54 * @retval 0 Operation was successful. 55 */ RedOsMutexInit(void)56 REDSTATUS RedOsMutexInit( void ) 57 { 58 REDSTATUS ret = 0; 59 60 #if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) 61 xMutex = xSemaphoreCreateMutexStatic( &xMutexBuffer ); 62 63 if( xMutex == NULL ) 64 { 65 /* The only error case for xSemaphoreCreateMutexStatic is that the mutex 66 * buffer parameter is NULL, which is not the case. 67 */ 68 REDERROR(); 69 ret = -RED_EINVAL; 70 } 71 #else 72 xMutex = xSemaphoreCreateMutex(); 73 74 if( xMutex == NULL ) 75 { 76 ret = -RED_ENOMEM; 77 } 78 #endif /* if defined( configSUPPORT_STATIC_ALLOCATION ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ 79 80 return ret; 81 } 82 83 84 /** @brief Uninitialize the mutex. 85 * 86 * The behavior of calling this function when the mutex is not initialized is 87 * undefined; likewise, the behavior of uninitializing the mutex when it is 88 * in the acquired state is undefined. 89 * 90 * @return A negated ::REDSTATUS code indicating the operation result. 91 * 92 * @retval 0 Operation was successful. 93 */ RedOsMutexUninit(void)94 REDSTATUS RedOsMutexUninit( void ) 95 { 96 vSemaphoreDelete( xMutex ); 97 xMutex = NULL; 98 99 return 0; 100 } 101 102 103 /** @brief Acquire the mutex. 104 * 105 * The behavior of calling this function when the mutex is not initialized is 106 * undefined; likewise, the behavior of recursively acquiring the mutex is 107 * undefined. 108 */ RedOsMutexAcquire(void)109 void RedOsMutexAcquire( void ) 110 { 111 while( xSemaphoreTake( xMutex, portMAX_DELAY ) != pdTRUE ) 112 { 113 } 114 } 115 116 117 /** @brief Release the mutex. 118 * 119 * The behavior is undefined in the following cases: 120 * 121 * - Releasing the mutex when the mutex is not initialized. 122 * - Releasing the mutex when it is not in the acquired state. 123 * - Releasing the mutex from a task or thread other than the one which 124 * acquired the mutex. 125 */ RedOsMutexRelease(void)126 void RedOsMutexRelease( void ) 127 { 128 BaseType_t xSuccess; 129 130 xSuccess = xSemaphoreGive( xMutex ); 131 REDASSERT( xSuccess == pdTRUE ); 132 IGNORE_ERRORS( xSuccess ); 133 } 134 135 #endif /* if REDCONF_TASK_COUNT > 1U */ 136