1 /***********************************************************************************************//**
2 * \file cyabs_rtos_zephyr.c
3 *
4 * \brief
5 * Implementation for Zephyr RTOS abstraction
6 *
7 ***************************************************************************************************
8 * \copyright
9 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation
11 *
12 * SPDX-License-Identifier: Apache-2.0
13 *
14 * Licensed under the Apache License, Version 2.0 (the "License");
15 * you may not use this file except in compliance with the License.
16 * You may obtain a copy of the License at
17 *
18 * http://www.apache.org/licenses/LICENSE-2.0
19 *
20 * Unless required by applicable law or agreed to in writing, software
21 * distributed under the License is distributed on an "AS IS" BASIS,
22 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 * See the License for the specific language governing permissions and
24 * limitations under the License.
25 **************************************************************************************************/
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <cy_utils.h>
30 #include <cyabs_rtos.h>
31
32 #if defined(__cplusplus)
33 extern "C" {
34 #endif
35
36
37 /*
38 * Error Converter
39 */
40
41 /* Last received error status */
42 static cy_rtos_error_t dbgErr;
43
cy_rtos_last_error(void)44 cy_rtos_error_t cy_rtos_last_error(void)
45 {
46 return dbgErr;
47 }
48
49 /* Converts internal error type to external error type */
error_converter(cy_rtos_error_t internalError)50 static cy_rslt_t error_converter(cy_rtos_error_t internalError)
51 {
52 cy_rslt_t value;
53
54 switch (internalError) {
55 case 0:
56 value = CY_RSLT_SUCCESS;
57 break;
58
59 case -EAGAIN:
60 value = CY_RTOS_TIMEOUT;
61 break;
62
63 case -EINVAL:
64 value = CY_RTOS_BAD_PARAM;
65 break;
66
67 case -ENOMEM:
68 value = CY_RTOS_NO_MEMORY;
69 break;
70
71 default:
72 value = CY_RTOS_GENERAL_ERROR;
73 break;
74 }
75
76 /* Update the last known error status */
77 dbgErr = internalError;
78
79 return value;
80 }
81
free_thead_obj(cy_thread_t * thread)82 static void free_thead_obj(cy_thread_t *thread)
83 {
84 /* Free allocated stack buffer */
85 if ((*thread)->memptr != NULL) {
86 k_free((*thread)->memptr);
87 }
88
89 /* Free object */
90 k_free(*thread);
91 }
92
93
94 /*
95 * Threads
96 */
97
thread_entry_function_wrapper(void * p1,void * p2,void * p3)98 static void thread_entry_function_wrapper(void *p1, void *p2, void *p3)
99 {
100 CY_UNUSED_PARAMETER(p3);
101 ((cy_thread_entry_fn_t)p2)(p1);
102 }
103
cy_rtos_create_thread(cy_thread_t * thread,cy_thread_entry_fn_t entry_function,const char * name,void * stack,uint32_t stack_size,cy_thread_priority_t priority,cy_thread_arg_t arg)104 cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_function,
105 const char *name, void *stack, uint32_t stack_size,
106 cy_thread_priority_t priority, cy_thread_arg_t arg)
107 {
108 cy_rslt_t status = CY_RSLT_SUCCESS;
109 cy_rtos_error_t status_internal = 0;
110
111 if ((thread == NULL) || (stack_size < CY_RTOS_MIN_STACK_SIZE)) {
112 status = CY_RTOS_BAD_PARAM;
113 } else if ((stack != NULL) && (0 != (((uint32_t)stack) & CY_RTOS_ALIGNMENT_MASK))) {
114 status = CY_RTOS_ALIGNMENT_ERROR;
115 } else {
116 void *stack_alloc = NULL;
117 k_tid_t my_tid = NULL;
118
119 /* Allocate cy_thread_t object */
120 *thread = k_malloc(sizeof(k_thread_wrapper_t));
121
122 /* Allocate stack if NULL was passed */
123 if ((uint32_t *)stack == NULL) {
124 stack_alloc = k_aligned_alloc(Z_KERNEL_STACK_OBJ_ALIGN,
125 K_KERNEL_STACK_LEN(stack_size));
126
127 /* Store pointer to allocated stack,
128 * NULL if not allocated by cy_rtos_thread_create (passed by application).
129 */
130 (*thread)->memptr = stack_alloc;
131 } else {
132 stack_alloc = stack;
133 (*thread)->memptr = NULL;
134 }
135
136 if (stack_alloc == NULL) {
137 status = CY_RTOS_NO_MEMORY;
138 } else {
139 /* Create thread */
140 my_tid = k_thread_create(&(*thread)->z_thread, stack_alloc, stack_size,
141 thread_entry_function_wrapper,
142 (cy_thread_arg_t)arg, (void *)entry_function, NULL,
143 priority, 0, K_NO_WAIT);
144
145 /* Set thread name */
146 status_internal = k_thread_name_set(my_tid, name);
147 /* NOTE: k_thread_name_set returns -ENOSYS if thread name
148 * configuration option not enabled.
149 */
150 }
151
152 if ((my_tid == NULL) || ((status_internal != 0) && (status_internal != -ENOSYS))) {
153 status = CY_RTOS_GENERAL_ERROR;
154
155 /* Free allocated thread object and stack buffer */
156 free_thead_obj(thread);
157 }
158 }
159
160 return status;
161 }
162
cy_rtos_exit_thread(void)163 cy_rslt_t cy_rtos_exit_thread(void)
164 {
165 cy_rslt_t status = CY_RSLT_SUCCESS;
166
167 if (k_is_in_isr()) {
168 status = CY_RTOS_GENERAL_ERROR;
169 } else {
170 cy_thread_t thread = (cy_thread_t)k_current_get();
171
172 /* Abort thread */
173 k_thread_abort((k_tid_t)&(thread)->z_thread);
174
175 CODE_UNREACHABLE;
176 }
177
178 return status;
179 }
180
cy_rtos_terminate_thread(cy_thread_t * thread)181 cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread)
182 {
183 cy_rslt_t status = CY_RSLT_SUCCESS;
184
185 if (thread == NULL) {
186 status = CY_RTOS_BAD_PARAM;
187 } else if (k_is_in_isr()) {
188 status = CY_RTOS_GENERAL_ERROR;
189 } else {
190 /* Abort thread */
191 k_thread_abort((k_tid_t)&(*thread)->z_thread);
192
193 /* Free allocated stack buffer */
194 if ((*thread)->memptr != NULL) {
195 k_free((*thread)->memptr);
196 }
197 }
198
199 return status;
200 }
201
cy_rtos_is_thread_running(cy_thread_t * thread,bool * running)202 cy_rslt_t cy_rtos_is_thread_running(cy_thread_t *thread, bool *running)
203 {
204 cy_rslt_t status = CY_RSLT_SUCCESS;
205
206 if ((thread == NULL) || (running == NULL)) {
207 status = CY_RTOS_BAD_PARAM;
208 } else {
209 *running = (k_current_get() == &(*thread)->z_thread) ? true : false;
210 }
211
212 return status;
213 }
cy_rtos_get_thread_state(cy_thread_t * thread,cy_thread_state_t * state)214 cy_rslt_t cy_rtos_get_thread_state(cy_thread_t *thread, cy_thread_state_t *state)
215 {
216 cy_rslt_t status = CY_RSLT_SUCCESS;
217
218 if ((thread == NULL) || (state == NULL)) {
219 status = CY_RTOS_BAD_PARAM;
220 } else {
221 if (k_is_in_isr()) {
222 *state = CY_THREAD_STATE_UNKNOWN;
223 } else if (k_current_get() == &(*thread)->z_thread) {
224 *state = CY_THREAD_STATE_RUNNING;
225 }
226 if (((*thread)->z_thread.base.thread_state & _THREAD_DEAD) != 0) {
227 *state = CY_THREAD_STATE_TERMINATED;
228 } else {
229 switch ((*thread)->z_thread.base.thread_state) {
230 case _THREAD_DUMMY:
231 *state = CY_THREAD_STATE_UNKNOWN;
232 break;
233
234 case _THREAD_SUSPENDED:
235 case _THREAD_SLEEPING:
236 case _THREAD_PENDING:
237 *state = CY_THREAD_STATE_BLOCKED;
238 break;
239
240 case _THREAD_QUEUED:
241 *state = CY_THREAD_STATE_READY;
242 break;
243
244 default:
245 *state = CY_THREAD_STATE_UNKNOWN;
246 break;
247 }
248 }
249 }
250
251 return status;
252 }
253
cy_rtos_join_thread(cy_thread_t * thread)254 cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread)
255 {
256 cy_rslt_t status = CY_RSLT_SUCCESS;
257 cy_rtos_error_t status_internal;
258
259 if (thread == NULL) {
260 status = CY_RTOS_BAD_PARAM;
261 } else {
262 if (*thread != NULL) {
263 /* Sleep until a thread exits */
264 status_internal = k_thread_join(&(*thread)->z_thread, K_FOREVER);
265 status = error_converter(status_internal);
266
267 if (status == CY_RSLT_SUCCESS) {
268 /* Free allocated thread object and stack buffer */
269 free_thead_obj(thread);
270 }
271 }
272 }
273
274 return status;
275 }
276
cy_rtos_get_thread_handle(cy_thread_t * thread)277 cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t *thread)
278 {
279 cy_rslt_t status = CY_RSLT_SUCCESS;
280
281 if (thread == NULL) {
282 status = CY_RTOS_BAD_PARAM;
283 } else {
284 *thread = (cy_thread_t)k_current_get();
285 }
286
287 return status;
288 }
289
cy_rtos_wait_thread_notification(cy_time_t timeout_ms)290 cy_rslt_t cy_rtos_wait_thread_notification(cy_time_t timeout_ms)
291 {
292 cy_rtos_error_t status_internal;
293 cy_rslt_t status = CY_RSLT_SUCCESS;
294
295 if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
296 status_internal = k_sleep(K_FOREVER);
297 } else {
298 status_internal = k_msleep((int32_t)timeout_ms);
299 if (status_internal == 0) {
300 status = CY_RTOS_TIMEOUT;
301 }
302 }
303
304 if ((status_internal < 0) && (status_internal != K_TICKS_FOREVER)) {
305 status = error_converter(status_internal);
306 }
307
308 return status;
309 }
310
cy_rtos_thread_set_notification(cy_thread_t * thread,bool in_isr)311 cy_rslt_t cy_rtos_thread_set_notification(cy_thread_t *thread, bool in_isr)
312 {
313 CY_UNUSED_PARAMETER(in_isr);
314
315 cy_rslt_t status = CY_RSLT_SUCCESS;
316
317 if (thread == NULL) {
318 status = CY_RTOS_BAD_PARAM;
319 } else {
320 k_wakeup(&(*thread)->z_thread);
321 }
322
323 return status;
324 }
325
326
327 /*
328 * Mutexes
329 */
330
cy_rtos_init_mutex2(cy_mutex_t * mutex,bool recursive)331 cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t *mutex, bool recursive)
332 {
333 cy_rtos_error_t status_internal;
334 cy_rslt_t status;
335
336 /* Non recursive mutex is not supported by Zephyr */
337 CY_UNUSED_PARAMETER(recursive);
338
339 if (mutex == NULL) {
340 status = CY_RTOS_BAD_PARAM;
341 } else {
342 /* Initialize a mutex object */
343 status_internal = k_mutex_init(mutex);
344 status = error_converter(status_internal);
345 }
346
347 return status;
348 }
349
cy_rtos_get_mutex(cy_mutex_t * mutex,cy_time_t timeout_ms)350 cy_rslt_t cy_rtos_get_mutex(cy_mutex_t *mutex, cy_time_t timeout_ms)
351 {
352 cy_rtos_error_t status_internal;
353 cy_rslt_t status;
354
355 if (mutex == NULL) {
356 status = CY_RTOS_BAD_PARAM;
357 } else if (k_is_in_isr()) {
358 /* Mutexes may not be locked in ISRs */
359 status = CY_RTOS_GENERAL_ERROR;
360 } else {
361 /* Convert timeout value */
362 k_timeout_t k_timeout =
363 (timeout_ms == CY_RTOS_NEVER_TIMEOUT) ? K_FOREVER : K_MSEC(timeout_ms);
364
365 /* Lock a mutex */
366 status_internal = k_mutex_lock(mutex, k_timeout);
367 status = error_converter(status_internal);
368 }
369
370 return status;
371 }
372
cy_rtos_set_mutex(cy_mutex_t * mutex)373 cy_rslt_t cy_rtos_set_mutex(cy_mutex_t *mutex)
374 {
375 cy_rtos_error_t status_internal;
376 cy_rslt_t status;
377
378 if (mutex == NULL) {
379 status = CY_RTOS_BAD_PARAM;
380 } else if (k_is_in_isr()) {
381 /* Mutexes may not be unlocked in ISRs */
382 status = CY_RTOS_GENERAL_ERROR;
383 } else {
384 /* Unlock a mutex */
385 status_internal = k_mutex_unlock(mutex);
386 status = error_converter(status_internal);
387 }
388
389 return status;
390 }
391
cy_rtos_deinit_mutex(cy_mutex_t * mutex)392 cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex)
393 {
394 cy_rslt_t status = CY_RSLT_SUCCESS;
395
396 if (mutex == NULL) {
397 status = CY_RTOS_BAD_PARAM;
398 } else {
399 /* Force unlock mutex, do not care about return */
400 (void)k_mutex_unlock(mutex);
401 }
402
403 return status;
404 }
405
406
407 /*
408 * Semaphores
409 */
410
cy_rtos_init_semaphore(cy_semaphore_t * semaphore,uint32_t maxcount,uint32_t initcount)411 cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount)
412 {
413 cy_rtos_error_t status_internal;
414 cy_rslt_t status;
415
416 if (semaphore == NULL) {
417 status = CY_RTOS_BAD_PARAM;
418 } else {
419 /* Initialize a semaphore object */
420 status_internal = k_sem_init(semaphore, initcount, maxcount);
421 status = error_converter(status_internal);
422 }
423
424 return status;
425 }
426
cy_rtos_get_semaphore(cy_semaphore_t * semaphore,cy_time_t timeout_ms,bool in_isr)427 cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr)
428 {
429 CY_UNUSED_PARAMETER(in_isr);
430
431 cy_rtos_error_t status_internal;
432 cy_rslt_t status;
433
434 if (semaphore == NULL) {
435 status = CY_RTOS_BAD_PARAM;
436 } else {
437 /* Convert timeout value */
438 k_timeout_t k_timeout;
439
440 if (k_is_in_isr()) {
441 /* NOTE: Based on Zephyr documentation when k_sem_take
442 * is called from ISR timeout must be set to K_NO_WAIT.
443 */
444 k_timeout = K_NO_WAIT;
445 } else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
446 k_timeout = K_FOREVER;
447 } else {
448 k_timeout = K_MSEC(timeout_ms);
449 }
450
451 /* Take a semaphore */
452 status_internal = k_sem_take(semaphore, k_timeout);
453 status = error_converter(status_internal);
454
455 if (k_is_in_isr() && (status_internal == -EBUSY)) {
456 status = CY_RSLT_SUCCESS;
457 }
458 }
459
460 return status;
461 }
462
cy_rtos_set_semaphore(cy_semaphore_t * semaphore,bool in_isr)463 cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr)
464 {
465 CY_UNUSED_PARAMETER(in_isr);
466
467 cy_rslt_t status = CY_RSLT_SUCCESS;
468
469 if (semaphore == NULL) {
470 status = CY_RTOS_BAD_PARAM;
471 } else {
472 /* Give a semaphore */
473 k_sem_give(semaphore);
474 }
475
476 return status;
477 }
478
cy_rtos_get_count_semaphore(cy_semaphore_t * semaphore,size_t * count)479 cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t *semaphore, size_t *count)
480 {
481 cy_rslt_t status = CY_RSLT_SUCCESS;
482
483 if ((semaphore == NULL) || (count == NULL)) {
484 status = CY_RTOS_BAD_PARAM;
485 } else {
486 *count = k_sem_count_get(semaphore);
487 }
488
489 return status;
490 }
491
cy_rtos_deinit_semaphore(cy_semaphore_t * semaphore)492 cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore)
493 {
494 cy_rslt_t status = CY_RSLT_SUCCESS;
495
496 if (semaphore == NULL) {
497 status = CY_RTOS_BAD_PARAM;
498 } else {
499 k_sem_reset(semaphore);
500 }
501
502 return status;
503 }
504
505
506 /*
507 * Events
508 */
509
cy_rtos_init_event(cy_event_t * event)510 cy_rslt_t cy_rtos_init_event(cy_event_t *event)
511 {
512 cy_rslt_t status = CY_RSLT_SUCCESS;
513
514 if (event == NULL) {
515 status = CY_RTOS_BAD_PARAM;
516 } else {
517 /* Initialize an event object */
518 k_event_init(event);
519 }
520
521 return status;
522 }
523
cy_rtos_setbits_event(cy_event_t * event,uint32_t bits,bool in_isr)524 cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
525 {
526 CY_UNUSED_PARAMETER(in_isr);
527
528 cy_rslt_t status = CY_RSLT_SUCCESS;
529
530 if (event == NULL) {
531 status = CY_RTOS_BAD_PARAM;
532 } else {
533 /* Post the new bits */
534 k_event_post(event, bits);
535 }
536
537 return status;
538 }
539
cy_rtos_clearbits_event(cy_event_t * event,uint32_t bits,bool in_isr)540 cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
541 {
542 CY_UNUSED_PARAMETER(in_isr);
543
544 cy_rslt_t status = CY_RSLT_SUCCESS;
545
546 if (event == NULL) {
547 status = CY_RTOS_BAD_PARAM;
548 } else {
549 uint32_t current_bits;
550
551 /* Reads events value */
552 status = cy_rtos_getbits_event(event, ¤t_bits);
553
554 /* Set masked value */
555 k_event_set(event, (~bits & current_bits));
556 }
557
558 return status;
559 }
560
cy_rtos_getbits_event(cy_event_t * event,uint32_t * bits)561 cy_rslt_t cy_rtos_getbits_event(cy_event_t *event, uint32_t *bits)
562 {
563 cy_rslt_t status = CY_RSLT_SUCCESS;
564
565 if ((event == NULL) || (bits == NULL)) {
566 status = CY_RTOS_BAD_PARAM;
567 } else {
568 /* NOTE: Zephyr does not provide function for get bits,
569 * retrieve it from event object.
570 */
571 *bits = event->events;
572 }
573
574 return status;
575 }
576
cy_rtos_waitbits_event(cy_event_t * event,uint32_t * bits,bool clear,bool all,cy_time_t timeout)577 cy_rslt_t cy_rtos_waitbits_event(cy_event_t *event, uint32_t *bits, bool clear, bool all,
578 cy_time_t timeout)
579 {
580 cy_rslt_t status;
581
582 if ((event == NULL) || (bits == NULL)) {
583 status = CY_RTOS_BAD_PARAM;
584 } else {
585 uint32_t wait_for = *bits;
586 k_timeout_t k_timeout =
587 (timeout == CY_RTOS_NEVER_TIMEOUT) ? K_FOREVER : K_MSEC(timeout);
588
589 if (all) {
590 /* Wait for all of the specified events */
591 *bits = k_event_wait_all(event, wait_for, false, k_timeout);
592 } else {
593 /* Wait for any of the specified events */
594 *bits = k_event_wait(event, wait_for, false, k_timeout);
595 }
596
597 /* Check timeout */
598 status = (*bits == 0) ? CY_RTOS_TIMEOUT : CY_RSLT_SUCCESS;
599
600 /* Return full current events */
601 cy_rtos_getbits_event(event, bits);
602
603 /* Crear bits if required */
604 if ((status == CY_RSLT_SUCCESS) && (clear == true)) {
605 cy_rtos_clearbits_event(event, wait_for, false);
606 }
607 }
608 return status;
609 }
610
cy_rtos_deinit_event(cy_event_t * event)611 cy_rslt_t cy_rtos_deinit_event(cy_event_t *event)
612 {
613 cy_rslt_t status = CY_RSLT_SUCCESS;
614
615 if (event != NULL) {
616 /* Clear event */
617 k_event_set(event, 0);
618 } else {
619 status = CY_RTOS_BAD_PARAM;
620 }
621 return status;
622 }
623
624
625 /*
626 * Queues
627 */
628
cy_rtos_init_queue(cy_queue_t * queue,size_t length,size_t itemsize)629 cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize)
630 {
631 cy_rtos_error_t status_internal;
632 cy_rslt_t status;
633
634 if (queue == NULL) {
635 status = CY_RTOS_BAD_PARAM;
636 } else {
637 /* Initialize a message queue */
638 status_internal = k_msgq_alloc_init(queue, itemsize, length);
639 status = error_converter(status_internal);
640 }
641
642 return status;
643 }
644
cy_rtos_put_queue(cy_queue_t * queue,const void * item_ptr,cy_time_t timeout_ms,bool in_isr)645 cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t timeout_ms,
646 bool in_isr)
647 {
648 CY_UNUSED_PARAMETER(in_isr);
649
650 cy_rtos_error_t status_internal;
651 cy_rslt_t status;
652
653 if ((queue == NULL) || (item_ptr == NULL)) {
654 status = CY_RTOS_BAD_PARAM;
655 } else {
656 /* Convert timeout value */
657 k_timeout_t k_timeout;
658
659 if (k_is_in_isr()) {
660 k_timeout = K_NO_WAIT;
661 } else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
662 k_timeout = K_FOREVER;
663 } else {
664 k_timeout = K_MSEC(timeout_ms);
665 }
666
667 /* Send a message to a message queue */
668 status_internal = k_msgq_put(queue, item_ptr, k_timeout);
669 status = error_converter(status_internal);
670 }
671
672 return status;
673 }
674
cy_rtos_get_queue(cy_queue_t * queue,void * item_ptr,cy_time_t timeout_ms,bool in_isr)675 cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout_ms, bool in_isr)
676 {
677 CY_UNUSED_PARAMETER(in_isr);
678
679 cy_rtos_error_t status_internal;
680 cy_rslt_t status;
681
682 if ((queue == NULL) || (item_ptr == NULL)) {
683 status = CY_RTOS_BAD_PARAM;
684 } else {
685 /* Convert timeout value */
686 k_timeout_t k_timeout;
687
688 if (k_is_in_isr()) {
689 k_timeout = K_NO_WAIT;
690 } else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
691 k_timeout = K_FOREVER;
692 } else {
693 k_timeout = K_MSEC(timeout_ms);
694 }
695
696 /* Receive a message from a message queue */
697 status_internal = k_msgq_get(queue, item_ptr, k_timeout);
698 status = error_converter(status_internal);
699 }
700
701 return status;
702 }
703
cy_rtos_count_queue(cy_queue_t * queue,size_t * num_waiting)704 cy_rslt_t cy_rtos_count_queue(cy_queue_t *queue, size_t *num_waiting)
705 {
706 cy_rslt_t status = CY_RSLT_SUCCESS;
707
708 if ((queue == NULL) || (num_waiting == NULL)) {
709 status = CY_RTOS_BAD_PARAM;
710 } else {
711 /* Get the number of messages in a message queue */
712 *num_waiting = k_msgq_num_used_get(queue);
713 }
714
715 return status;
716 }
717
cy_rtos_space_queue(cy_queue_t * queue,size_t * num_spaces)718 cy_rslt_t cy_rtos_space_queue(cy_queue_t *queue, size_t *num_spaces)
719 {
720 cy_rslt_t status = CY_RSLT_SUCCESS;
721
722 if ((queue == NULL) || (num_spaces == NULL)) {
723 status = CY_RTOS_BAD_PARAM;
724 } else {
725 /* Get the amount of free space in a message queue */
726 *num_spaces = k_msgq_num_free_get(queue);
727 }
728
729 return status;
730 }
731
cy_rtos_reset_queue(cy_queue_t * queue)732 cy_rslt_t cy_rtos_reset_queue(cy_queue_t *queue)
733 {
734 cy_rslt_t status = CY_RSLT_SUCCESS;
735
736 if (queue == NULL) {
737 status = CY_RTOS_BAD_PARAM;
738 } else {
739 /* Reset a message queue */
740 k_msgq_purge(queue);
741 }
742
743 return status;
744 }
745
cy_rtos_deinit_queue(cy_queue_t * queue)746 cy_rslt_t cy_rtos_deinit_queue(cy_queue_t *queue)
747 {
748 cy_rtos_error_t status_internal;
749 cy_rslt_t status;
750
751 if (queue == NULL) {
752 status = CY_RTOS_BAD_PARAM;
753 } else {
754 /* Reset a message queue */
755 status = cy_rtos_reset_queue(queue);
756
757 if (status == CY_RSLT_SUCCESS) {
758 /* Release allocated buffer for a queue */
759 status_internal = k_msgq_cleanup(queue);
760 status = error_converter(status_internal);
761 }
762 }
763
764 return status;
765 }
766
767
768 /*
769 * Timers
770 */
zephyr_timer_event_handler(struct k_timer * timer)771 static void zephyr_timer_event_handler(struct k_timer *timer)
772 {
773 cy_timer_t *_timer = (cy_timer_t *)timer;
774
775 ((cy_timer_callback_t)_timer->callback_function)(
776 (cy_timer_callback_arg_t)_timer->arg);
777 }
778
cy_rtos_init_timer(cy_timer_t * timer,cy_timer_trigger_type_t type,cy_timer_callback_t fun,cy_timer_callback_arg_t arg)779 cy_rslt_t cy_rtos_init_timer(cy_timer_t *timer, cy_timer_trigger_type_t type,
780 cy_timer_callback_t fun, cy_timer_callback_arg_t arg)
781 {
782 cy_rslt_t status = CY_RSLT_SUCCESS;
783
784 if ((timer == NULL) || (fun == NULL)) {
785 status = CY_RTOS_BAD_PARAM;
786 } else {
787 timer->callback_function = (void *)fun;
788 timer->trigger_type = (uint32_t)type;
789 timer->arg = (void *)arg;
790
791 k_timer_init(&timer->z_timer, zephyr_timer_event_handler, NULL);
792 }
793
794 return status;
795 }
796
cy_rtos_start_timer(cy_timer_t * timer,cy_time_t num_ms)797 cy_rslt_t cy_rtos_start_timer(cy_timer_t *timer, cy_time_t num_ms)
798 {
799 cy_rslt_t status = CY_RSLT_SUCCESS;
800
801 if (timer == NULL) {
802 status = CY_RTOS_BAD_PARAM;
803 } else {
804 if ((cy_timer_trigger_type_t)timer->trigger_type == CY_TIMER_TYPE_ONCE) {
805 /* Called once only */
806 k_timer_start(&timer->z_timer, K_MSEC(num_ms), K_NO_WAIT);
807 } else {
808 /* Called periodically until stopped */
809 k_timer_start(&timer->z_timer, K_MSEC(num_ms), K_MSEC(num_ms));
810 }
811 }
812
813 return status;
814 }
815
cy_rtos_stop_timer(cy_timer_t * timer)816 cy_rslt_t cy_rtos_stop_timer(cy_timer_t *timer)
817 {
818 cy_rslt_t status = CY_RSLT_SUCCESS;
819
820 if (timer == NULL) {
821 status = CY_RTOS_BAD_PARAM;
822 } else {
823 /* Stop timer */
824 k_timer_stop(&timer->z_timer);
825 }
826
827 return status;
828 }
829
cy_rtos_is_running_timer(cy_timer_t * timer,bool * state)830 cy_rslt_t cy_rtos_is_running_timer(cy_timer_t *timer, bool *state)
831 {
832 cy_rslt_t status = CY_RSLT_SUCCESS;
833
834 if ((timer == NULL) || (state == NULL)) {
835 status = CY_RTOS_BAD_PARAM;
836 } else {
837 /* Check if running */
838 *state = (k_timer_remaining_get(&timer->z_timer) != 0u);
839 }
840
841 return status;
842 }
843
cy_rtos_deinit_timer(cy_timer_t * timer)844 cy_rslt_t cy_rtos_deinit_timer(cy_timer_t *timer)
845 {
846 cy_rslt_t status;
847
848 if (timer == NULL) {
849 status = CY_RTOS_BAD_PARAM;
850 } else {
851 bool running;
852
853 /* Get current timer state */
854 status = cy_rtos_is_running_timer(timer, &running);
855
856 /* Check if running */
857 if ((status == CY_RSLT_SUCCESS) && (running)) {
858 /* Stop timer */
859 status = cy_rtos_stop_timer(timer);
860 }
861 }
862
863 return status;
864 }
865
866
867 /*
868 * Time
869 */
870
cy_rtos_get_time(cy_time_t * tval)871 cy_rslt_t cy_rtos_get_time(cy_time_t *tval)
872 {
873 cy_rslt_t status = CY_RSLT_SUCCESS;
874
875 if (tval == NULL) {
876 status = CY_RTOS_BAD_PARAM;
877 } else {
878 /* Get system uptime (32-bit version) */
879 *tval = k_uptime_get_32();
880 }
881
882 return status;
883 }
884
cy_rtos_delay_milliseconds(cy_time_t num_ms)885 cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms)
886 {
887 cy_rslt_t status = CY_RSLT_SUCCESS;
888
889 if (k_is_in_isr()) {
890 status = CY_RTOS_GENERAL_ERROR;
891 } else {
892 k_msleep(num_ms);
893 }
894
895 return status;
896 }
897
898 #if defined(__cplusplus)
899 }
900 #endif
901