mbed TLS v2.2.0
slpal_freertos.h
Go to the documentation of this file.
1 /*
2  * Platform Abstraction Layer interface for FreeRTOS.
3  *
4  * Copyright (C) 2016, Silicon Labs, http://www.silabs.com
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may
8  * not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MBEDTLS_SLPAL_FREERTOS_H
21 #define MBEDTLS_SLPAL_FREERTOS_H
22 
23 #if !defined(MBEDTLS_CONFIG_FILE)
24 #include "config.h"
25 #else
26 #include MBEDTLS_CONFIG_FILE
27 #endif
28 
29 #if defined( MBEDTLS_FREERTOS )
30 
31 #include "slpal_common.h"
32 #include "em_assert.h"
33 #include "FreeRTOS.h"
34 #include "task.h"
35 #include "queue.h"
36 #include "semphr.h"
37 #include <stdbool.h>
38 
39 /*******************************************************************************
40  ****************************** Defines **********************************
41  ******************************************************************************/
42 
43 /* In order to wait forever in blocking functions the user can pass the
44  following value. */
45 #define SLPAL_WAIT_FOREVER ((int)portMAX_DELAY)
46 /* In order to return immediately in blocking functions the user can pass the
47  following value. */
48 #define SLPAL_NON_BLOCKING (0)
49 
50 #if defined(MBEDTLS_CRYPTO_IRQ_PRIORITY)
51 #define SLPAL_CRYPTO_IRQ_PRIORITY MBEDTLS_CRYPTO_IRQ_PRIORITY
52 #else
53 #define SLPAL_CRYPTO_IRQ_PRIORITY ( configMAX_SYSCALL_INTERRUPT_PRIORITY >> ( 8U - __NVIC_PRIO_BITS ) )
54 #endif
55 
56 #if ( SLPAL_CRYPTO_IRQ_PRIORITY < ( configMAX_SYSCALL_INTERRUPT_PRIORITY >> ( 8U - __NVIC_PRIO_BITS ) ) )
57 #error CRYPTO IRQ priority should be numerically higher than or equal to the syscall interrupt.
58 #endif
59 
60 /* Max thread priority of system */
61 #define SLPAL_MAX_PRIORITY (configMAX_PRIORITIES-1)
62 
63 /* Max count value of semaphores */
64 #define SEM_COUNT_MAX (65535)
65 
66 /*******************************************************************************
67  ****************************** TYPEDEFS **********************************
68  ******************************************************************************/
69 
70 /* Completion object used to wait for and signal end of an operation. */
71 typedef SemaphoreHandle_t SLPAL_Completion_t;
72 /* Mutex object used for mutual exclusion, e.g. locking resources.
73  Shall support priority inheritance. */
74 typedef SemaphoreHandle_t SLPAL_Mutex_t;
75 
76 /*******************************************************************************
77  ****************************** FUNCTIONS **********************************
78  ******************************************************************************/
79 
80 /***************************************************************************/
93 __STATIC_INLINE SLPAL_irqState_t SLPAL_CriticalEnter(void)
94 {
95  SLPAL_irqState_t irqState;
96 
98  {
99  irqState = taskENTER_CRITICAL_FROM_ISR();
100  }
101  else
102  {
103  irqState = __get_BASEPRI();
104  taskENTER_CRITICAL();
105  }
106 
107  return irqState;
108 }
109 
110 /***************************************************************************/
123 __STATIC_INLINE void SLPAL_CriticalExit(SLPAL_irqState_t irqState)
124 {
126  {
127  taskEXIT_CRITICAL_FROM_ISR(irqState);
128  }
129  else
130  {
131  (void) irqState;
132  taskEXIT_CRITICAL();
133  }
134 }
135 
136 /***************************************************************************/
144 __STATIC_INLINE void SLPAL_IsrEnter(void)
145 {
146 }
147 
148 /***************************************************************************/
156 __STATIC_INLINE void SLPAL_IsrExit(void)
157 {
158 }
159 
160 /***************************************************************************/
170 __STATIC_INLINE unsigned long SLPAL_ThreadPriorityGet(void)
171 {
172  return (unsigned long)uxTaskPriorityGet(NULL);
173 }
174 
175 /*******************************************************************************
176  * @brief
177  * Initialize a completion object.
178  *
179  * @param pComp
180  * Pointer to an SLPAL_Completion_t object allocated by the user.
181  *
182  * @return
183  * 0 for success, SLPAL_ERROR_OS_SPECIFIC for error.
184 *******************************************************************************/
185 __STATIC_INLINE int SLPAL_InitCompletion(SLPAL_Completion_t *pComp)
186 {
187  *pComp = (SLPAL_Completion_t) xSemaphoreCreateBinary();
188  EFM_ASSERT(*pComp != NULL);
189  return (*pComp == NULL ? SLPAL_ERROR_OS_SPECIFIC : 0);
190 }
191 
192 /*******************************************************************************
193  * @brief
194  * Free a completion object.
195  *
196  * @param pComp
197  * Pointer to an SLPAL_Completion_t object.
198  *
199  * @return
200  * 0 for success, SLPAL_ERROR_OS_SPECIFIC for error.
201 *******************************************************************************/
202 __STATIC_INLINE int SLPAL_FreeCompletion(SLPAL_Completion_t *pComp)
203 {
204  (void) pComp;
205  /*
206  Removed call to
207  vSemaphoreDelete( (SemaphoreHandle_t) *pComp );
208 
209  Semaphores can not be deleted with default heap management of the current
210  port. The following comment is from the vPortFree function of FreeRTOS
211  which is called from vSemaphoreDelete (and subsequently vQueueDelete).
212  */
213  /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and
214  heap_4.c for alternative implementations, and the memory management pages of
215  http://www.FreeRTOS.org for more information. */
216 
217  return ( 0 );
218 }
219 
220 /*******************************************************************************
221  * @brief
222  * Wait for completion event.
223  *
224  * @param[in] pComp
225  * Pointer to completion object which must be initialized by calling
226  * SLPAL_CompletionInit before calling this function.
227  *
228  * @param[in] ticks
229  * Ticks to wait for the completion.
230  * Pass a value of SLPAL_WAIT_FOREVER in order to wait forever.
231  * Pass a value of SLPAL_NON_BLOCKING in order to return immediately.
232  *
233  * @return
234  * 0 if success, and SLPAL_ERROR_TIMEOUT if the completion was not completed
235  * within the timeout.
236 ********************************************************************************/
237 __STATIC_INLINE int SLPAL_WaitForCompletion(SLPAL_Completion_t *pComp, int ticks)
238 {
239  int ret;
240  BaseType_t status =
241  xSemaphoreTake( (SemaphoreHandle_t) *pComp, (TickType_t) ticks );
242  if (status == pdTRUE)
243  {
244  ret = 0;
245  }
246  else
247  {
248  ret = SLPAL_ERROR_TIMEOUT;
249  }
250  return ret;
251 }
252 
253 /*******************************************************************************
254  * @brief
255  * Signal completion.
256  *
257  * @param[in] pComp
258  * Pointer to completion object which must be initialized by calling
259  * SLPAL_CompletionInit before calling this function.
260  *
261  * @return
262  * 0 for success, SLPAL_ERROR_OS_SPECIFIC for error.
263 ********************************************************************************/
264 __STATIC_INLINE int SLPAL_Complete(SLPAL_Completion_t* pComp)
265 {
266  BaseType_t status;
268  {
269  BaseType_t HigherPriorityTaskWoken;
270  status = xSemaphoreGiveFromISR( (SemaphoreHandle_t) *pComp,
271  &HigherPriorityTaskWoken );
272  }
273  else
274  {
275  status = xSemaphoreGive( (SemaphoreHandle_t) *pComp );
276  }
277  EFM_ASSERT(status == pdTRUE);
278  return (status == pdTRUE ? 0 : SLPAL_ERROR_OS_SPECIFIC );
279 }
280 
281 /*******************************************************************************
282  * @brief
283  * Initialize a mutex object with support for priority inheritance.
284  *
285  * @param pMutex
286  * Pointer to an SLPAL_Mutex_t object allocated by the user.
287  *
288  * @return
289  * 0 for success, SLPAL_ERROR_OS_SPECIFIC for error.
290 *******************************************************************************/
291 __STATIC_INLINE int SLPAL_InitMutex(SLPAL_Mutex_t *pMutex)
292 {
293  *pMutex = (SLPAL_Mutex_t) xSemaphoreCreateMutex();
294  EFM_ASSERT(*pMutex != NULL);
295  return (*pMutex == NULL ? SLPAL_ERROR_OS_SPECIFIC : 0);
296 }
297 
298 /*******************************************************************************
299  * @brief
300  * Free a mutex object.
301  *
302  * @param pMutex
303  * Pointer to an SLPAL_Mutex_t object.
304  *
305  * @return
306  * 0 for success, SLPAL_ERROR_OS_SPECIFIC for error.
307 *******************************************************************************/
308 __STATIC_INLINE int SLPAL_FreeMutex(SLPAL_Mutex_t *pMutex)
309 {
310  (void) pMutex;
311  /*
312  Removed call to
313  vSemaphoreDelete( (SemaphoreHandle_t) *pComp );
314 
315  Mutex semaphores can not be deleted with default heap management of the
316  current port. The following comment is from the vPortFree function of
317  FreeRTOS which is called from vSemaphoreDelete (and subsequently
318  vQueueDelete).
319  */
320  /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and
321  heap_4.c for alternative implementations, and the memory management pages
322  of http://www.FreeRTOS.org for more information. */
323 
324  return ( 0 );
325 }
326 
327 /*******************************************************************************
328  * @brief
329  * Take (and optionally wait for) a mutex to be given.
330  *
331  * @param[in] pMutex
332  * Pointer to mutex object which must be initialized by calling
333  * SLPAL_MutexInit before calling this function.
334  *
335  * @param[in] ticks
336  * Ticks to wait for the mutex.
337  * Pass a value of SLPAL_WAIT_FOREVER in order to wait forever.
338  * Pass a value of SLPAL_NON_BLOCKING in order to return immediately.
339  *
340  * @return
341  * 0 if success, and SLPAL_ERROR_TIMEOUT if the mutex was not given
342  * within the timeout.
343 ********************************************************************************/
344 __STATIC_INLINE int SLPAL_TakeMutex(SLPAL_Mutex_t *pMutex, int ticks)
345 {
346  int ret;
347  BaseType_t status =
348  xSemaphoreTake( (SemaphoreHandle_t) *pMutex, (TickType_t) ticks );
349  if (status == pdTRUE)
350  {
351  ret = 0;
352  }
353  else
354  {
355  ret = SLPAL_ERROR_TIMEOUT;
356  }
357  return ret;
358 }
359 
360 /*******************************************************************************
361  * @brief
362  * Give a mutex.
363  *
364  * @param[in] pMutex
365  * Pointer to mutex object which must be initialized by calling
366  * SLPAL_MutexInit before calling this function.
367  *
368  * @return
369  * 0 for success, SLPAL_ERROR_OS_SPECIFIC for error.
370 ********************************************************************************/
371 __STATIC_INLINE int SLPAL_GiveMutex(SLPAL_Mutex_t* pMutex)
372 {
373  BaseType_t status;
375  {
376  BaseType_t HigherPriorityTaskWoken;
377  status = xSemaphoreGiveFromISR( (SemaphoreHandle_t) *pMutex,
378  &HigherPriorityTaskWoken );
379  }
380  else
381  {
382  status = xSemaphoreGive( (SemaphoreHandle_t) *pMutex );
383  }
384  EFM_ASSERT(status == pdTRUE);
385  return (status == pdTRUE ? 0 : SLPAL_ERROR_OS_SPECIFIC );
386 }
387 
388 #endif /* MBEDTLS_FREERTOS */
389 
390 #endif /* MBEDTLS_SLPAL_FREERTOS_H */
#define RUNNING_AT_INTERRUPT_LEVEL
Definition: slpal_common.h:37
volatile unsigned int SLPAL_Mutex_t
uint32_t SLPAL_irqState_t
Storage for PRIMASK or BASEPRI value used for SLPAL critical regions.
Definition: slpal_common.h:46
#define SLPAL_ERROR_OS_SPECIFIC
Definition: slpal_common.h:30
__STATIC_INLINE void SLPAL_IsrEnter(void)
Enter an ISR.
__STATIC_INLINE int SLPAL_TakeMutex(SLPAL_Mutex_t *pMutex, int ticks)
Compatibility names (set of defines)
#define SLPAL_ERROR_TIMEOUT
Definition: slpal_common.h:29
__STATIC_INLINE void SLPAL_CriticalExit(SLPAL_irqState_t irqState)
Exit a critical region.
__STATIC_INLINE SLPAL_irqState_t SLPAL_CriticalEnter(void)
Enter a critical region.
__STATIC_INLINE int SLPAL_InitMutex(SLPAL_Mutex_t *pMutex)
volatile bool SLPAL_Completion_t
__STATIC_INLINE void SLPAL_IsrExit(void)
Exit an ISR.
__STATIC_INLINE int SLPAL_GiveMutex(SLPAL_Mutex_t *pMutex)
__STATIC_INLINE int SLPAL_InitCompletion(SLPAL_Completion_t *pComp)
__STATIC_INLINE unsigned long SLPAL_ThreadPriorityGet(void)
Get thread priority of calling thread.
__STATIC_INLINE int SLPAL_Complete(SLPAL_Completion_t *pComp)
__STATIC_INLINE int SLPAL_FreeMutex(SLPAL_Mutex_t *pMutex)
__STATIC_INLINE int SLPAL_WaitForCompletion(SLPAL_Completion_t *pComp, int ticks)
__STATIC_INLINE int SLPAL_FreeCompletion(SLPAL_Completion_t *pComp)