1 /***********************************************************************************************//**
2  * \file cyabs_rtos.h
3  *
4  * \brief
5  * Defines the Cypress RTOS Interface. Provides prototypes for functions that
6  * allow Cypress libraries to use RTOS resources such as threads, mutexes &
7  * timing functions in an abstract way. The APIs are implemented in the Port
8  * Layer RTOS interface which is specific to the RTOS in use.
9  *
10  ***************************************************************************************************
11  * \copyright
12  * Copyright 2018-2021 Cypress Semiconductor Corporation (an Infineon company) or
13  * an affiliate of Cypress Semiconductor Corporation
14  *
15  * SPDX-License-Identifier: Apache-2.0
16  *
17  * Licensed under the Apache License, Version 2.0 (the "License");
18  * you may not use this file except in compliance with the License.
19  * You may obtain a copy of the License at
20  *
21  *     http://www.apache.org/licenses/LICENSE-2.0
22  *
23  * Unless required by applicable law or agreed to in writing, software
24  * distributed under the License is distributed on an "AS IS" BASIS,
25  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26  * See the License for the specific language governing permissions and
27  * limitations under the License.
28  **************************************************************************************************/
29 
30 #pragma once
31 
32 #include "cyabs_rtos_impl.h"
33 #include "cy_result.h"
34 #include <stdint.h>
35 #include <stdbool.h>
36 #include <stddef.h>
37 
38 /**
39  * \defgroup group_abstraction_rtos_common Common
40  * General types and defines for working with the RTOS abstraction layer.
41  * \defgroup group_abstraction_rtos_event Events
42  * APIs for acquiring and working with Events.
43  * \defgroup group_abstraction_rtos_mutex Mutex
44  * APIs for acquiring and working with Mutexes.
45  * \defgroup group_abstraction_rtos_queue Queue
46  * APIs for creating and working with Queues.
47  * \defgroup group_abstraction_rtos_semaphore Semaphore
48  * APIs for acquiring and working with Semaphores.
49  * \defgroup group_abstraction_rtos_threads Threads
50  * APIs for creating and working with Threads.
51  * \defgroup group_abstraction_rtos_time Time
52  * APIs for getting the current time and waiting.
53  * \defgroup group_abstraction_rtos_timer Timer
54  * APIs for creating and working with Timers.
55  */
56 
57 #ifdef __cplusplus
58 extern "C"
59 {
60 #endif
61 
62 /******************************************** CONSTANTS *******************************************/
63 
64 /**
65  * \ingroup group_abstraction_rtos_common
66  * \{
67  */
68 
69 #if defined(DOXYGEN)
70 /** Return value indicating success */
71 #define CY_RSLT_SUCCESS ((cy_rslt_t)0x00000000U)
72 #endif
73 
74 /** Used with RTOS calls that require a timeout.  This implies the call will never timeout. */
75 #define CY_RTOS_NEVER_TIMEOUT ( (uint32_t)0xffffffffUL )
76 
77 //
78 // Note on error strategy.  If the error is a normal part of operation (timeouts, full queues, empty
79 // queues), the these errors are listed here and the abstraction layer implementation must map from
80 // the underlying errors to these.  If the errors are special cases, the the error \ref
81 // CY_RTOS_GENERAL_ERROR will be returned and \ref cy_rtos_last_error() can be used to retrieve the
82 // RTOS specific error message.
83 //
84 /** Requested operation did not complete in the specified time */
85 #define CY_RTOS_TIMEOUT                     \
86     CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 0)
87 /** The RTOS could not allocate memory for the specified operation */
88 #define CY_RTOS_NO_MEMORY                   \
89     CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 1)
90 /** An error occured in the RTOS */
91 #define CY_RTOS_GENERAL_ERROR               \
92     CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 2)
93 /** A bad argument was passed into the APIs */
94 #define CY_RTOS_BAD_PARAM                   \
95     CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 5)
96 /** A memory alignment issue was detected. Ensure memory provided is aligned per \ref
97    CY_RTOS_ALIGNMENT_MASK */
98 #define CY_RTOS_ALIGNMENT_ERROR             \
99     CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 6)
100 
101 /** \} group_abstraction_rtos_common */
102 
103 /**
104  * \ingroup group_abstraction_rtos_queue
105  * \{
106  */
107 
108 /** The Queue is already full and can't accept any more items at this time */
109 #define CY_RTOS_QUEUE_FULL                  \
110     CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 3)
111 /** The Queue is empty and has nothing to remove */
112 #define CY_RTOS_QUEUE_EMPTY                 \
113     CY_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_OS, 4)
114 
115 /** \} group_abstraction_rtos_queue */
116 
117 /********************************************* TYPES **********************************************/
118 
119 /**
120  * The state a thread can be in
121  *
122  * \ingroup group_abstraction_rtos_threads
123  */
124 typedef enum cy_thread_state
125 {
126     CY_THREAD_STATE_INACTIVE,   /**< thread has not started or was terminated but not yet joined */
127     CY_THREAD_STATE_READY,      /**< thread can run, but is not currently */
128     CY_THREAD_STATE_RUNNING,    /**< thread is currently running */
129     CY_THREAD_STATE_BLOCKED,    /**< thread is blocked waiting for something */
130     CY_THREAD_STATE_TERMINATED, /**< thread has terminated but not freed */
131     CY_THREAD_STATE_UNKNOWN     /**< thread is in an unknown state */
132 } cy_thread_state_t;
133 
134 /**
135  * The type of timer
136  *
137  * \ingroup group_abstraction_rtos_timer
138  */
139 typedef enum cy_timer_trigger_type
140 {
141     CY_TIMER_TYPE_PERIODIC,                             /**< called periodically until stopped */
142     CY_TIMER_TYPE_ONCE,                                 /**< called once only */
143     cy_timer_type_periodic = CY_TIMER_TYPE_PERIODIC,    /**< \deprecated replaced by \ref
144                                                            CY_TIMER_TYPE_PERIODIC */
145     cy_timer_type_once     = CY_TIMER_TYPE_ONCE         /**< \deprecated replaced by \ref
146                                                            CY_TIMER_TYPE_ONCE */
147 } cy_timer_trigger_type_t;
148 
149 /**
150  * The type of a function that is the entry point for a thread
151  *
152  * @param[in] arg the argument passed from the thread create call to the entry function
153  *
154  * \ingroup group_abstraction_rtos_threads
155  */
156 typedef void (* cy_thread_entry_fn_t)(cy_thread_arg_t arg);
157 
158 /**
159  * The callback function to be called by a timer
160  *
161  * \ingroup group_abstraction_rtos_timer
162  */
163 typedef void (* cy_timer_callback_t)(cy_timer_callback_arg_t arg);
164 
165 /**
166  * Return the last error from the RTOS.
167  *
168  * The functions in the RTOS abstraction layer adhere to the Infineon return
169  * results calling convention.  The underlying RTOS implementations will not but rather
170  * will have their own error code conventions.  This function is provided as a service
171  * to the developer, mostly for debugging, and returns the underlying RTOS error code
172  * from the last RTOS abstraction layer that returned \ref CY_RTOS_GENERAL_ERROR.
173  *
174  * @return RTOS specific error code.
175  *
176  * \ingroup group_abstraction_rtos_common
177  */
178 cy_rtos_error_t cy_rtos_last_error(void);
179 
180 
181 /********************************************* Threads ********************************************/
182 
183 /**
184  * \ingroup group_abstraction_rtos_threads
185  * \{
186  */
187 
188 /** Create a thread with specific thread argument.
189  *
190  * This function is called to startup a new thread. If the thread can exit, it must call
191  * \ref cy_rtos_exit_thread() just before doing so. All created threads that can terminate, either
192  * by themselves or forcefully by another thread MUST have \ref cy_rtos_join_thread() called on them
193  * by another thread in order to cleanup any resources that might have been allocated for them.
194  *
195  * @param[out] thread         Pointer to a variable which will receive the new thread handle
196  * @param[in]  entry_function Function pointer which points to the main function for the new thread
197  * @param[in]  name           String thread name used for a debugger
198  * @param[in]  stack          The buffer to use for the thread stack. This must be aligned to
199  *                            \ref CY_RTOS_ALIGNMENT_MASK with a size of at least \ref
200  *                            CY_RTOS_MIN_STACK_SIZE.
201  *                            If stack is null, cy_rtos_create_thread will allocate a stack from
202  *                            the heap.
203  * @param[in]  stack_size     The size of the thread stack in bytes
204  * @param[in]  priority       The priority of the thread. Values are operating system specific,
205  *                            but some common priority levels are defined:
206  *                                CY_THREAD_PRIORITY_LOW
207  *                                CY_THREAD_PRIORITY_NORMAL
208  *                                CY_THREAD_PRIORITY_HIGH
209  * @param[in]  arg            The argument to pass to the new thread
210  *
211  * @return The status of thread create request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
212  *         CY_RTOS_GENERAL_ERROR]
213  */
214 cy_rslt_t cy_rtos_create_thread(cy_thread_t* thread, cy_thread_entry_fn_t entry_function,
215                                 const char* name, void* stack, uint32_t stack_size,
216                                 cy_thread_priority_t priority, cy_thread_arg_t arg);
217 
218 /** Exit the current thread.
219  *
220  * This function is called just before a thread exits.  In some cases it is sufficient
221  * for a thread to just return to exit, but in other cases, the RTOS must be explicitly
222  * signaled. In cases where a return is sufficient, this should be a null funcition.
223  * where the RTOS must be signaled, this function should perform that In cases operation.
224  * In code using RTOS services, this function should be placed at any at any location
225  * where the main thread function will return, exiting the thread. Threads that can
226  * exit must still be joined (\ref cy_rtos_join_thread) to ensure their resources are
227  * fully cleaned up.
228  *
229  * @return The status of thread exit request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
230  */
231 cy_rslt_t cy_rtos_exit_thread(void);
232 
233 /** Terminates another thread.
234  *
235  * This function is called to terminate another thread and reap the resources claimed
236  * by the thread. This should be called both when forcibly terminating another thread
237  * as well as any time a thread can exit on its own. For some RTOS implementations
238  * this is not required as the thread resources are claimed as soon as it exits. In
239  * other cases, this must be called to reclaim resources. Threads that are terminated
240  * must still be joined (\ref cy_rtos_join_thread) to ensure their resources are fully
241  * cleaned up.
242  *
243  * @param[in] thread Handle of the thread to terminate
244  *
245  * @returns The status of the thread terminate. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
246  */
247 cy_rslt_t cy_rtos_terminate_thread(cy_thread_t* thread);
248 
249 /** Waits for a thread to complete.
250  *
251  * This must be called on any thread that can complete to ensure that any resources that
252  * were allocated for it are cleaned up.
253  *
254  * @param[in] thread Handle of the thread to wait for
255  *
256  * @returns The status of thread join request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
257  */
258 cy_rslt_t cy_rtos_join_thread(cy_thread_t* thread);
259 
260 /** Checks if the thread is running
261  *
262  * This function is called to determine if a thread is actively running or not. For information on
263  * the thread state, use the \ref cy_rtos_get_thread_state() function.
264  *
265  * @param[in] thread     Handle of the terminated thread to delete
266  * @param[out] running   Returns true if the thread is running, otherwise false
267  *
268  * @returns The status of the thread running check. [\ref CY_RSLT_SUCCESS, \ref
269  *          CY_RTOS_GENERAL_ERROR]
270  */
271 cy_rslt_t cy_rtos_is_thread_running(cy_thread_t* thread, bool* running);
272 
273 /** Gets the state the thread is currently in
274  *
275  * This function is called to determine if a thread is running/blocked/inactive/ready etc.
276  *
277  * @param[in] thread     Handle of the terminated thread to delete
278  * @param[out] state     Returns the state the thread is currently in
279  *
280  * @returns The status of the thread state check. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
281  */
282 cy_rslt_t cy_rtos_get_thread_state(cy_thread_t* thread, cy_thread_state_t* state);
283 
284 /** Get current thread handle
285  *
286  * Returns the unique thread handle of the current running thread.
287  *
288  * @param[out] thread Handle of the current running thread
289  *
290  * @returns The status of thread join request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
291  */
292 cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t* thread);
293 
294 
295 /** Suspend current thread until notification is received
296  *
297  * This function suspends the execution of current thread until it is notified
298  * by \ref cy_rtos_set_thread_notification from another thread or ISR, or timed out with
299  * specify timeout value
300  *
301  * @param[in] timeout_ms  Maximum number of milliseconds to wait
302  *                        Use the \ref CY_RTOS_NEVER_TIMEOUT constant to wait forever.
303  *
304  * @returns The status of thread wait. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_TIMEOUT, \ref
305  *                                     CY_RTOS_GENERAL_ERROR]
306  */
307 cy_rslt_t cy_rtos_wait_thread_notification(cy_time_t timeout_ms);
308 
309 
310 /** Set the thread notification for a thread
311  *
312  * This function sets the thread notification for the target thread.
313  * The target thread waiting for the notification to be set will resume from suspended state.
314  *
315  * @param[in] thread     Handle of the target thread
316  * @param[in] in_isr     If true this is being called from within an ISR
317  *
318  * @returns The status of thread wait. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR,
319  *                                      \ref CY_RTOS_BAD_PARAM]
320  */
321 cy_rslt_t cy_rtos_set_thread_notification(cy_thread_t* thread, bool in_isr);
322 
323 
324 /** \} group_abstraction_rtos_threads */
325 
326 
327 /********************************************* Mutexes ********************************************/
328 
329 /**
330  * \ingroup group_abstraction_rtos_mutex
331  * \{
332  */
333 
334 /** Create a recursive mutex.
335  *
336  * Creates a binary mutex which can be used for mutual exclusion to prevent simulatenous
337  * access of shared resources. Created mutexes can support priority inheritance if recursive.
338  *
339  * This function has been replaced by \ref cy_rtos_init_mutex2 which allow for specifying
340  * whether or not the mutex supports recursion or not.
341  *
342  * @param[out] mutex Pointer to the mutex handle to be initialized
343  *
344  * @return The status of mutex creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
345  *         CY_RTOS_GENERAL_ERROR]
346  */
347 #define cy_rtos_init_mutex(mutex) cy_rtos_init_mutex2(mutex, true)
348 
349 /** Create a mutex which can support recursion or not.
350  *
351  * Creates a binary mutex which can be used for mutual exclusion to prevent simulatenous
352  * access of shared resources. Created mutexes can support priority inheritance if recursive.
353  *
354  * \note Not all RTOS implementations support non-recursive mutexes. In this case a recursive
355  * mutex will be created.
356  *
357  * @param[out] mutex     Pointer to the mutex handle to be initialized
358  * @param[in]  recursive Should the created mutex support recursion or not
359  *
360  * @return The status of mutex creation request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
361  *         CY_RTOS_GENERAL_ERROR]
362  */
363 cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t* mutex, bool recursive);
364 
365 /** Get a mutex.
366  *
367  * If the mutex is available, it is acquired and this function returned.
368  * If the mutex is not available, the thread waits until the mutex is available
369  * or until the timeout occurs.
370  *
371  * @note This function must not be called from an interrupt context as it may block.
372  *
373  * @param[in] mutex       Pointer to the mutex handle
374  * @param[in] timeout_ms  Maximum number of milliseconds to wait while attempting to get
375  *                        the mutex. Use the \ref CY_RTOS_NEVER_TIMEOUT constant to wait forever.
376  *
377  * @return The status of the get mutex. Returns timeout if mutex was not acquired
378  *                    before timeout_ms period. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_TIMEOUT, \ref
379  *                    CY_RTOS_GENERAL_ERROR]
380  */
381 cy_rslt_t cy_rtos_get_mutex(cy_mutex_t* mutex, cy_time_t timeout_ms);
382 
383 /** Set a mutex.
384  *
385  * The mutex is released allowing any other threads waiting on the mutex to
386  * obtain the semaphore.
387  *
388  * @param[in] mutex   Pointer to the mutex handle
389  *
390  * @return The status of the set mutex request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
391  *
392  */
393 cy_rslt_t cy_rtos_set_mutex(cy_mutex_t* mutex);
394 
395 /** Deletes a mutex.
396  *
397  * This function frees the resources associated with a sempahore.
398  *
399  * @param[in] mutex Pointer to the mutex handle
400  *
401  * @return The status to the delete request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
402  */
403 cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t* mutex);
404 
405 /** \} group_abstraction_rtos_mutex */
406 
407 /******************************************** Semaphores ******************************************/
408 
409 /**
410  * \ingroup group_abstraction_rtos_semaphore
411  * \{
412  */
413 
414 /**
415  * Create a semaphore
416  *
417  * This is basically a counting semaphore. It can be used for synchronization between tasks and
418  * tasks and interrupts.
419  *
420  * @param[in,out] semaphore  Pointer to the semaphore handle to be initialized
421  * @param[in] maxcount       The maximum count for this semaphore
422  * @param[in] initcount      The initial count for this semaphore
423  *
424  * @return The status of the semaphore creation. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
425  *         CY_RTOS_GENERAL_ERROR]
426  */
427 cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t* semaphore, uint32_t maxcount, uint32_t initcount);
428 
429 /**
430  * Get/Acquire a semaphore
431  *
432  * If the semaphore count is zero, waits until the semaphore count is greater than zero.
433  * Once the semaphore count is greater than zero, this function decrements
434  * the count and return.  It may also return if the timeout is exceeded.
435  *
436  * @param[in] semaphore   Pointer to the semaphore handle
437  * @param[in] timeout_ms  Maximum number of milliseconds to wait while attempting to get
438  *                        the semaphore. Use the \ref CY_RTOS_NEVER_TIMEOUT constant to wait
439  *                        forever. Must be zero if in_isr is true.
440  * @param[in] in_isr      true if we are trying to get the semaphore from with an ISR
441  * @return The status of get semaphore operation [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_TIMEOUT, \ref
442  *         CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
443  */
444 cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t* semaphore, cy_time_t timeout_ms, bool in_isr);
445 
446 /**
447  * Set/Release a semaphore
448  *
449  * Increments the semaphore count, up to the maximum count for this semaphore.
450  *
451  * @param[in] semaphore   Pointer to the semaphore handle
452  * @param[in] in_isr      Value of true indicates calling from interrupt context
453  *                        Value of false indicates calling from normal thread context
454  * @return The status of set semaphore operation [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
455  *         CY_RTOS_GENERAL_ERROR]
456  */
457 cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t* semaphore, bool in_isr);
458 
459 /**
460  * Get the count of a semaphore.
461  *
462  * Gets the number of available tokens on the semaphore.
463  *
464  * @param[in]  semaphore   Pointer to the semaphore handle
465  * @param[out] count       Pointer to the return count
466  * @return The status of get semaphore count operation [\ref CY_RSLT_SUCCESS, \ref
467  *         CY_RTOS_GENERAL_ERROR]
468  */
469 cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t* semaphore, size_t* count);
470 
471 /**
472  * Deletes a semaphore
473  *
474  * This function frees the resources associated with a semaphore.
475  *
476  * @param[in] semaphore   Pointer to the semaphore handle
477  *
478  * @return The status of semaphore deletion [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
479  *         CY_RTOS_GENERAL_ERROR]
480  */
481 cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t* semaphore);
482 
483 /** \} group_abstraction_rtos_semaphore */
484 
485 /********************************************* Events ********************************************/
486 
487 /**
488  * \ingroup group_abstraction_rtos_event
489  * \{
490  */
491 
492 /** Create an event.
493  *
494  * This is an event which can be used to signal a set of threads
495  * with a 32 bit data element.
496  *
497  * @param[in,out] event Pointer to the event handle to be initialized
498  *
499  * @return The status of the event initialization request.
500  *         [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref CY_RTOS_GENERAL_ERROR]
501  */
502 cy_rslt_t cy_rtos_init_event(cy_event_t* event);
503 
504 /** Set the event flag bits.
505  *
506  * This is an event which can be used to signal a set of threads
507  * with a 32 bit data element. Any threads waiting on this event are released
508  *
509  * @param[in] event  Pointer to the event handle
510  * @param[in] bits   The value of the 32 bit flags
511  * @param[in] in_isr If true, this is called from an ISR, otherwise from a thread
512  *
513  * @return The status of the set request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
514  *         CY_RTOS_GENERAL_ERROR]
515  */
516 cy_rslt_t cy_rtos_setbits_event(cy_event_t* event, uint32_t bits, bool in_isr);
517 
518 /**
519  * Clear the event flag bits
520  *
521  * This function clears bits in the event.
522  *
523  * @param[in] event   Pointer to the event handle
524  * @param[in] bits    Any bits set in this value, will be cleared in the event.
525  * @param[in] in_isr  if true, this is called from an ISR, otherwise from a thread
526  *
527  * @return The status of the clear flags request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY,
528  *         \ref CY_RTOS_GENERAL_ERROR]
529  */
530 cy_rslt_t cy_rtos_clearbits_event(cy_event_t* event, uint32_t bits, bool in_isr);
531 
532 /** Get the event bits.
533  *
534  * Returns the current bits for the event.
535  *
536  * @param[in]  event Pointer to the event handle
537  * @param[out] bits  pointer to receive the value of the event flags
538  *
539  * @return The status of the get request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
540  *         CY_RTOS_GENERAL_ERROR]
541  */
542 cy_rslt_t cy_rtos_getbits_event(cy_event_t* event, uint32_t* bits);
543 
544 /** Wait for the event and return bits.
545  *
546  * Waits for the event to be set and then returns the bits associated
547  * with the event, or waits for the given timeout period.
548  * @note This function returns if any bit in the set is set.
549  *
550  * @param[in] event        Pointer to the event handle
551  * @param[in,out] bits     pointer to receive the value of the event flags
552  * @param[in] clear        if true, clear any bits set that cause the wait to return
553  *                         if false, do not clear bits
554  * @param[in] all          if true, all bits in the initial bits value must be set to return
555  *                         if false, any one bit in the initial bits value must be set to return
556  * @param[in] timeout_ms   The amount of time to wait in milliseconds
557  *
558  * @return The status of the wait for event request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY,
559  *         \ref CY_RTOS_GENERAL_ERROR]
560  */
561 cy_rslt_t cy_rtos_waitbits_event(cy_event_t* event, uint32_t* bits, bool clear, bool all,
562                                  cy_time_t timeout_ms);
563 
564 /** Deinitialize a event.
565  *
566  * This function frees the resources associated with an event.
567  *
568  * @param[in] event Pointer to the event handle
569  *
570  * @return The status of the deletion request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
571  */
572 cy_rslt_t cy_rtos_deinit_event(cy_event_t* event);
573 
574 /** \} group_abstraction_rtos_event */
575 
576 /********************************************* Queues *********************************************/
577 
578 /**
579  * \ingroup group_abstraction_rtos_queue
580  * \{
581  */
582 
583 /** Create a queue.
584  *
585  * This is a queue of data where entries are placed on the back of the queue
586  * and removed from the front of the queue.
587  *
588  * @param[out] queue    Pointer to the queue handle
589  * @param[in]  length   The maximum length of the queue in items
590  * @param[in]  itemsize The size of each item in the queue.
591  *
592  * @return The status of the init request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
593  *         CY_RTOS_GENERAL_ERROR]
594  */
595 cy_rslt_t cy_rtos_init_queue(cy_queue_t* queue, size_t length, size_t itemsize);
596 
597 /** Put an item in a queue.
598  *
599  * This function puts an item in the queue. The item is copied
600  * into the queue using a memory copy and the data pointed to by item_ptr
601  * is no longer referenced once the call returns.
602  *
603  * @note If in_isr is true, timeout_ms must be zero.
604  *
605  * @param[in] queue      Pointer to the queue handle
606  * @param[in] item_ptr   Pointer to the item to place in the queue
607  * @param[in] timeout_ms The time to wait to place the item in the queue
608  * @param[in] in_isr     If true this is being called from within and ISR
609  *
610  * @return The status of the put request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
611  *         CY_RTOS_GENERAL_ERROR, \ref CY_RTOS_QUEUE_FULL]
612  */
613 cy_rslt_t cy_rtos_put_queue(cy_queue_t* queue, const void* item_ptr, cy_time_t timeout_ms,
614                             bool in_isr);
615 
616 /** Gets an item in a queue.
617  *
618  * This function gets an item from the queue. The item is copied
619  * out of the queue into the memory provide by item_ptr. This space must be
620  * large enough to hold a queue entry as defined when the queue was initialized.
621  *
622  * @note If in_isr is true, timeout_ms must be zero.
623  *
624  * @param[in] queue      Pointer to the queue handle
625  * @param[in] item_ptr   Pointer to the memory for the item from the queue
626  * @param[in] timeout_ms The time to wait to get an item from the queue
627  * @param[in] in_isr     If true this is being called from within an ISR
628  *
629  * @return The status of the get request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_NO_MEMORY, \ref
630  *         CY_RTOS_GENERAL_ERROR, \ref CY_RTOS_QUEUE_EMPTY]
631  */
632 cy_rslt_t cy_rtos_get_queue(cy_queue_t* queue, void* item_ptr, cy_time_t timeout_ms, bool in_isr);
633 
634 /** Return the number of items in the queue.
635  *
636  * This function returns the number of items currently in the queue.
637  *
638  * @param[in]  queue       Pointer to the queue handle
639  * @param[out] num_waiting Pointer to the return count
640  *
641  * @return The status of the count request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
642  */
643 cy_rslt_t cy_rtos_count_queue(cy_queue_t* queue, size_t* num_waiting);
644 
645 /** Return the amount of empty space in the queue.
646  *
647  * This function returns the amount of empty space in the
648  * queue. For instance, if the queue was created with 10 entries max and there
649  * are currently 2 entries in the queue, this will return 8.
650  *
651  * @param[in]  queue      Pointer to the queue handle
652  * @param[out] num_spaces Pointer to the return count.
653  *
654  * @return The status of the space request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
655  */
656 cy_rslt_t cy_rtos_space_queue(cy_queue_t* queue, size_t* num_spaces);
657 
658 /** Reset the queue.
659  *
660  * This function sets the queue to empty.
661  *
662  * @param[in] queue pointer to the queue handle
663  *
664  * @return The status of the reset request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
665  */
666 cy_rslt_t cy_rtos_reset_queue(cy_queue_t* queue);
667 
668 /** Deinitialize the queue handle.
669  *
670  * This function de-initializes the queue and returns all
671  * resources used by the queue.
672  *
673  * @param[in] queue Pointer to the queue handle
674  *
675  * @return The status of the deinit request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
676  */
677 cy_rslt_t cy_rtos_deinit_queue(cy_queue_t* queue);
678 
679 /** \} group_abstraction_rtos_queue */
680 
681 /********************************************* Timers *********************************************/
682 
683 /**
684  * \ingroup group_abstraction_rtos_timer
685  * \{
686  */
687 
688 /** Create a new timer.
689  *
690  * This function initializes a timer object.
691  * @note The timer is not active until start is called.
692  * @note The callback may be (likely will be) called from a different thread.
693  *
694  * @param[out] timer Pointer to the timer handle to initialize
695  * @param[in]  type  Type of timer (periodic or once)
696  * @param[in]  fun   The function
697  * @param[in]  arg   Argument to pass along to the callback function
698  *
699  * @return The status of the init request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
700  */
701 cy_rslt_t cy_rtos_init_timer(cy_timer_t* timer, cy_timer_trigger_type_t type,
702                              cy_timer_callback_t fun, cy_timer_callback_arg_t arg);
703 
704 /** Sends a request to start the timer. Depending on the priorities of threads in the system,
705  * it may be necessary for high priority items to wait before the timer actually starts running.
706  *
707  * @param[in] timer  Pointer to the timer handle
708  * @param[in] num_ms The number of milliseconds to wait before the timer fires
709  *
710  * @return The status of the start request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
711  */
712 cy_rslt_t cy_rtos_start_timer(cy_timer_t* timer, cy_time_t num_ms);
713 
714 /** Sends a request to stop the timer. Depending on the priorities of threads in the system,
715  * it may be necessary for high priority items to wait before the timer is actually stopped.
716  *
717  * @param[in] timer Pointer to the timer handle
718  *
719  * @return The status of the stop request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
720  */
721 cy_rslt_t cy_rtos_stop_timer(cy_timer_t* timer);
722 
723 /** Returns state of a timer.
724  *
725  * @param[in]  timer Pointer to the timer handle
726  * @param[out] state Return value for state, true if running, false otherwise
727  *
728  * @return The status of the is_running request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
729  */
730 cy_rslt_t cy_rtos_is_running_timer(cy_timer_t* timer, bool* state);
731 
732 /** Deinit the timer.
733  *
734  * This function deinitializes the timer and frees all consumed resources.
735  *
736  * @param[in] timer Pointer to the timer handle
737  *
738  * @return The status of the deinit request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
739  */
740 cy_rslt_t cy_rtos_deinit_timer(cy_timer_t* timer);
741 
742 /** \} group_abstraction_rtos_timer */
743 
744 /********************************************** Time **********************************************/
745 
746 /**
747  * \ingroup group_abstraction_rtos_time
748  * \{
749  */
750 
751 /** Gets time in milliseconds since RTOS start.
752  *
753  * @note Since this is only 32 bits, it will roll over every 49 days, 17 hours, 2 mins, 47.296
754  * seconds
755  *
756  * @param[out] tval Pointer to the struct to populate with the RTOS time
757  *
758  * @returns Time in milliseconds since the RTOS started.
759  */
760 cy_rslt_t cy_rtos_get_time(cy_time_t* tval);
761 
762 /** Delay for a number of milliseconds.
763  *
764  * Processing of this function depends on the minimum sleep
765  * time resolution of the RTOS. The current thread should sleep for
766  * the longest period possible which is less than the delay required,
767  * then makes up the difference with a tight loop.
768  *
769  * @param[in] num_ms The number of milliseconds to delay for
770  *
771  * @return The status of the delay request. [\ref CY_RSLT_SUCCESS, \ref CY_RTOS_GENERAL_ERROR]
772  */
773 cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms);
774 
775 /** \} group_abstraction_rtos_time */
776 
777 #ifdef __cplusplus
778 } // extern "C"
779 #endif
780