/* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include #include "wrapper.h" #define DONT_CARE (0) #define NSEC_PER_MSEC (NSEC_PER_USEC * USEC_PER_MSEC) /** * @brief Set the specified Thread Flags of a thread. */ uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags) { int key; struct cv2_thread *tid = (struct cv2_thread *)thread_id; if ((thread_id == NULL) || (is_cmsis_rtos_v2_thread(thread_id) == NULL) || (flags & 0x80000000)) { return osFlagsErrorParameter; } key = irq_lock(); tid->signal_results |= flags; irq_unlock(key); k_poll_signal_raise(&tid->poll_signal, DONT_CARE); return tid->signal_results; } /** * @brief Get the current Thread Flags of current running thread. */ uint32_t osThreadFlagsGet(void) { struct cv2_thread *tid; if (k_is_in_isr()) { return 0; } tid = (struct cv2_thread *)osThreadGetId(); if (tid == NULL) { return 0; } else { return tid->signal_results; } } /** * @brief Clear the specified Thread Flags of current running thread. */ uint32_t osThreadFlagsClear(uint32_t flags) { struct cv2_thread *tid; int sig, key; if (k_is_in_isr()) { return osFlagsErrorUnknown; } if (flags & 0x80000000) { return osFlagsErrorParameter; } tid = (struct cv2_thread *)osThreadGetId(); if (tid == NULL) { return osFlagsErrorUnknown; } key = irq_lock(); sig = tid->signal_results; tid->signal_results &= ~(flags); irq_unlock(key); return sig; } /** * @brief Wait for one or more Thread Flags of the current running thread to * become signalled. */ uint32_t osThreadFlagsWait(uint32_t flags, uint32_t options, uint32_t timeout) { struct cv2_thread *tid; int retval, key; u32_t sig; u32_t time_delta_ms, timeout_ms = __ticks_to_ms(timeout); u64_t time_stamp_start, hwclk_cycles_delta, time_delta_ns; if (k_is_in_isr()) { return osFlagsErrorUnknown; } if (flags & 0x80000000) { return osFlagsErrorParameter; } tid = (struct cv2_thread *)osThreadGetId(); if (tid == NULL) { return osFlagsErrorUnknown; } for (;;) { time_stamp_start = (u64_t)k_cycle_get_32(); switch (timeout) { case 0: retval = k_poll(&tid->poll_event, 1, K_NO_WAIT); break; case osWaitForever: retval = k_poll(&tid->poll_event, 1, K_FOREVER); break; default: retval = k_poll(&tid->poll_event, 1, timeout_ms); break; } switch (retval) { case 0: break; case -EAGAIN: return osFlagsErrorTimeout; default: return osFlagsErrorUnknown; } __ASSERT(tid->poll_event.state == K_POLL_STATE_SIGNALED, "event state not signalled!"); __ASSERT(tid->poll_event.signal->signaled == 1, "event signaled is not 1"); /* Reset the states to facilitate the next trigger */ tid->poll_event.signal->signaled = 0; tid->poll_event.state = K_POLL_STATE_NOT_READY; if (options & osFlagsWaitAll) { /* Check if all events we are waiting on have * been signalled */ if ((tid->signal_results & flags) == flags) { break; } /* If we need to wait on more signals, we need to * adjust the timeout value accordingly based on * the time that has already elapsed. */ hwclk_cycles_delta = (u64_t)k_cycle_get_32() - time_stamp_start; time_delta_ns = (u32_t)SYS_CLOCK_HW_CYCLES_TO_NS(hwclk_cycles_delta); time_delta_ms = (u32_t)time_delta_ns / NSEC_PER_MSEC; if (timeout_ms > time_delta_ms) { timeout_ms -= time_delta_ms; } else { timeout_ms = 0; } } else { break; } } sig = tid->signal_results; if (!(options & osFlagsNoClear)) { /* Clear signal flags as the thread is ready now */ key = irq_lock(); tid->signal_results &= ~(flags); irq_unlock(key); } return sig; }