1 /**************************************************************************/ /**
2 * @file
3 * @brief OS abstraction layer primitives for SE manager on CMSIS RTOS2
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2021 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #ifndef SE_MANAGER_OSAL_CMSIS_RTOS_H
32 #define SE_MANAGER_OSAL_CMSIS_RTOS_H
33
34 #include "cmsis_os2.h"
35
36 #if defined (SL_COMPONENT_CATALOG_PRESENT)
37 #include "sl_component_catalog.h"
38 #endif
39
40 #if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
41 #include "FreeRTOSConfig.h"
42 #if (configSUPPORT_STATIC_ALLOCATION == 1)
43 #include "FreeRTOS.h" // StaticSemaphore_t
44 #include <string.h>
45 #endif
46 #else
47 #include "em_core.h"
48 #endif
49
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53
54 // -----------------------------------------------------------------------------
55 // Defines
56
57 /// In order to wait forever in blocking functions the user can pass the
58 /// following value.
59 #define SE_MANAGER_OSAL_WAIT_FOREVER (osWaitForever)
60 /// In order to return immediately in blocking functions the user can pass the
61 /// following value.
62 #define SE_MANAGER_OSAL_NON_BLOCKING (0)
63
64 /// Priority to use for SEMBRX IRQ
65 #if defined(SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY)
66 #if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY >= (1U << __NVIC_PRIO_BITS) )
67 #error Illegal SEMBRX priority level.
68 #endif
69 #if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
70 #if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY < (configMAX_SYSCALL_INTERRUPT_PRIORITY >> (8U - __NVIC_PRIO_BITS) ) )
71 #error Illegal SEMBRX priority level.
72 #endif
73 #else
74 #if (SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY < CORE_ATOMIC_BASE_PRIORITY_LEVEL)
75 #error Illegal SEMBRX priority level.
76 #endif
77 #endif
78 #define SE_MANAGER_SEMBRX_IRQ_PRIORITY SE_MANAGER_USER_SEMBRX_IRQ_PRIORITY
79 #else
80 #if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT)
81 #define SE_MANAGER_SEMBRX_IRQ_PRIORITY (configMAX_SYSCALL_INTERRUPT_PRIORITY >> (8U - __NVIC_PRIO_BITS) )
82 #else
83 #define SE_MANAGER_SEMBRX_IRQ_PRIORITY (CORE_ATOMIC_BASE_PRIORITY_LEVEL)
84 #endif
85 #endif
86
87 /// Determine if executing at interrupt level on ARM Cortex-M.
88 #define RUNNING_AT_INTERRUPT_LEVEL (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk)
89
90 // -----------------------------------------------------------------------------
91 // Typedefs
92
93 /// Completion object used to wait for and signal end of an operation.
94 typedef struct se_manager_osal_completion {
95 #if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
96 osSemaphoreAttr_t semaphore_attr;
97 StaticSemaphore_t static_sem_object;
98 #endif
99 osSemaphoreId_t semaphore_ID;
100 } se_manager_osal_completion_t;
101
102 /// SE manager mutex definition for CMSIS RTOS2.
103 typedef struct se_manager_osal_mutex {
104 #if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
105 osMutexAttr_t mutex_attr;
106 StaticSemaphore_t static_sem_object;
107 #endif
108 osMutexId_t mutex_ID;
109 } se_manager_osal_mutex_t;
110
111 // -----------------------------------------------------------------------------
112 // Functions
113
114 /// Initialize a mutex object.
115 __STATIC_INLINE
se_manager_osal_init_mutex(se_manager_osal_mutex_t * mutex)116 sl_status_t se_manager_osal_init_mutex(se_manager_osal_mutex_t *mutex)
117 {
118 if (mutex == NULL) {
119 return SL_STATUS_FAIL;
120 }
121
122 #if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
123 // Zeroize all members of the mutex attributes object and setup the static control block.
124 memset(&mutex->mutex_attr, 0, sizeof(mutex->mutex_attr));
125 mutex->mutex_attr.cb_mem = &mutex->static_sem_object;
126 mutex->mutex_attr.cb_size = sizeof(mutex->static_sem_object);
127 mutex->mutex_ID = osMutexNew(&mutex->mutex_attr);
128 #else
129 mutex->mutex_ID = osMutexNew(NULL);
130 #endif
131
132 return (mutex->mutex_ID == NULL ? SL_STATUS_FAIL : SL_STATUS_OK);
133 }
134
135 /// Free a mutex object.
136 __STATIC_INLINE
se_manager_osal_free_mutex(se_manager_osal_mutex_t * mutex)137 sl_status_t se_manager_osal_free_mutex(se_manager_osal_mutex_t *mutex)
138 {
139 if (mutex == NULL) {
140 return SL_STATUS_FAIL;
141 }
142
143 osStatus_t status = osMutexDelete(mutex->mutex_ID);
144 return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
145 }
146
147 /// Acquire ownership of a mutex. If busy, wait until available.
148 __STATIC_INLINE
se_manager_osal_take_mutex(se_manager_osal_mutex_t * mutex)149 sl_status_t se_manager_osal_take_mutex(se_manager_osal_mutex_t *mutex)
150 {
151 if (mutex == NULL) {
152 return SL_STATUS_FAIL;
153 }
154
155 osStatus_t status = osOK;
156 if (osKernelGetState() == osKernelRunning) {
157 status = osMutexAcquire(mutex->mutex_ID, SE_MANAGER_OSAL_WAIT_FOREVER);
158 }
159 return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
160 }
161
162 /// Try to acquire ownership of a mutex without waiting.
163 __STATIC_INLINE
se_manager_osal_take_mutex_non_blocking(se_manager_osal_mutex_t * mutex)164 sl_status_t se_manager_osal_take_mutex_non_blocking(se_manager_osal_mutex_t *mutex)
165 {
166 if (mutex == NULL) {
167 return SL_STATUS_FAIL;
168 }
169
170 osStatus_t status = osOK;
171 if (osKernelGetState() == osKernelRunning) {
172 status = osMutexAcquire(mutex->mutex_ID, SE_MANAGER_OSAL_NON_BLOCKING);
173 }
174 return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
175 }
176
177 /// Release ownership of a mutex.
178 __STATIC_INLINE
se_manager_osal_give_mutex(se_manager_osal_mutex_t * mutex)179 sl_status_t se_manager_osal_give_mutex(se_manager_osal_mutex_t *mutex)
180 {
181 if (mutex == NULL) {
182 return SL_STATUS_FAIL;
183 }
184
185 osStatus_t status = osOK;
186 if (osKernelGetState() == osKernelRunning) {
187 status = osMutexRelease(mutex->mutex_ID);
188 }
189 return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
190 }
191
192 /// Initialize a completion object.
193 __STATIC_INLINE sl_status_t
se_manager_osal_init_completion(se_manager_osal_completion_t * p_comp)194 se_manager_osal_init_completion(se_manager_osal_completion_t *p_comp)
195 {
196 if (p_comp == NULL) {
197 return SL_STATUS_FAIL;
198 }
199
200 #if defined(SL_CATALOG_FREERTOS_KERNEL_PRESENT) && (configSUPPORT_STATIC_ALLOCATION == 1)
201 // Zeroize all members of the semaphore attributes object and setup the static control block.
202 memset(&p_comp->semaphore_attr, 0, sizeof(p_comp->semaphore_attr));
203 p_comp->semaphore_attr.cb_mem = &p_comp->static_sem_object;
204 p_comp->semaphore_attr.cb_size = sizeof(p_comp->static_sem_object);
205 p_comp->semaphore_ID = osSemaphoreNew(1u, 0u, &p_comp->semaphore_attr);
206 #else
207 p_comp->semaphore_ID = osSemaphoreNew(1u, 0u, NULL);
208 #endif
209
210 return (p_comp->semaphore_ID == NULL ? SL_STATUS_FAIL : SL_STATUS_OK);
211 }
212
213 /// Free a completion object.
214 __STATIC_INLINE sl_status_t
se_manager_osal_free_completion(se_manager_osal_completion_t * p_comp)215 se_manager_osal_free_completion(se_manager_osal_completion_t *p_comp)
216 {
217 if (p_comp == NULL) {
218 return SL_STATUS_FAIL;
219 }
220
221 osStatus_t status = osSemaphoreDelete(p_comp->semaphore_ID);
222 return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
223 }
224
225 // Wait for a completion object to be completed.
226 __STATIC_INLINE sl_status_t
se_manager_osal_wait_completion(se_manager_osal_completion_t * p_comp,int ticks)227 se_manager_osal_wait_completion(se_manager_osal_completion_t *p_comp, int ticks)
228 {
229 if (p_comp == NULL) {
230 return SL_STATUS_FAIL;
231 }
232
233 osStatus_t status = osOK;
234 if (osKernelGetState() == osKernelRunning) {
235 status = osSemaphoreAcquire(p_comp->semaphore_ID,
236 (uint32_t)ticks);
237 }
238 return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
239 }
240
241 // Complete a completion object.
242 __STATIC_INLINE sl_status_t
se_manager_osal_complete(se_manager_osal_completion_t * p_comp)243 se_manager_osal_complete(se_manager_osal_completion_t* p_comp)
244 {
245 if (p_comp == NULL) {
246 return SL_STATUS_FAIL;
247 }
248
249 osStatus_t status = osOK;
250 osKernelState_t state = osKernelGetState();
251 if ((state == osKernelRunning) || (state == osKernelLocked)) {
252 status = osSemaphoreRelease(p_comp->semaphore_ID);
253 }
254 return (status == osOK ? SL_STATUS_OK : SL_STATUS_FAIL);
255 }
256
257 // Lock the RTOS Kernel scheduler.
258 __STATIC_INLINE int32_t
se_manager_osal_kernel_lock(void)259 se_manager_osal_kernel_lock(void)
260 {
261 return osKernelLock();
262 }
263
264 // Restore the RTOS Kernel scheduler lock state.
265 __STATIC_INLINE int32_t
se_manager_osal_kernel_restore_lock(int32_t lock)266 se_manager_osal_kernel_restore_lock(int32_t lock)
267 {
268 return osKernelRestoreLock(lock);
269 }
270
271 // Current RTOS kernel state.
272 __STATIC_INLINE osKernelState_t
se_manager_osal_kernel_get_state(void)273 se_manager_osal_kernel_get_state(void)
274 {
275 return osKernelGetState();
276 }
277
278 #ifdef __cplusplus
279 }
280 #endif
281
282 #endif // SE_MANAGER_OSAL_CMSIS_RTOS_H
283