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