1 /*
2  * Copyright (c) 2015-2019, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ============================================================================
33  *  @file       MutexP.h
34  *
35  *  @brief      Mutex module for the RTOS Porting Interface
36  *
37  *  The MutexP module allows task to maintain critical region segments. The
38  *  MutexP module has two main functions: ::MutexP_lock and ::MutexP_unlock.
39  *
40  *  The MutexP module supports recursive calls to the MutexP_lock API by a
41  *  single task. The same number of MutexP_unlock calls must be done for the
42  *  mutex to be release. Note: the returned key must be provided in the LIFO
43  *  order. For example:
44  *  @code
45  *  uintptr_t key1, key2;
46  *  key1 = MutexP_lock();
47  *  key2 = MutexP_lock();
48  *  MutexP_lock(key2);
49  *  MutexP_lock(key1);
50  *  @endcode
51  *
52  *  ============================================================================
53  */
54 
55 #ifndef ti_dpl_MutexP__include
56 #define ti_dpl_MutexP__include
57 
58 #include <stdint.h>
59 #include <stdbool.h>
60 #include <stddef.h>
61 
62 #ifdef __cplusplus
63 extern "C" {
64 #endif
65 
66 /*!
67  *  @brief    Number of bytes greater than or equal to the size of any RTOS
68  *            MutexP object.
69  *
70  *  nortos:   12
71  *  SysBIOS:  40
72  */
73 #define MutexP_STRUCT_SIZE   (40)
74 
75 /*!
76  *  @brief    MutexP structure.
77  *
78  *  Opaque structure that should be large enough to hold any of the
79  *  RTOS specific MutexP objects.
80  */
81 typedef union MutexP_Struct {
82     uint32_t dummy;  /*!< Align object */
83     char     data[MutexP_STRUCT_SIZE];
84 } MutexP_Struct;
85 
86 /*!
87  *  @brief    Status codes for MutexP APIs
88  */
89 typedef enum {
90     /*! API completed successfully */
91     MutexP_OK = 0,
92     /*! API failed */
93     MutexP_FAILURE = -1
94 } MutexP_Status;
95 
96 /*!
97  *  @brief    Opaque client reference to an instance of a MutexP
98  *
99  *  A MutexP_Handle returned from the ::MutexP_create represents that instance.
100  *  and then is used in the other instance based functions (e.g. ::MutexP_lock,
101  *  ::MutexP_unlock, etc.).
102  */
103 typedef void *MutexP_Handle;
104 
105 /*!
106  *  @brief    Basic MutexP Parameters
107  *
108  *  Structure that contains the parameters are passed into ::MutexP_create
109  *  when creating a MutexP instance. The ::MutexP_Params_init function should
110  *  be used to initialize the fields to default values before the application
111  *  sets the fields manually. The MutexP default parameters are noted in
112  *  ::MutexP_Params_init.
113  */
114 typedef struct {
115     void (*callback)(void); /*!< Callback while waiting for mutex unlock */
116 } MutexP_Params;
117 
118 
119 /*!
120  *  @brief  Function to construct a mutex.
121  *
122  *  @param  handle Pointer to a MutexP_Struct object
123  *
124  *  @param  params  Pointer to the instance configuration parameters. NULL
125  *                  denotes to use the default parameters (MutexP default
126  *                  parameters as noted in ::MutexP_Params_init.
127  *
128  *  @return A MutexP_Handle on success or a NULL on an error
129  */
130 extern MutexP_Handle MutexP_construct(MutexP_Struct *handle,
131         MutexP_Params *params);
132 
133 /*!
134  *  @brief  Function to destruct a mutex object
135  *
136  *  @param  mutexP  Pointer to a MutexP_Struct object that was passed to
137  *                  MutexP_construct().
138  *
139  *  @return
140  */
141 extern void MutexP_destruct(MutexP_Struct *mutexP);
142 
143 /*!
144  *  @brief  Function to create a mutex.
145  *
146  *  @param  params  Pointer to the instance configuration parameters. NULL
147  *                  denotes to use the default parameters. The MutexP default
148  *                  parameters are noted in ::MutexP_Params_init.
149  *
150  *  @return A MutexP_Handle on success or a NULL on an error
151  */
152 extern MutexP_Handle MutexP_create(MutexP_Params *params);
153 
154 /*!
155  *  @brief  Function to delete a mutex.
156  *
157  *  @param  handle  A MutexP_Handle returned from MutexP_create
158  */
159 extern void MutexP_delete(MutexP_Handle handle);
160 
161 /*!
162  *  @brief  Initialize params structure to default values.
163  *
164  *  The default parameters are:
165  *      callback - NULL.
166  *
167  *  @param params  Pointer to the instance configuration parameters.
168  */
169 extern void MutexP_Params_init(MutexP_Params *params);
170 
171 /*!
172  *  @brief  Function to lock a mutex.
173  *
174  *  This function can only be called from a Task. It cannot be called from
175  *  an interrupt. The lock will block until the mutex is available.
176  *
177  *  Users of a mutex should make every attempt to minimize the duration that
178  *  that they have it locked. This is to minimize latency. It is recommended
179  *  that the users of the mutex do not block while they have the mutex locked.
180  *
181  *  This function unlocks the mutex. If the mutex is locked multiple times
182  *  by the caller, the same number of unlocks must be called.
183  *
184  *  @param  handle  A MutexP_Handle returned from ::MutexP_create
185  *
186  *  @return A key is returned. This key must be passed into ::MutexP_unlock.
187  */
188 extern uintptr_t MutexP_lock(MutexP_Handle handle);
189 
190 /*!
191  *  @brief  Function to unlock a mutex
192  *
193  *  This function unlocks the mutex. If the mutex is locked multiple times
194  *  by the caller, the same number of unlocks must be called. The order of
195  *  the keys must be reversed. For example
196  *  @code
197  *  uintptr_t key1, key2;
198  *  key1 = MutexP_lock();
199  *  key2 = MutexP_lock();
200  *  MutexP_lock(key2);
201  *  MutexP_lock(key1);
202  *  @endcode
203  *
204  *  @param  handle  A MutexP_Handle returned from ::MutexP_create
205  *
206  *  @param  key  Return from ::MutexP_lock.
207  */
208 extern void MutexP_unlock(MutexP_Handle handle, uintptr_t key);
209 
210 #ifdef __cplusplus
211 }
212 #endif
213 
214 #endif /* ti_dpl_MutexP__include */
215