1 /*
2 * Copyright 2024 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * The BSD-3-Clause license can be found at https://spdx.org/licenses/BSD-3-Clause.html
6 */
7 /*!\file osa.h
8 *\brief This file contains OSA wrapper declarations for timer, read/write lock and idle hook.
9 */
10
11 #ifndef _OSA_H_
12 #define _OSA_H_
13
14 #include <wifi_config_default.h>
15 #include "fsl_os_abstraction.h"
16 #include <osa_zephyr.h>
17 #include <wmerrno.h>
18 #include <wm_utils.h>
19
20 /*** Timer Management ***/
21 /** Create timer
22 *
23 * This function creates a timer.
24 *
25 * @param[in] timerHandle Pointer to the timer handle
26 * @param[in] ticks Period in ticks
27 * @param[in] call_back Timer expire callback function
28 * @param[in] cb_arg Timer callback data
29 * @param[in] reload Reload Options, valid values include \ref KOSA_TimerOnce
30 * or \ref KOSA_TimerPeriodic.
31 * @param[in] activate Activate Options, valid values include \ref
32 * OSA_TIMER_AUTO_ACTIVATE or \ref OSA_TIMER_NO_ACTIVATE
33 *
34 * @return KOSA_StatusSuccess if timer created successfully
35 * @return KOSA_StatusError if timer creation fails
36 */
37 osa_status_t OSA_TimerCreate(osa_timer_handle_t timerHandle,
38 osa_timer_tick ticks,
39 void (*call_back)(osa_timer_arg_t),
40 void *cb_arg,
41 osa_timer_t reload,
42 osa_timer_activate_t activate);
43
44 /** Activate timer
45 *
46 * This function activates (or starts) a timer that was previously created using
47 * OSA_TimerCreate(). If the timer had already started and was already in the
48 * active state, then this call is equivalent to OSA_TimerReset().
49 *
50 * @param[in] timerHandle Pointer to a timer handle
51 *
52 * @return KOSA_StatusSuccess if timer activated successfully
53 * @return KOSA_StatusError if timer activation fails
54 *
55 */
56 osa_status_t OSA_TimerActivate(osa_timer_handle_t timerHandle);
57
58 /** Change timer period
59 *
60 * This function changes the period of a timer that was previously created using
61 * OSA_TimerCreate(). This function changes the period of an active or dormant
62 * state timer.
63 *
64 * @param[in] timerHandle Pointer to a timer handle
65 * @param[in] ntime Time in ticks after which the timer will expire
66 * @param[in] block_time This option is currently not supported
67 *
68 * @return KOSA_StatusSuccess if timer change successfully
69 * @return KOSA_StatusError if timer change fails
70 */
71 osa_status_t OSA_TimerChange(osa_timer_handle_t timerHandle, osa_timer_tick ntime, osa_timer_tick block_time);
72
73 /** Check the timer active state
74 *
75 * This function checks if the timer is in the active or dormant state. A timer
76 * is in the dormant state if (a) it has been created but not started, or (b) it
77 * has expired and a one-shot timer.
78 *
79 * @param [in] timerHandle Pointer to a timer handle
80 *
81 * @return true if timer is active
82 * @return false if time is not active
83 */
84 bool OSA_TimerIsRunning(osa_timer_handle_t timerHandle);
85
86 /**
87 * Get the timer context
88 *
89 * This function helps to retrieve the timer context i.e. 'cb_arg' passed
90 * to OSA_TimerCreate().
91 *
92 * @param[in] timer_t Pointer to timer handle. The timer handle is received
93 * in the timer callback.
94 *
95 * @return The timer context i.e. the callback argument passed to
96 * OSA_TimerCreate().
97 */
98 void *OSA_TimerGetContext(osa_timer_handle_t timerHandle);
99
100 /** Reset timer
101 *
102 * This function resets a timer that was previously created using using
103 * OSA_TimerCreate(). If the timer had already been started and was already in
104 * the active state, then this call will cause the timer to re-evaluate its
105 * expiry time so that it is relative to when OSA_TimerReset() was called. If
106 * the timer was in the dormant state then this call behaves in the same way as
107 * OSA_TimerActivate().
108 *
109 * @param[in] timerHandle Pointer to a timer handle
110 *
111 * @return KOSA_StatusSuccess if timer reset successfully
112 * @return KOSA_StatusError if timer reset fails
113 */
114 osa_status_t OSA_TimerReset(osa_timer_handle_t timerHandle);
115
116 /** Deactivate timer
117 *
118 * This function deactivates (or stops) a timer that was previously started.
119 *
120 * @param [in] timerHandle handle populated by OSA_TimerCreate().
121 *
122 * @return KOSA_StatusSuccess if timer deactivate successfully
123 * @return KOSA_StatusError if timer deactivate fails
124 */
125 osa_status_t OSA_TimerDeactivate(osa_timer_handle_t timerHandle);
126
127 /** Destroy timer
128 *
129 * This function deletes a timer.
130 *
131 * @param[in] timerHandle Pointer to a timer handle
132 *
133 * @return KOSA_StatusSuccess if timer destroy successfully
134 * @return KOSA_StatusError if timer destroy fails
135 */
136 osa_status_t OSA_TimerDestroy(osa_timer_handle_t timerHandle);
137
138 /*
139 * Reader Writer Locks
140 * This is a generic implementation of reader writer locks
141 * which is reader priority.
142 * Not only it provides mutual exclusion but also synchronization.
143 * Six APIs are exposed to user which include.
144 * -# Create a reader writer lock
145 * -# Delete a reader writer lock
146 * -# Reader lock
147 * -# Reader unlock
148 * -# Writer lock
149 * -# Writer unlock
150 * The locking operation is timeout based.
151 * Caller can give a timeout from 0 (no wait) to
152 * infinite (wait forever)
153 */
154
155 typedef struct _rw_lock osa_rw_lock_t;
156 /** This is prototype of reader callback */
157 typedef int (*cb_fn)(osa_rw_lock_t *plock, unsigned int wait_time);
158
159 struct _rw_lock
160 {
161 /** Mutex for reader mutual exclusion */
162 OSA_MUTEX_HANDLE_DEFINE(reader_mutex);
163 /** Mutex for write mutual exclusion */
164 OSA_MUTEX_HANDLE_DEFINE(write_mutex);
165 /** Lock which when held by reader,
166 * writer cannot enter critical section
167 */
168 OSA_SEMAPHORE_HANDLE_DEFINE(rw_lock);
169 /** Function being called when first reader gets
170 * the lock
171 */
172 cb_fn reader_cb;
173 /** Counter to maintain number of readers
174 * in critical section
175 */
176 unsigned int reader_count;
177 };
178
179 int OSA_RWLockCreateWithCB(osa_rw_lock_t *plock, const char *mutex_name, const char *lock_name, cb_fn r_fn);
180
181 /** Create reader-writer lock
182 *
183 * This function creates a reader-writer lock.
184 *
185 * @param[in] lock Pointer to a reader-writer lock handle
186 * @param[in] mutex_name Name of the mutex
187 * @param[in] lock_name Name of the lock
188 *
189 * @return WM_SUCCESS on success
190 * @return -WM_FAIL on error
191 */
192 int OSA_RWLockCreate(osa_rw_lock_t *plock, const char *mutex_name, const char *lock_name);
193
194 /** Delete a reader-write lock
195 *
196 * This function deletes a reader-writer lock.
197 *
198 * @param[in] lock Pointer to the reader-writer lock handle
199 *
200 */
201 void OSA_RWLockDestroy(osa_rw_lock_t *lock);
202
203 /** Acquire writer lock
204 *
205 * This function acquires a writer lock. While readers can acquire the lock on a
206 * sharing basis, writers acquire the lock in an exclusive manner.
207 *
208 * @param[in] lock Pointer to the reader-writer lock handle
209 * @param[in] wait_time The maximum amount of time, in OS ticks, the task should
210 * block waiting for the lock to be acquired. The special values \ref
211 * osaWaitForever_c and \ref osaWaitNone_c are provided to respectively wait
212 * infinitely or return immediately.
213 *
214 * @return WM_SUCCESS on success
215 * @return -WM_FAIL on error
216 *
217 */
218 int OSA_RWLockWriteLock(osa_rw_lock_t *lock, unsigned int wait_time);
219
220 /** Release writer lock
221 *
222 * This function releases a writer lock previously acquired using
223 * OSA_RWLockWriteLock().
224 *
225 * @param[in] lock Pointer to the reader-writer lock handle
226 */
227 void OSA_RWLockWriteUnlock(osa_rw_lock_t *lock);
228
229 /** Acquire reader lock
230 *
231 * This function acquires a reader lock. While readers can acquire the lock on a
232 * sharing basis, writers acquire the lock in an exclusive manner.
233 *
234 * @param[in] lock pointer to the reader-writer lock handle
235 * @param[in] wait_time The maximum amount of time, in OS ticks, the task should
236 * block waiting for the lock to be acquired. The special values \ref
237 * osaWaitForever_c and \ref osaWaitNone_c are provided to respectively wait
238 * infinitely or return immediately.
239 *
240 * @return WM_SUCCESS on success
241 * @return -WM_FAIL on error
242 *
243 */
244 int OSA_RWLockReadLock(osa_rw_lock_t *lock, unsigned int wait_time);
245
246 /** Release reader lock
247 *
248 * This function releases a reader lock previously acquired using
249 * OSA_RWLockReadLock().
250 *
251 * @param[in] lock pointer to the reader-writer lock handle
252 *
253 * @return WM_SUCCESS if unlock operation successful.
254 * @return -WM_FAIL if unlock operation failed.
255 */
256 int OSA_RWLockReadUnlock(osa_rw_lock_t *lock);
257
258 /*** Tick function */
259 #define MAX_CUSTOM_HOOKS 4U
260
261 extern void (*g_osa_tick_hooks[MAX_CUSTOM_HOOKS])(void);
262 extern void (*g_osa_idle_hooks[MAX_CUSTOM_HOOKS])(void);
263
264 /** Setup idle function
265 *
266 * This function sets up a callback function which will be called whenever the
267 * system enters the idle thread context.
268 *
269 * @param[in] func The callback function
270 *
271 * @return WM_SUCCESS on success
272 * @return -WM_FAIL on error
273 */
274 int OSA_SetupIdleFunction(void (*func)(void));
275
276 /** Setup tick function
277 *
278 * This function sets up a callback function which will be called on every
279 * SysTick interrupt.
280 *
281 * @param[in] func The callback function
282 *
283 * @return WM_SUCCESS on success
284 * @return -WM_FAIL on error
285 */
286 int OSA_SetupTickFunction(void (*func)(void));
287
288 /** Remove idle function
289 *
290 * This function removes an idle callback function that was registered
291 * previously using OSA_SetupIdleFunction().
292 *
293 * @param[in] func The callback function
294 *
295 * @return WM_SUCCESS on success
296 * @return -WM_FAIL on error
297 */
298 int OSA_RemoveIdleFunction(void (*func)(void));
299
300 /** Remove tick function
301 *
302 * This function removes a tick callback function that was registered
303 * previously using OSA_SetupTickFunction().
304 *
305 * @param[in] func Callback function
306 * @return WM_SUCCESS on success
307 * @return -WM_FAIL on error
308 */
309 int OSA_RemoveTickFunction(void (*func)(void));
310
311 /* Init value for rand generator seed */
312 extern uint32_t wm_rand_seed;
313
314 /** This function initialize the seed for rand generator
315 * @return a uint32_t random numer
316 */
OSA_Srand(uint32_t seed)317 static inline void OSA_Srand(uint32_t seed)
318 {
319 wm_rand_seed = seed;
320 }
321
322 /** This function generate a random number
323 * @return a uint32_t random numer
324 */
OSA_Rand()325 static inline uint32_t OSA_Rand()
326 {
327 if (wm_rand_seed == -1)
328 OSA_Srand(OSA_TimeGetMsec());
329 wm_rand_seed = (uint32_t)((((uint64_t)wm_rand_seed * 279470273UL) % 4294967291UL) & 0xFFFFFFFFUL);
330 return wm_rand_seed;
331 }
332
333 /** This function generate a random number in a range
334 * @param [in] low range low
335 * @param [in] high range high
336 * @return a uint32_t random numer
337 */
OSA_RandRange(uint32_t low,uint32_t high)338 static inline uint32_t OSA_RandRange(uint32_t low, uint32_t high)
339 {
340 uint32_t tmp;
341 if (low == high)
342 return low;
343 if (low > high)
344 {
345 tmp = low;
346 low = high;
347 high = tmp;
348 }
349 return (low + OSA_Rand() % (high - low));
350 }
351
352 /** Suspend the given thread
353 *
354 * - The function OSA_ThreadSelfComplete() will \b permanently suspend the
355 * given thread. Passing NULL will suspend the current thread. This
356 * function never returns.
357 * - The thread continues to consume system resources. To delete the thread
358 * the function OSA_TaskDestroy() needs to be called separately.
359 *
360 * @param[in] taskHandle Pointer to thread handle
361 */
362 void OSA_ThreadSelfComplete(osa_task_handle_t taskHandle);
363
364 /** Return the number of messages stored in queue.
365 *
366 * @param[in] msgqHandle Pointer to handle of the queue to be queried.
367 *
368 * @returns Number of items in the queue
369 */
370 uint32_t OSA_MsgQWaiting(osa_msgq_handle_t msgqHandle);
371
372 #endif /* ! _OSA_H_ */
373