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_PRESTART:
235 *state = CY_THREAD_STATE_INACTIVE;
236 break;
237
238 case _THREAD_SUSPENDED:
239 case _THREAD_PENDING:
240 *state = CY_THREAD_STATE_BLOCKED;
241 break;
242
243 case _THREAD_QUEUED:
244 *state = CY_THREAD_STATE_READY;
245 break;
246
247 default:
248 *state = CY_THREAD_STATE_UNKNOWN;
249 break;
250 }
251 }
252 }
253
254 return status;
255 }
256
cy_rtos_join_thread(cy_thread_t * thread)257 cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread)
258 {
259 cy_rslt_t status = CY_RSLT_SUCCESS;
260 cy_rtos_error_t status_internal;
261
262 if (thread == NULL) {
263 status = CY_RTOS_BAD_PARAM;
264 } else {
265 if (*thread != NULL) {
266 /* Sleep until a thread exits */
267 status_internal = k_thread_join(&(*thread)->z_thread, K_FOREVER);
268 status = error_converter(status_internal);
269
270 if (status == CY_RSLT_SUCCESS) {
271 /* Free allocated thread object and stack buffer */
272 free_thead_obj(thread);
273 }
274 }
275 }
276
277 return status;
278 }
279
cy_rtos_get_thread_handle(cy_thread_t * thread)280 cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t *thread)
281 {
282 cy_rslt_t status = CY_RSLT_SUCCESS;
283
284 if (thread == NULL) {
285 status = CY_RTOS_BAD_PARAM;
286 } else {
287 *thread = (cy_thread_t)k_current_get();
288 }
289
290 return status;
291 }
292
cy_rtos_wait_thread_notification(cy_time_t timeout_ms)293 cy_rslt_t cy_rtos_wait_thread_notification(cy_time_t timeout_ms)
294 {
295 cy_rtos_error_t status_internal;
296 cy_rslt_t status = CY_RSLT_SUCCESS;
297
298 if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
299 status_internal = k_sleep(K_FOREVER);
300 } else {
301 status_internal = k_msleep((int32_t)timeout_ms);
302 if (status_internal == 0) {
303 status = CY_RTOS_TIMEOUT;
304 }
305 }
306
307 if ((status_internal < 0) && (status_internal != K_TICKS_FOREVER)) {
308 status = error_converter(status_internal);
309 }
310
311 return status;
312 }
313
cy_rtos_thread_set_notification(cy_thread_t * thread,bool in_isr)314 cy_rslt_t cy_rtos_thread_set_notification(cy_thread_t *thread, bool in_isr)
315 {
316 CY_UNUSED_PARAMETER(in_isr);
317
318 cy_rslt_t status = CY_RSLT_SUCCESS;
319
320 if (thread == NULL) {
321 status = CY_RTOS_BAD_PARAM;
322 } else {
323 k_wakeup(&(*thread)->z_thread);
324 }
325
326 return status;
327 }
328
329
330 /*
331 * Mutexes
332 */
333
cy_rtos_init_mutex2(cy_mutex_t * mutex,bool recursive)334 cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t *mutex, bool recursive)
335 {
336 cy_rtos_error_t status_internal;
337 cy_rslt_t status;
338
339 /* Non recursive mutex is not supported by Zephyr */
340 CY_UNUSED_PARAMETER(recursive);
341
342 if (mutex == NULL) {
343 status = CY_RTOS_BAD_PARAM;
344 } else {
345 /* Initialize a mutex object */
346 status_internal = k_mutex_init(mutex);
347 status = error_converter(status_internal);
348 }
349
350 return status;
351 }
352
cy_rtos_get_mutex(cy_mutex_t * mutex,cy_time_t timeout_ms)353 cy_rslt_t cy_rtos_get_mutex(cy_mutex_t *mutex, cy_time_t timeout_ms)
354 {
355 cy_rtos_error_t status_internal;
356 cy_rslt_t status;
357
358 if (mutex == NULL) {
359 status = CY_RTOS_BAD_PARAM;
360 } else if (k_is_in_isr()) {
361 /* Mutexes may not be locked in ISRs */
362 status = CY_RTOS_GENERAL_ERROR;
363 } else {
364 /* Convert timeout value */
365 k_timeout_t k_timeout =
366 (timeout_ms == CY_RTOS_NEVER_TIMEOUT) ? K_FOREVER : K_MSEC(timeout_ms);
367
368 /* Lock a mutex */
369 status_internal = k_mutex_lock(mutex, k_timeout);
370 status = error_converter(status_internal);
371 }
372
373 return status;
374 }
375
cy_rtos_set_mutex(cy_mutex_t * mutex)376 cy_rslt_t cy_rtos_set_mutex(cy_mutex_t *mutex)
377 {
378 cy_rtos_error_t status_internal;
379 cy_rslt_t status;
380
381 if (mutex == NULL) {
382 status = CY_RTOS_BAD_PARAM;
383 } else if (k_is_in_isr()) {
384 /* Mutexes may not be unlocked in ISRs */
385 status = CY_RTOS_GENERAL_ERROR;
386 } else {
387 /* Unlock a mutex */
388 status_internal = k_mutex_unlock(mutex);
389 status = error_converter(status_internal);
390 }
391
392 return status;
393 }
394
cy_rtos_deinit_mutex(cy_mutex_t * mutex)395 cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex)
396 {
397 cy_rslt_t status = CY_RSLT_SUCCESS;
398
399 if (mutex == NULL) {
400 status = CY_RTOS_BAD_PARAM;
401 } else {
402 /* Force unlock mutex, do not care about return */
403 (void)k_mutex_unlock(mutex);
404 }
405
406 return status;
407 }
408
409
410 /*
411 * Semaphores
412 */
413
cy_rtos_init_semaphore(cy_semaphore_t * semaphore,uint32_t maxcount,uint32_t initcount)414 cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount)
415 {
416 cy_rtos_error_t status_internal;
417 cy_rslt_t status;
418
419 if (semaphore == NULL) {
420 status = CY_RTOS_BAD_PARAM;
421 } else {
422 /* Initialize a semaphore object */
423 status_internal = k_sem_init(semaphore, initcount, maxcount);
424 status = error_converter(status_internal);
425 }
426
427 return status;
428 }
429
cy_rtos_get_semaphore(cy_semaphore_t * semaphore,cy_time_t timeout_ms,bool in_isr)430 cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr)
431 {
432 CY_UNUSED_PARAMETER(in_isr);
433
434 cy_rtos_error_t status_internal;
435 cy_rslt_t status;
436
437 if (semaphore == NULL) {
438 status = CY_RTOS_BAD_PARAM;
439 } else {
440 /* Convert timeout value */
441 k_timeout_t k_timeout;
442
443 if (k_is_in_isr()) {
444 /* NOTE: Based on Zephyr documentation when k_sem_take
445 * is called from ISR timeout must be set to K_NO_WAIT.
446 */
447 k_timeout = K_NO_WAIT;
448 } else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
449 k_timeout = K_FOREVER;
450 } else {
451 k_timeout = K_MSEC(timeout_ms);
452 }
453
454 /* Take a semaphore */
455 status_internal = k_sem_take(semaphore, k_timeout);
456 status = error_converter(status_internal);
457
458 if (k_is_in_isr() && (status_internal == -EBUSY)) {
459 status = CY_RSLT_SUCCESS;
460 }
461 }
462
463 return status;
464 }
465
cy_rtos_set_semaphore(cy_semaphore_t * semaphore,bool in_isr)466 cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr)
467 {
468 CY_UNUSED_PARAMETER(in_isr);
469
470 cy_rslt_t status = CY_RSLT_SUCCESS;
471
472 if (semaphore == NULL) {
473 status = CY_RTOS_BAD_PARAM;
474 } else {
475 /* Give a semaphore */
476 k_sem_give(semaphore);
477 }
478
479 return status;
480 }
481
cy_rtos_get_count_semaphore(cy_semaphore_t * semaphore,size_t * count)482 cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t *semaphore, size_t *count)
483 {
484 cy_rslt_t status = CY_RSLT_SUCCESS;
485
486 if ((semaphore == NULL) || (count == NULL)) {
487 status = CY_RTOS_BAD_PARAM;
488 } else {
489 *count = k_sem_count_get(semaphore);
490 }
491
492 return status;
493 }
494
cy_rtos_deinit_semaphore(cy_semaphore_t * semaphore)495 cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore)
496 {
497 cy_rslt_t status = CY_RSLT_SUCCESS;
498
499 if (semaphore == NULL) {
500 status = CY_RTOS_BAD_PARAM;
501 } else {
502 k_sem_reset(semaphore);
503 }
504
505 return status;
506 }
507
508
509 /*
510 * Events
511 */
512
cy_rtos_init_event(cy_event_t * event)513 cy_rslt_t cy_rtos_init_event(cy_event_t *event)
514 {
515 cy_rslt_t status = CY_RSLT_SUCCESS;
516
517 if (event == NULL) {
518 status = CY_RTOS_BAD_PARAM;
519 } else {
520 /* Initialize an event object */
521 k_event_init(event);
522 }
523
524 return status;
525 }
526
cy_rtos_setbits_event(cy_event_t * event,uint32_t bits,bool in_isr)527 cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
528 {
529 CY_UNUSED_PARAMETER(in_isr);
530
531 cy_rslt_t status = CY_RSLT_SUCCESS;
532
533 if (event == NULL) {
534 status = CY_RTOS_BAD_PARAM;
535 } else {
536 /* Post the new bits */
537 k_event_post(event, bits);
538 }
539
540 return status;
541 }
542
cy_rtos_clearbits_event(cy_event_t * event,uint32_t bits,bool in_isr)543 cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
544 {
545 CY_UNUSED_PARAMETER(in_isr);
546
547 cy_rslt_t status = CY_RSLT_SUCCESS;
548
549 if (event == NULL) {
550 status = CY_RTOS_BAD_PARAM;
551 } else {
552 uint32_t current_bits;
553
554 /* Reads events value */
555 status = cy_rtos_getbits_event(event, ¤t_bits);
556
557 /* Set masked value */
558 k_event_set(event, (~bits & current_bits));
559 }
560
561 return status;
562 }
563
cy_rtos_getbits_event(cy_event_t * event,uint32_t * bits)564 cy_rslt_t cy_rtos_getbits_event(cy_event_t *event, uint32_t *bits)
565 {
566 cy_rslt_t status = CY_RSLT_SUCCESS;
567
568 if ((event == NULL) || (bits == NULL)) {
569 status = CY_RTOS_BAD_PARAM;
570 } else {
571 /* NOTE: Zephyr does not provide function for get bits,
572 * retrieve it from event object.
573 */
574 *bits = event->events;
575 }
576
577 return status;
578 }
579
cy_rtos_waitbits_event(cy_event_t * event,uint32_t * bits,bool clear,bool all,cy_time_t timeout)580 cy_rslt_t cy_rtos_waitbits_event(cy_event_t *event, uint32_t *bits, bool clear, bool all,
581 cy_time_t timeout)
582 {
583 cy_rslt_t status;
584
585 if ((event == NULL) || (bits == NULL)) {
586 status = CY_RTOS_BAD_PARAM;
587 } else {
588 uint32_t wait_for = *bits;
589 k_timeout_t k_timeout =
590 (timeout == CY_RTOS_NEVER_TIMEOUT) ? K_FOREVER : K_MSEC(timeout);
591
592 if (all) {
593 /* Wait for all of the specified events */
594 *bits = k_event_wait_all(event, wait_for, false, k_timeout);
595 } else {
596 /* Wait for any of the specified events */
597 *bits = k_event_wait(event, wait_for, false, k_timeout);
598 }
599
600 /* Check timeout */
601 status = (*bits == 0) ? CY_RTOS_TIMEOUT : CY_RSLT_SUCCESS;
602
603 /* Return full current events */
604 cy_rtos_getbits_event(event, bits);
605
606 /* Crear bits if required */
607 if ((status == CY_RSLT_SUCCESS) && (clear == true)) {
608 cy_rtos_clearbits_event(event, wait_for, false);
609 }
610 }
611 return status;
612 }
613
cy_rtos_deinit_event(cy_event_t * event)614 cy_rslt_t cy_rtos_deinit_event(cy_event_t *event)
615 {
616 cy_rslt_t status = CY_RSLT_SUCCESS;
617
618 if (event != NULL) {
619 /* Clear event */
620 k_event_set(event, 0);
621 } else {
622 status = CY_RTOS_BAD_PARAM;
623 }
624 return status;
625 }
626
627
628 /*
629 * Queues
630 */
631
cy_rtos_init_queue(cy_queue_t * queue,size_t length,size_t itemsize)632 cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize)
633 {
634 cy_rtos_error_t status_internal;
635 cy_rslt_t status;
636
637 if (queue == NULL) {
638 status = CY_RTOS_BAD_PARAM;
639 } else {
640 /* Initialize a message queue */
641 status_internal = k_msgq_alloc_init(queue, itemsize, length);
642 status = error_converter(status_internal);
643 }
644
645 return status;
646 }
647
cy_rtos_put_queue(cy_queue_t * queue,const void * item_ptr,cy_time_t timeout_ms,bool in_isr)648 cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t timeout_ms,
649 bool in_isr)
650 {
651 CY_UNUSED_PARAMETER(in_isr);
652
653 cy_rtos_error_t status_internal;
654 cy_rslt_t status;
655
656 if ((queue == NULL) || (item_ptr == NULL)) {
657 status = CY_RTOS_BAD_PARAM;
658 } else {
659 /* Convert timeout value */
660 k_timeout_t k_timeout;
661
662 if (k_is_in_isr()) {
663 k_timeout = K_NO_WAIT;
664 } else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
665 k_timeout = K_FOREVER;
666 } else {
667 k_timeout = K_MSEC(timeout_ms);
668 }
669
670 /* Send a message to a message queue */
671 status_internal = k_msgq_put(queue, item_ptr, k_timeout);
672 status = error_converter(status_internal);
673 }
674
675 return status;
676 }
677
cy_rtos_get_queue(cy_queue_t * queue,void * item_ptr,cy_time_t timeout_ms,bool in_isr)678 cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout_ms, bool in_isr)
679 {
680 CY_UNUSED_PARAMETER(in_isr);
681
682 cy_rtos_error_t status_internal;
683 cy_rslt_t status;
684
685 if ((queue == NULL) || (item_ptr == NULL)) {
686 status = CY_RTOS_BAD_PARAM;
687 } else {
688 /* Convert timeout value */
689 k_timeout_t k_timeout;
690
691 if (k_is_in_isr()) {
692 k_timeout = K_NO_WAIT;
693 } else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
694 k_timeout = K_FOREVER;
695 } else {
696 k_timeout = K_MSEC(timeout_ms);
697 }
698
699 /* Receive a message from a message queue */
700 status_internal = k_msgq_get(queue, item_ptr, k_timeout);
701 status = error_converter(status_internal);
702 }
703
704 return status;
705 }
706
cy_rtos_count_queue(cy_queue_t * queue,size_t * num_waiting)707 cy_rslt_t cy_rtos_count_queue(cy_queue_t *queue, size_t *num_waiting)
708 {
709 cy_rslt_t status = CY_RSLT_SUCCESS;
710
711 if ((queue == NULL) || (num_waiting == NULL)) {
712 status = CY_RTOS_BAD_PARAM;
713 } else {
714 /* Get the number of messages in a message queue */
715 *num_waiting = k_msgq_num_used_get(queue);
716 }
717
718 return status;
719 }
720
cy_rtos_space_queue(cy_queue_t * queue,size_t * num_spaces)721 cy_rslt_t cy_rtos_space_queue(cy_queue_t *queue, size_t *num_spaces)
722 {
723 cy_rslt_t status = CY_RSLT_SUCCESS;
724
725 if ((queue == NULL) || (num_spaces == NULL)) {
726 status = CY_RTOS_BAD_PARAM;
727 } else {
728 /* Get the amount of free space in a message queue */
729 *num_spaces = k_msgq_num_free_get(queue);
730 }
731
732 return status;
733 }
734
cy_rtos_reset_queue(cy_queue_t * queue)735 cy_rslt_t cy_rtos_reset_queue(cy_queue_t *queue)
736 {
737 cy_rslt_t status = CY_RSLT_SUCCESS;
738
739 if (queue == NULL) {
740 status = CY_RTOS_BAD_PARAM;
741 } else {
742 /* Reset a message queue */
743 k_msgq_purge(queue);
744 }
745
746 return status;
747 }
748
cy_rtos_deinit_queue(cy_queue_t * queue)749 cy_rslt_t cy_rtos_deinit_queue(cy_queue_t *queue)
750 {
751 cy_rtos_error_t status_internal;
752 cy_rslt_t status;
753
754 if (queue == NULL) {
755 status = CY_RTOS_BAD_PARAM;
756 } else {
757 /* Reset a message queue */
758 status = cy_rtos_reset_queue(queue);
759
760 if (status == CY_RSLT_SUCCESS) {
761 /* Release allocated buffer for a queue */
762 status_internal = k_msgq_cleanup(queue);
763 status = error_converter(status_internal);
764 }
765 }
766
767 return status;
768 }
769
770
771 /*
772 * Timers
773 */
zephyr_timer_event_handler(struct k_timer * timer)774 static void zephyr_timer_event_handler(struct k_timer *timer)
775 {
776 cy_timer_t *_timer = (cy_timer_t *)timer;
777
778 ((cy_timer_callback_t)_timer->callback_function)(
779 (cy_timer_callback_arg_t)_timer->arg);
780 }
781
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)782 cy_rslt_t cy_rtos_init_timer(cy_timer_t *timer, cy_timer_trigger_type_t type,
783 cy_timer_callback_t fun, cy_timer_callback_arg_t arg)
784 {
785 cy_rslt_t status = CY_RSLT_SUCCESS;
786
787 if ((timer == NULL) || (fun == NULL)) {
788 status = CY_RTOS_BAD_PARAM;
789 } else {
790 timer->callback_function = (void *)fun;
791 timer->trigger_type = (uint32_t)type;
792 timer->arg = (void *)arg;
793
794 k_timer_init(&timer->z_timer, zephyr_timer_event_handler, NULL);
795 }
796
797 return status;
798 }
799
cy_rtos_start_timer(cy_timer_t * timer,cy_time_t num_ms)800 cy_rslt_t cy_rtos_start_timer(cy_timer_t *timer, cy_time_t num_ms)
801 {
802 cy_rslt_t status = CY_RSLT_SUCCESS;
803
804 if (timer == NULL) {
805 status = CY_RTOS_BAD_PARAM;
806 } else {
807 if ((cy_timer_trigger_type_t)timer->trigger_type == CY_TIMER_TYPE_ONCE) {
808 /* Called once only */
809 k_timer_start(&timer->z_timer, K_MSEC(num_ms), K_NO_WAIT);
810 } else {
811 /* Called periodically until stopped */
812 k_timer_start(&timer->z_timer, K_MSEC(num_ms), K_MSEC(num_ms));
813 }
814 }
815
816 return status;
817 }
818
cy_rtos_stop_timer(cy_timer_t * timer)819 cy_rslt_t cy_rtos_stop_timer(cy_timer_t *timer)
820 {
821 cy_rslt_t status = CY_RSLT_SUCCESS;
822
823 if (timer == NULL) {
824 status = CY_RTOS_BAD_PARAM;
825 } else {
826 /* Stop timer */
827 k_timer_stop(&timer->z_timer);
828 }
829
830 return status;
831 }
832
cy_rtos_is_running_timer(cy_timer_t * timer,bool * state)833 cy_rslt_t cy_rtos_is_running_timer(cy_timer_t *timer, bool *state)
834 {
835 cy_rslt_t status = CY_RSLT_SUCCESS;
836
837 if ((timer == NULL) || (state == NULL)) {
838 status = CY_RTOS_BAD_PARAM;
839 } else {
840 /* Check if running */
841 *state = (k_timer_remaining_get(&timer->z_timer) != 0u);
842 }
843
844 return status;
845 }
846
cy_rtos_deinit_timer(cy_timer_t * timer)847 cy_rslt_t cy_rtos_deinit_timer(cy_timer_t *timer)
848 {
849 cy_rslt_t status;
850
851 if (timer == NULL) {
852 status = CY_RTOS_BAD_PARAM;
853 } else {
854 bool running;
855
856 /* Get current timer state */
857 status = cy_rtos_is_running_timer(timer, &running);
858
859 /* Check if running */
860 if ((status == CY_RSLT_SUCCESS) && (running)) {
861 /* Stop timer */
862 status = cy_rtos_stop_timer(timer);
863 }
864 }
865
866 return status;
867 }
868
869
870 /*
871 * Time
872 */
873
cy_rtos_get_time(cy_time_t * tval)874 cy_rslt_t cy_rtos_get_time(cy_time_t *tval)
875 {
876 cy_rslt_t status = CY_RSLT_SUCCESS;
877
878 if (tval == NULL) {
879 status = CY_RTOS_BAD_PARAM;
880 } else {
881 /* Get system uptime (32-bit version) */
882 *tval = k_uptime_get_32();
883 }
884
885 return status;
886 }
887
cy_rtos_delay_milliseconds(cy_time_t num_ms)888 cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms)
889 {
890 cy_rslt_t status = CY_RSLT_SUCCESS;
891
892 if (k_is_in_isr()) {
893 status = CY_RTOS_GENERAL_ERROR;
894 } else {
895 k_msleep(num_ms);
896 }
897
898 return status;
899 }
900
901 #if defined(__cplusplus)
902 }
903 #endif
904