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