1 /***********************************************************************************************//**
2 * \file cyabs_rtos_rtxv5.c
3 *
4 * \brief
5 * Implementation for CMSIS RTOS v2 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 <cy_utils.h>
29 #include <cyabs_rtos.h>
30 #include "cyabs_rtos_internal.h"
31
32 #if defined(__cplusplus)
33 extern "C" {
34 #endif
35
36 #define CY_RTOS_THREAD_FLAG 0x01
37
38 /******************************************************
39 * Error Converter
40 ******************************************************/
41
42 // Last received error status
43 static cy_rtos_error_t dbgErr;
44
45
46 //--------------------------------------------------------------------------------------------------
47 // cy_rtos_last_error
48 //--------------------------------------------------------------------------------------------------
cy_rtos_last_error(void)49 cy_rtos_error_t cy_rtos_last_error(void)
50 {
51 return dbgErr;
52 }
53
54
55 //--------------------------------------------------------------------------------------------------
56 // error_converter
57 //
58 // Converts internal error type to external error type
59 //--------------------------------------------------------------------------------------------------
error_converter(cy_rtos_error_t internalError)60 static cy_rslt_t error_converter(cy_rtos_error_t internalError)
61 {
62 cy_rslt_t value;
63
64 switch (internalError)
65 {
66 case osOK:
67 value = CY_RSLT_SUCCESS;
68 break;
69
70 case osErrorTimeout:
71 value = CY_RTOS_TIMEOUT;
72 break;
73
74 case osErrorParameter:
75 value = CY_RTOS_BAD_PARAM;
76 break;
77
78 case osErrorNoMemory:
79 value = CY_RTOS_NO_MEMORY;
80 break;
81
82 case osError:
83 case osErrorResource:
84 case osErrorISR:
85 default:
86 value = CY_RTOS_GENERAL_ERROR;
87 break;
88 }
89
90 // Update the last known error status
91 dbgErr = internalError;
92 return value;
93 }
94
95
96 //--------------------------------------------------------------------------------------------------
97 // convert_ms_to_ticks
98 //--------------------------------------------------------------------------------------------------
convert_ms_to_ticks(cy_time_t timeout_ms)99 static uint32_t convert_ms_to_ticks(cy_time_t timeout_ms)
100 {
101 if (timeout_ms == CY_RTOS_NEVER_TIMEOUT)
102 {
103 return osWaitForever;
104 }
105 else if (timeout_ms == 0)
106 {
107 return 0;
108 }
109 else
110 {
111 // Get number of ticks per second
112 uint32_t tick_freq = osKernelGetTickFreq();
113 uint32_t ticks = (uint32_t)(((uint64_t)timeout_ms * tick_freq) / 1000);
114
115 if (ticks == 0)
116 {
117 ticks = 1;
118 }
119 else if (ticks >= UINT32_MAX)
120 {
121 // if ticks if more than 32 bits, change ticks to max possible value that isn't
122 // osWaitForever.
123 ticks = UINT32_MAX - 1;
124 }
125 return ticks;
126 }
127 }
128
129
130 /******************************************************
131 * Threads
132 ******************************************************/
133
cy_rtos_thread_create(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)134 cy_rslt_t cy_rtos_thread_create(cy_thread_t* thread, cy_thread_entry_fn_t entry_function,
135 const char* name, void* stack, uint32_t stack_size,
136 cy_thread_priority_t priority, cy_thread_arg_t arg)
137 {
138 cy_rslt_t status = CY_RSLT_SUCCESS;
139 osThreadAttr_t attr;
140
141 if ((thread == NULL) || (stack_size < CY_RTOS_MIN_STACK_SIZE))
142 {
143 status = CY_RTOS_BAD_PARAM;
144 }
145 else if ((stack != NULL) && (0 != (((uint32_t)stack) & CY_RTOS_ALIGNMENT_MASK)))
146 {
147 status = CY_RTOS_ALIGNMENT_ERROR;
148 }
149 else
150 {
151 attr.name = name;
152 attr.attr_bits = osThreadJoinable;
153 attr.cb_size = osRtxThreadCbSize;
154 attr.stack_size = stack_size;
155 attr.priority = (osPriority_t)priority;
156 attr.tz_module = 0;
157 attr.reserved = 0;
158
159 // Allocate stack if NULL was passed
160 if ((uint32_t*)stack == NULL)
161 {
162 // Note: 1 malloc so that it can be freed with 1 call when terminating
163 uint32_t cb_mem_pad = (~osRtxThreadCbSize + 1) & CY_RTOS_ALIGNMENT_MASK;
164 attr.cb_mem = malloc(osRtxThreadCbSize + cb_mem_pad + stack_size);
165 if (attr.cb_mem != NULL)
166 {
167 attr.stack_mem =
168 (uint32_t*)((uint32_t)attr.cb_mem + osRtxThreadCbSize + cb_mem_pad);
169 }
170 }
171 else
172 {
173 attr.cb_mem = malloc(osRtxThreadCbSize);
174 attr.stack_mem = stack;
175 }
176
177 if (attr.cb_mem == NULL)
178 {
179 status = CY_RTOS_NO_MEMORY;
180 }
181 else
182 {
183 CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
184 CY_ASSERT(((uint32_t)attr.stack_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
185 *thread = osThreadNew((osThreadFunc_t)entry_function, arg, &attr);
186 CY_ASSERT((*thread == attr.cb_mem) || (*thread == NULL));
187 status = (*thread == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
188 }
189 }
190
191 return status;
192 }
193
194
195 //--------------------------------------------------------------------------------------------------
196 // cy_rtos_thread_exit
197 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_exit(void)198 cy_rslt_t cy_rtos_thread_exit(void)
199 {
200 // This does not have a return statement because the osThreadExit() function * does not return
201 // so the return statement would be unreachable and causes a * warning for IAR compiler.
202 osThreadExit();
203 }
204
205
206 //--------------------------------------------------------------------------------------------------
207 // cy_rtos_thread_terminate
208 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_terminate(cy_thread_t * thread)209 cy_rslt_t cy_rtos_thread_terminate(cy_thread_t* thread)
210 {
211 cy_rslt_t status;
212 cy_rtos_error_t statusInternal;
213
214 if (thread == NULL)
215 {
216 status = CY_RTOS_BAD_PARAM;
217 }
218 else
219 {
220 statusInternal = osThreadTerminate(*thread);
221 status = error_converter(statusInternal);
222 }
223
224 return status;
225 }
226
227
228 //--------------------------------------------------------------------------------------------------
229 // cy_rtos_thread_is_running
230 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_is_running(cy_thread_t * thread,bool * running)231 cy_rslt_t cy_rtos_thread_is_running(cy_thread_t* thread, bool* running)
232 {
233 cy_rslt_t status = CY_RSLT_SUCCESS;
234
235 if ((thread == NULL) || (running == NULL))
236 {
237 status = CY_RTOS_BAD_PARAM;
238 }
239 else
240 {
241 *running = (osThreadGetState(*thread) == osThreadRunning) ? true : false;
242 }
243
244 return status;
245 }
246
247
248 //--------------------------------------------------------------------------------------------------
249 // cy_rtos_thread_get_state
250 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_get_state(cy_thread_t * thread,cy_thread_state_t * state)251 cy_rslt_t cy_rtos_thread_get_state(cy_thread_t* thread, cy_thread_state_t* state)
252 {
253 cy_rslt_t status = CY_RSLT_SUCCESS;
254
255 if ((thread == NULL) || (state == NULL))
256 {
257 status = CY_RTOS_BAD_PARAM;
258 }
259 else
260 {
261 switch (osThreadGetState(*thread))
262 {
263 case osThreadInactive:
264 *state = CY_THREAD_STATE_INACTIVE;
265 break;
266
267 case osThreadReady:
268 *state = CY_THREAD_STATE_READY;
269 break;
270
271 case osThreadRunning:
272 *state = CY_THREAD_STATE_RUNNING;
273 break;
274
275 case osThreadBlocked:
276 *state = CY_THREAD_STATE_BLOCKED;
277 break;
278
279 case osThreadTerminated:
280 *state = CY_THREAD_STATE_TERMINATED;
281 break;
282
283 case osThreadError:
284 case osThreadReserved:
285 default:
286 *state = CY_THREAD_STATE_UNKNOWN;
287 break;
288 }
289 }
290
291 return status;
292 }
293
294
295 //--------------------------------------------------------------------------------------------------
296 // cy_rtos_thread_join
297 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_join(cy_thread_t * thread)298 cy_rslt_t cy_rtos_thread_join(cy_thread_t* thread)
299 {
300 cy_rslt_t status;
301 cy_rtos_error_t statusInternal;
302
303 if (thread == NULL)
304 {
305 status = CY_RTOS_BAD_PARAM;
306 }
307 else
308 {
309 statusInternal = osThreadJoin(*thread);
310 status = error_converter(statusInternal);
311
312 if (status == CY_RSLT_SUCCESS)
313 {
314 free(*thread);
315 *thread = NULL;
316 }
317 }
318
319 return status;
320 }
321
322
323 //--------------------------------------------------------------------------------------------------
324 // cy_rtos_thread_get_handle
325 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_get_handle(cy_thread_t * thread)326 cy_rslt_t cy_rtos_thread_get_handle(cy_thread_t* thread)
327 {
328 cy_rslt_t status = CY_RSLT_SUCCESS;
329
330 if (thread == NULL)
331 {
332 status = CY_RTOS_BAD_PARAM;
333 }
334 else
335 {
336 *thread = osThreadGetId();
337 }
338
339 return status;
340 }
341
342
343 //--------------------------------------------------------------------------------------------------
344 // cy_rtos_thread_wait_notification
345 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_wait_notification(cy_time_t timeout_ms)346 cy_rslt_t cy_rtos_thread_wait_notification(cy_time_t timeout_ms)
347 {
348 uint32_t ret;
349 cy_rslt_t status = CY_RSLT_SUCCESS;
350 ret = osThreadFlagsWait(CY_RTOS_THREAD_FLAG, osFlagsWaitAll, convert_ms_to_ticks(timeout_ms));
351 if (ret & osFlagsError)
352 {
353 status = (ret == osFlagsErrorTimeout) ? CY_RTOS_TIMEOUT : CY_RTOS_GENERAL_ERROR;
354 // Update the last known error status
355 dbgErr = (cy_rtos_error_t)ret;
356 }
357 return status;
358 }
359
360
361 //--------------------------------------------------------------------------------------------------
362 // cy_rtos_thread_set_notification
363 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_set_notification(cy_thread_t * thread)364 cy_rslt_t cy_rtos_thread_set_notification(cy_thread_t* thread)
365 {
366 cy_rslt_t status = CY_RSLT_SUCCESS;
367 uint32_t ret;
368
369 if (thread == NULL)
370 {
371 status = CY_RTOS_BAD_PARAM;
372 }
373 else
374 {
375 /* According to the description of CMSIS-RTOS v2
376 * osThreadFlagsSet() can be called inside ISR
377 */
378 ret = osThreadFlagsSet(*thread, CY_RTOS_THREAD_FLAG);
379 if (ret & osFlagsError)
380 {
381 status = CY_RTOS_GENERAL_ERROR;
382 // Update the last known error status
383 dbgErr = (cy_rtos_error_t)ret;
384 }
385 }
386 return status;
387 }
388
389
390 //--------------------------------------------------------------------------------------------------
391 // cy_rtos_thread_get_name
392 //--------------------------------------------------------------------------------------------------
cy_rtos_thread_get_name(cy_thread_t * thread,const char ** thread_name)393 cy_rslt_t cy_rtos_thread_get_name(cy_thread_t* thread, const char** thread_name)
394 {
395 *thread_name = osThreadGetName(*thread);
396 return CY_RSLT_SUCCESS;
397 }
398
399
400 /******************************************************
401 * Scheduler
402 ******************************************************/
403 static uint16_t _cy_rtos_suspend_count = 0;
404
405 //--------------------------------------------------------------------------------------------------
406 // cy_rtos_scheduler_suspend
407 //--------------------------------------------------------------------------------------------------
cy_rtos_scheduler_suspend(void)408 cy_rslt_t cy_rtos_scheduler_suspend(void)
409 {
410 ++_cy_rtos_suspend_count;
411 osKernelLock();
412
413 return CY_RSLT_SUCCESS;
414 }
415
416
417 //--------------------------------------------------------------------------------------------------
418 // cy_rtos_scheduler_resume
419 //--------------------------------------------------------------------------------------------------
cy_rtos_scheduler_resume(void)420 cy_rslt_t cy_rtos_scheduler_resume(void)
421 {
422 cy_rslt_t status;
423 if (_cy_rtos_suspend_count > 0)
424 {
425 --_cy_rtos_suspend_count;
426 osKernelUnlock();
427 status = CY_RSLT_SUCCESS;
428 }
429 else
430 {
431 status = CY_RTOS_BAD_PARAM;
432 }
433
434 return status;
435 }
436
437
438 /******************************************************
439 * Mutexes
440 ******************************************************/
441
cy_rtos_mutex_init(cy_mutex_t * mutex,bool recursive)442 cy_rslt_t cy_rtos_mutex_init(cy_mutex_t* mutex, bool recursive)
443 {
444 cy_rslt_t status;
445 osMutexAttr_t attr;
446
447 if (mutex == NULL)
448 {
449 status = CY_RTOS_BAD_PARAM;
450 }
451 else
452 {
453 attr.name = NULL;
454 attr.attr_bits = osMutexPrioInherit;
455 if (recursive)
456 {
457 attr.attr_bits |= osMutexRecursive;
458 }
459 attr.cb_mem = malloc(osRtxMutexCbSize);
460 attr.cb_size = osRtxMutexCbSize;
461
462 if (attr.cb_mem == NULL)
463 {
464 status = CY_RTOS_NO_MEMORY;
465 }
466 else
467 {
468 CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
469 *mutex = osMutexNew(&attr);
470 CY_ASSERT((*mutex == attr.cb_mem) || (*mutex == NULL));
471 status = (*mutex == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
472 }
473 }
474
475 return status;
476 }
477
478
479 //--------------------------------------------------------------------------------------------------
480 // cy_rtos_mutex_get
481 //--------------------------------------------------------------------------------------------------
cy_rtos_mutex_get(cy_mutex_t * mutex,cy_time_t timeout_ms)482 cy_rslt_t cy_rtos_mutex_get(cy_mutex_t* mutex, cy_time_t timeout_ms)
483 {
484 cy_rslt_t status;
485 cy_rtos_error_t statusInternal;
486
487 if (mutex == NULL)
488 {
489 status = CY_RTOS_BAD_PARAM;
490 }
491 else
492 {
493 statusInternal = osMutexAcquire(*mutex, timeout_ms);
494 status = error_converter(statusInternal);
495 }
496
497 return status;
498 }
499
500
501 //--------------------------------------------------------------------------------------------------
502 // cy_rtos_mutex_set
503 //--------------------------------------------------------------------------------------------------
cy_rtos_mutex_set(cy_mutex_t * mutex)504 cy_rslt_t cy_rtos_mutex_set(cy_mutex_t* mutex)
505 {
506 cy_rslt_t status;
507 cy_rtos_error_t statusInternal;
508
509 if (mutex == NULL)
510 {
511 status = CY_RTOS_BAD_PARAM;
512 }
513 else
514 {
515 statusInternal = osMutexRelease(*mutex);
516 status = error_converter(statusInternal);
517 }
518
519 return status;
520 }
521
522
523 //--------------------------------------------------------------------------------------------------
524 // cy_rtos_mutex_deinit
525 //--------------------------------------------------------------------------------------------------
cy_rtos_mutex_deinit(cy_mutex_t * mutex)526 cy_rslt_t cy_rtos_mutex_deinit(cy_mutex_t* mutex)
527 {
528 cy_rslt_t status;
529 cy_rtos_error_t statusInternal;
530
531 if (mutex == NULL)
532 {
533 status = CY_RTOS_BAD_PARAM;
534 }
535 else
536 {
537 statusInternal = osMutexDelete(*mutex);
538 status = error_converter(statusInternal);
539
540 if (status == CY_RSLT_SUCCESS)
541 {
542 free(*mutex);
543 *mutex = NULL;
544 }
545 }
546
547 return status;
548 }
549
550
551 /******************************************************
552 * Semaphores
553 ******************************************************/
554
cy_rtos_semaphore_init(cy_semaphore_t * semaphore,uint32_t maxcount,uint32_t initcount)555 cy_rslt_t cy_rtos_semaphore_init(cy_semaphore_t* semaphore, uint32_t maxcount, uint32_t initcount)
556 {
557 cy_rslt_t status;
558 osSemaphoreAttr_t attr;
559
560 if (semaphore == NULL)
561 {
562 status = CY_RTOS_BAD_PARAM;
563 }
564 else
565 {
566 attr.name = NULL;
567 attr.attr_bits = 0U;
568 attr.cb_mem = malloc(osRtxSemaphoreCbSize);
569 attr.cb_size = osRtxSemaphoreCbSize;
570
571 if (attr.cb_mem == NULL)
572 {
573 status = CY_RTOS_NO_MEMORY;
574 }
575 else
576 {
577 CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
578 *semaphore = osSemaphoreNew(maxcount, initcount, &attr);
579 CY_ASSERT((*semaphore == attr.cb_mem) || (*semaphore == NULL));
580 status = (*semaphore == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
581 }
582 }
583
584 return status;
585 }
586
587
588 //--------------------------------------------------------------------------------------------------
589 // cy_rtos_semaphore_get
590 //--------------------------------------------------------------------------------------------------
cy_rtos_semaphore_get(cy_semaphore_t * semaphore,cy_time_t timeout_ms)591 cy_rslt_t cy_rtos_semaphore_get(cy_semaphore_t* semaphore, cy_time_t timeout_ms)
592 {
593 cy_rslt_t status = CY_RSLT_SUCCESS;
594 cy_rtos_error_t statusInternal;
595 bool in_isr = is_in_isr();
596 // Based on documentation when osSemaphoreAcquire is called from ISR timeout must be zero.
597 // https://www.keil.com/pack/doc/CMSIS/RTOS2/html/group__CMSIS__RTOS__SemaphoreMgmt.html#ga7e94c8b242a0c81f2cc79ec22895c87b
598 if ((semaphore == NULL) || (in_isr && (timeout_ms != 0)))
599 {
600 status = CY_RTOS_BAD_PARAM;
601 }
602 else
603 {
604 statusInternal = osSemaphoreAcquire(*semaphore, timeout_ms);
605 status = error_converter(statusInternal);
606 }
607
608 return status;
609 }
610
611
612 //--------------------------------------------------------------------------------------------------
613 // cy_rtos_semaphore_set
614 //--------------------------------------------------------------------------------------------------
cy_rtos_semaphore_set(cy_semaphore_t * semaphore)615 cy_rslt_t cy_rtos_semaphore_set(cy_semaphore_t* semaphore)
616 {
617 cy_rslt_t status = CY_RSLT_SUCCESS;
618 cy_rtos_error_t statusInternal;
619
620 if (semaphore == NULL)
621 {
622 status = CY_RTOS_BAD_PARAM;
623 }
624 else
625 {
626 statusInternal = osSemaphoreRelease(*semaphore);
627 status = error_converter(statusInternal);
628 }
629
630 return status;
631 }
632
633
634 //--------------------------------------------------------------------------------------------------
635 // cy_rtos_semaphore_get_count
636 //--------------------------------------------------------------------------------------------------
cy_rtos_semaphore_get_count(cy_semaphore_t * semaphore,size_t * count)637 cy_rslt_t cy_rtos_semaphore_get_count(cy_semaphore_t* semaphore, size_t* count)
638 {
639 cy_rslt_t status;
640 if ((semaphore == NULL) || (count == NULL))
641 {
642 status = CY_RTOS_BAD_PARAM;
643 }
644 else
645 {
646 *count = osSemaphoreGetCount(*semaphore);
647 status = CY_RSLT_SUCCESS;
648 }
649 return status;
650 }
651
652
653 //--------------------------------------------------------------------------------------------------
654 // cy_rtos_semaphore_deinit
655 //--------------------------------------------------------------------------------------------------
cy_rtos_deinit_semaphore(cy_semaphore_t * semaphore)656 cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t* semaphore)
657 {
658 cy_rslt_t status;
659 cy_rtos_error_t statusInternal;
660
661 if (semaphore == NULL)
662 {
663 status = CY_RTOS_BAD_PARAM;
664 }
665 else
666 {
667 statusInternal = osSemaphoreDelete(*semaphore);
668 status = error_converter(statusInternal);
669 if (status == CY_RSLT_SUCCESS)
670 {
671 free(*semaphore);
672 *semaphore = NULL;
673 }
674 }
675
676 return status;
677 }
678
679
680 /******************************************************
681 * Events
682 ******************************************************/
683
684 #define CY_RTOS_EVENT_ERRORFLAG 0x80000000UL
685 #define CY_RTOS_EVENT_FLAGS 0x7FFFFFFFUL
686
687 //--------------------------------------------------------------------------------------------------
688 // cy_rtos_event_init
689 //--------------------------------------------------------------------------------------------------
cy_rtos_event_init(cy_event_t * event)690 cy_rslt_t cy_rtos_event_init(cy_event_t* event)
691 {
692 cy_rslt_t status;
693 osEventFlagsAttr_t attr;
694
695 if (event == NULL)
696 {
697 status = CY_RTOS_BAD_PARAM;
698 }
699 else
700 {
701 attr.name = NULL;
702 attr.attr_bits = 0U;
703 attr.cb_mem = malloc(osRtxEventFlagsCbSize);
704 attr.cb_size = osRtxEventFlagsCbSize;
705
706 if (attr.cb_mem == NULL)
707 {
708 status = CY_RTOS_NO_MEMORY;
709 }
710 else
711 {
712 CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
713 *event = osEventFlagsNew(&attr);
714 CY_ASSERT((*event == attr.cb_mem) || (*event == NULL));
715 status = (*event == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
716 }
717 }
718
719 return status;
720 }
721
722
723 //--------------------------------------------------------------------------------------------------
724 // cy_rtos_event_setbits
725 //--------------------------------------------------------------------------------------------------
cy_rtos_event_setbits(cy_event_t * event,uint32_t bits)726 cy_rslt_t cy_rtos_event_setbits(cy_event_t* event, uint32_t bits)
727 {
728 cy_rslt_t status = CY_RSLT_SUCCESS;
729 cy_rtos_error_t statusInternal;
730
731 if (event == NULL)
732 {
733 status = CY_RTOS_BAD_PARAM;
734 }
735 else
736 {
737 statusInternal = (osStatus_t)osEventFlagsSet(*event, bits);
738 if ((statusInternal & CY_RTOS_EVENT_ERRORFLAG) != 0UL)
739 {
740 status = error_converter(statusInternal);
741 }
742 }
743
744 return status;
745 }
746
747
748 //--------------------------------------------------------------------------------------------------
749 // cy_rtos_event_clearbits
750 //--------------------------------------------------------------------------------------------------
cy_rtos_event_clearbits(cy_event_t * event,uint32_t bits)751 cy_rslt_t cy_rtos_event_clearbits(cy_event_t* event, uint32_t bits)
752 {
753 cy_rslt_t status = CY_RSLT_SUCCESS;
754 cy_rtos_error_t statusInternal;
755
756 if (event == NULL)
757 {
758 status = CY_RTOS_BAD_PARAM;
759 }
760 else
761 {
762 statusInternal = (osStatus_t)osEventFlagsClear(*event, bits);
763 if ((statusInternal & CY_RTOS_EVENT_ERRORFLAG) != 0UL)
764 {
765 status = error_converter(statusInternal);
766 }
767 }
768
769 return status;
770 }
771
772
773 //--------------------------------------------------------------------------------------------------
774 // cy_rtos_event_getbits
775 //--------------------------------------------------------------------------------------------------
cy_rtos_event_getbits(cy_event_t * event,uint32_t * bits)776 cy_rslt_t cy_rtos_event_getbits(cy_event_t* event, uint32_t* bits)
777 {
778 cy_rslt_t status = CY_RSLT_SUCCESS;
779
780 if ((event == NULL) || (bits == NULL))
781 {
782 status = CY_RTOS_BAD_PARAM;
783 }
784 else
785 {
786 *bits = osEventFlagsGet(*event);
787 }
788
789 return status;
790 }
791
792
793 //--------------------------------------------------------------------------------------------------
794 // cy_rtos_event_waitbits
795 //--------------------------------------------------------------------------------------------------
cy_rtos_event_waitbits(cy_event_t * event,uint32_t * bits,bool clear,bool all,cy_time_t timeout_ms)796 cy_rslt_t cy_rtos_event_waitbits(cy_event_t* event, uint32_t* bits, bool clear, bool all,
797 cy_time_t timeout_ms)
798 {
799 cy_rslt_t status = CY_RSLT_SUCCESS;
800 cy_rtos_error_t statusInternal;
801 uint32_t flagOption;
802
803 if ((event == NULL) || (bits == NULL))
804 {
805 status = CY_RTOS_BAD_PARAM;
806 }
807 else
808 {
809 flagOption = (all) ? osFlagsWaitAll : osFlagsWaitAny;
810 if (!clear)
811 {
812 flagOption |= osFlagsNoClear;
813 }
814
815 statusInternal = (osStatus_t)osEventFlagsWait(*event, *bits, flagOption, timeout_ms);
816 if ((statusInternal & CY_RTOS_EVENT_ERRORFLAG) == 0UL)
817 {
818 *bits = statusInternal;
819 }
820 else
821 {
822 status = error_converter(statusInternal);
823 }
824 }
825
826 return status;
827 }
828
829
830 //--------------------------------------------------------------------------------------------------
831 // cy_rtos_event_deinit
832 //--------------------------------------------------------------------------------------------------
cy_rtos_event_deinit(cy_event_t * event)833 cy_rslt_t cy_rtos_event_deinit(cy_event_t* event)
834 {
835 cy_rslt_t status;
836 cy_rtos_error_t statusInternal;
837
838 if (event == NULL)
839 {
840 status = CY_RTOS_BAD_PARAM;
841 }
842 else
843 {
844 statusInternal = osEventFlagsDelete(*event);
845 status = error_converter(statusInternal);
846 if (status == CY_RSLT_SUCCESS)
847 {
848 free(*event);
849 *event = NULL;
850 }
851 }
852
853 return status;
854 }
855
856
857 /******************************************************
858 * Queues
859 ******************************************************/
860
cy_rtos_queue_init(cy_queue_t * queue,size_t length,size_t itemsize)861 cy_rslt_t cy_rtos_queue_init(cy_queue_t* queue, size_t length, size_t itemsize)
862 {
863 cy_rslt_t status;
864 osMessageQueueAttr_t attr;
865
866 if (queue == NULL)
867 {
868 status = CY_RTOS_BAD_PARAM;
869 }
870 else
871 {
872 attr.name = NULL;
873 attr.attr_bits = 0U;
874 attr.cb_size = osRtxMessageQueueCbSize;
875 uint32_t blockSize = ((itemsize + 3U) & ~3UL) + sizeof(osRtxMessage_t);
876 attr.mq_size = blockSize * length;
877
878 // Note: 1 malloc for both so that they can be freed with 1 call
879 uint32_t cb_mem_pad = (8 - (osRtxMessageQueueCbSize & 0x07)) & 0x07;
880 attr.cb_mem = malloc(osRtxMessageQueueCbSize + cb_mem_pad + attr.mq_size);
881 if (attr.cb_mem != NULL)
882 {
883 attr.mq_mem = (uint32_t*)((uint32_t)attr.cb_mem + osRtxMessageQueueCbSize + cb_mem_pad);
884 }
885
886 if (attr.cb_mem == NULL)
887 {
888 status = CY_RTOS_NO_MEMORY;
889 }
890 else
891 {
892 CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
893 CY_ASSERT(((uint32_t)attr.mq_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
894 *queue = osMessageQueueNew(length, itemsize, &attr);
895 CY_ASSERT((*queue == attr.cb_mem) || (*queue == NULL));
896 status = (*queue == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
897 }
898 }
899
900 return status;
901 }
902
903
904 //--------------------------------------------------------------------------------------------------
905 // cy_rtos_queue_put
906 //--------------------------------------------------------------------------------------------------
cy_rtos_queue_put(cy_queue_t * queue,const void * item_ptr,cy_time_t timeout_ms)907 cy_rslt_t cy_rtos_queue_put(cy_queue_t* queue, const void* item_ptr, cy_time_t timeout_ms)
908 {
909 cy_rslt_t status;
910 cy_rtos_error_t statusInternal;
911 bool in_isr = is_in_isr();
912
913 if ((queue == NULL) || (item_ptr == NULL))
914 {
915 status = CY_RTOS_BAD_PARAM;
916 }
917 else
918 {
919 // Not allowed to be called in ISR if timeout != 0
920 if ((!in_isr) || (in_isr && (timeout_ms == 0U)))
921 {
922 statusInternal = osMessageQueuePut(*queue, (uint8_t*)item_ptr, 0u, timeout_ms);
923 }
924 else
925 {
926 statusInternal = osErrorISR;
927 }
928
929 status = error_converter(statusInternal);
930 }
931
932 return status;
933 }
934
935
936 //--------------------------------------------------------------------------------------------------
937 // cy_rtos_queue_get
938 //--------------------------------------------------------------------------------------------------
cy_rtos_queue_get(cy_queue_t * queue,void * item_ptr,cy_time_t timeout_ms)939 cy_rslt_t cy_rtos_queue_get(cy_queue_t* queue, void* item_ptr, cy_time_t timeout_ms)
940 {
941 cy_rslt_t status;
942 cy_rtos_error_t statusInternal;
943 bool in_isr = is_in_isr();
944
945 if ((queue == NULL) || (item_ptr == NULL))
946 {
947 status = CY_RTOS_BAD_PARAM;
948 }
949 else
950 {
951 // Not allowed to be called in ISR if timeout != 0
952 if ((!in_isr) || (in_isr && (timeout_ms == 0U)))
953 {
954 statusInternal = osMessageQueueGet(*queue, (uint8_t*)item_ptr, NULL, timeout_ms);
955 }
956 else
957 {
958 statusInternal = osErrorISR;
959 }
960
961 status = error_converter(statusInternal);
962 }
963
964 return status;
965 }
966
967
968 //--------------------------------------------------------------------------------------------------
969 // cy_rtos_queue_count
970 //--------------------------------------------------------------------------------------------------
cy_rtos_queue_count(cy_queue_t * queue,size_t * num_waiting)971 cy_rslt_t cy_rtos_queue_count(cy_queue_t* queue, size_t* num_waiting)
972 {
973 cy_rslt_t status = CY_RSLT_SUCCESS;
974
975 if ((queue == NULL) || (num_waiting == NULL))
976 {
977 status = CY_RTOS_BAD_PARAM;
978 }
979 else
980 {
981 *num_waiting = osMessageQueueGetCount(*queue);
982 }
983
984 return status;
985 }
986
987
988 //--------------------------------------------------------------------------------------------------
989 // cy_rtos_queue_space
990 //--------------------------------------------------------------------------------------------------
cy_rtos_queue_space(cy_queue_t * queue,size_t * num_spaces)991 cy_rslt_t cy_rtos_queue_space(cy_queue_t* queue, size_t* num_spaces)
992 {
993 cy_rslt_t status = CY_RSLT_SUCCESS;
994
995 if ((queue == NULL) || (num_spaces == NULL))
996 {
997 status = CY_RTOS_BAD_PARAM;
998 }
999 else
1000 {
1001 *num_spaces = osMessageQueueGetSpace(*queue);
1002 }
1003
1004 return status;
1005 }
1006
1007
1008 //--------------------------------------------------------------------------------------------------
1009 // cy_rtos_queue_reset
1010 //--------------------------------------------------------------------------------------------------
cy_rtos_queue_reset(cy_queue_t * queue)1011 cy_rslt_t cy_rtos_queue_reset(cy_queue_t* queue)
1012 {
1013 cy_rslt_t status;
1014 cy_rtos_error_t statusInternal;
1015
1016 if (queue == NULL)
1017 {
1018 status = CY_RTOS_BAD_PARAM;
1019 }
1020 else
1021 {
1022 statusInternal = osMessageQueueReset(*queue);
1023 status = error_converter(statusInternal);
1024 }
1025
1026 return status;
1027 }
1028
1029
1030 //--------------------------------------------------------------------------------------------------
1031 // cy_rtos_queue_deinit
1032 //--------------------------------------------------------------------------------------------------
cy_rtos_queue_deinit(cy_queue_t * queue)1033 cy_rslt_t cy_rtos_queue_deinit(cy_queue_t* queue)
1034 {
1035 cy_rslt_t status;
1036 cy_rtos_error_t statusInternal;
1037
1038 if (queue == NULL)
1039 {
1040 status = CY_RTOS_BAD_PARAM;
1041 }
1042 else
1043 {
1044 statusInternal = osMessageQueueDelete(*queue);
1045 status = error_converter(statusInternal);
1046
1047 if (status == CY_RSLT_SUCCESS)
1048 {
1049 free(*queue);
1050 *queue = NULL;
1051 }
1052 }
1053
1054 return status;
1055 }
1056
1057
1058 /******************************************************
1059 * Timers
1060 ******************************************************/
1061
cy_rtos_timer_init(cy_timer_t * timer,cy_timer_trigger_type_t type,cy_timer_callback_t fun,cy_timer_callback_arg_t arg)1062 cy_rslt_t cy_rtos_timer_init(cy_timer_t* timer, cy_timer_trigger_type_t type,
1063 cy_timer_callback_t fun, cy_timer_callback_arg_t arg)
1064 {
1065 cy_rslt_t status;
1066 osTimerAttr_t attr;
1067
1068 if (timer == NULL)
1069 {
1070 status = CY_RTOS_BAD_PARAM;
1071 }
1072 else
1073 {
1074 attr.name = NULL;
1075 attr.attr_bits = 0U;
1076 attr.cb_mem = malloc(osRtxTimerCbSize);
1077 attr.cb_size = osRtxTimerCbSize;
1078
1079 if (attr.cb_mem == NULL)
1080 {
1081 status = CY_RTOS_NO_MEMORY;
1082 }
1083 else
1084 {
1085 osTimerType_t osTriggerType = (CY_TIMER_TYPE_PERIODIC == type)
1086 ? osTimerPeriodic
1087 : osTimerOnce;
1088
1089 CY_ASSERT(((uint32_t)attr.cb_mem & CY_RTOS_ALIGNMENT_MASK) == 0UL);
1090 *timer = osTimerNew((osTimerFunc_t)fun, osTriggerType, (void*)arg, &attr);
1091 CY_ASSERT((*timer == attr.cb_mem) || (*timer == NULL));
1092 status = (*timer == NULL) ? CY_RTOS_GENERAL_ERROR : CY_RSLT_SUCCESS;
1093 }
1094 }
1095
1096 return status;
1097 }
1098
1099
1100 //--------------------------------------------------------------------------------------------------
1101 // cy_rtos_timer_start
1102 //--------------------------------------------------------------------------------------------------
cy_rtos_timer_start(cy_timer_t * timer,cy_time_t num_ms)1103 cy_rslt_t cy_rtos_timer_start(cy_timer_t* timer, cy_time_t num_ms)
1104 {
1105 cy_rslt_t status;
1106 cy_rtos_error_t statusInternal;
1107
1108 if (timer == NULL)
1109 {
1110 status = CY_RTOS_BAD_PARAM;
1111 }
1112 else
1113 {
1114 statusInternal = osTimerStart(*timer, convert_ms_to_ticks(num_ms));
1115 status = error_converter(statusInternal);
1116 }
1117
1118 return status;
1119 }
1120
1121
1122 //--------------------------------------------------------------------------------------------------
1123 // cy_rtos_timer_stop
1124 //--------------------------------------------------------------------------------------------------
cy_rtos_timer_stop(cy_timer_t * timer)1125 cy_rslt_t cy_rtos_timer_stop(cy_timer_t* timer)
1126 {
1127 cy_rslt_t status;
1128 cy_rtos_error_t statusInternal;
1129
1130 if (timer == NULL)
1131 {
1132 status = CY_RTOS_BAD_PARAM;
1133 }
1134 else
1135 {
1136 statusInternal = osTimerStop(*timer);
1137 status = error_converter(statusInternal);
1138 }
1139
1140 return status;
1141 }
1142
1143
1144 //--------------------------------------------------------------------------------------------------
1145 // cy_rtos_timer_is_running
1146 //--------------------------------------------------------------------------------------------------
cy_rtos_timer_is_running(cy_timer_t * timer,bool * state)1147 cy_rslt_t cy_rtos_timer_is_running(cy_timer_t* timer, bool* state)
1148 {
1149 cy_rslt_t status = CY_RSLT_SUCCESS;
1150
1151 if ((timer == NULL) || (state == NULL))
1152 {
1153 status = CY_RTOS_BAD_PARAM;
1154 }
1155 else
1156 {
1157 *state = osTimerIsRunning(*timer);
1158 }
1159
1160 return status;
1161 }
1162
1163
1164 //--------------------------------------------------------------------------------------------------
1165 // cy_rtos_timer_deinit
1166 //--------------------------------------------------------------------------------------------------
cy_rtos_timer_deinit(cy_timer_t * timer)1167 cy_rslt_t cy_rtos_timer_deinit(cy_timer_t* timer)
1168 {
1169 cy_rslt_t status;
1170 cy_rtos_error_t statusInternal;
1171
1172 if (timer == NULL)
1173 {
1174 status = CY_RTOS_BAD_PARAM;
1175 }
1176 else
1177 {
1178 statusInternal = osTimerDelete(*timer);
1179 status = error_converter(statusInternal);
1180
1181 if (status == CY_RSLT_SUCCESS)
1182 {
1183 free(*timer);
1184 *timer = NULL;
1185 }
1186 }
1187
1188 return status;
1189 }
1190
1191
1192 /******************************************************
1193 * Time
1194 ******************************************************/
1195
cy_rtos_time_get(cy_time_t * tval)1196 cy_rslt_t cy_rtos_time_get(cy_time_t* tval)
1197 {
1198 cy_rslt_t status = CY_RSLT_SUCCESS;
1199 uint32_t tick_freq;
1200
1201 if (tval == NULL)
1202 {
1203 status = CY_RTOS_BAD_PARAM;
1204 }
1205 else
1206 {
1207 // Get Number of ticks per second
1208 tick_freq = osKernelGetTickFreq();
1209
1210 // Convert ticks count to time in milliseconds
1211 if (tick_freq != 0)
1212 {
1213 *tval = (cy_time_t)((osKernelGetTickCount() * 1000LL) / tick_freq);
1214 }
1215 else
1216 {
1217 status = CY_RTOS_GENERAL_ERROR;
1218 }
1219 }
1220
1221 return status;
1222 }
1223
1224
1225 //--------------------------------------------------------------------------------------------------
1226 // cy_rtos_delay_milliseconds
1227 //--------------------------------------------------------------------------------------------------
cy_rtos_delay_milliseconds(cy_time_t num_ms)1228 cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms)
1229 {
1230 cy_rslt_t status;
1231 cy_rtos_error_t statusInternal;
1232
1233 statusInternal = osDelay(num_ms);
1234 status = error_converter(statusInternal);
1235
1236 return status;
1237 }
1238
1239
1240 #if defined(__cplusplus)
1241 }
1242 #endif
1243