183 lines
3.7 KiB
C
183 lines
3.7 KiB
C
/*
|
|
* Copyright (c) 2018 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <kernel_structs.h>
|
|
#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;
|
|
}
|