diff --git a/osal/cmsis_os/cmsis_os2.c b/osal/cmsis_os/cmsis_os2.c new file mode 100644 index 00000000..37aa6699 --- /dev/null +++ b/osal/cmsis_os/cmsis_os2.c @@ -0,0 +1,883 @@ +#include "cmsis_os2.h" +#include + +static k_prio_t priority_cmsis2knl(osPriority_t prio) { + if (prio == osPriorityError || prio == osPriorityISR || + prio == osPriorityReserved) { + return K_TASK_PRIO_INVALID; + } + + return (k_prio_t)(6 - prio / 8); +} + +static osPriority_t priority_knl2cmsis(k_prio_t prio) { + return (osPriority_t)((6 - prio) * 8); +} + +static osStatus_t errno_knl2cmsis(k_err_t err) { + osStatus_t state; + switch (err) { + case K_ERR_NONE: + state = osOK; + break; + case K_ERR_IN_IRQ: + state = osErrorISR; + break; + case K_ERR_OUT_OF_MEMORY: + state = osErrorNoMemory; + break; + case K_ERR_PEND_TIMEOUT: + state = osErrorTimeout; + break; + case K_ERR_PEND_DESTROY: + state = osErrorResource; + break; + default: + state = osError; + break; + } + return state; +} + +/*---------------------------------------------------------------------------*/ + +osStatus_t osKernelInitialize(void) { + return errno_knl2cmsis(tos_knl_init()); +} + +osStatus_t osKernelGetInfo(osVersion_t* version, + char* id_buf, + uint32_t id_size) { + if (version != NULL) { + version->api = osCMSIS; + version->kernel = osCMSIS_KERNEL; + } + + if ((id_buf != NULL) && (id_size != 0U)) { + if (id_size > sizeof(osKernelSystemId)) { + id_size = sizeof(osKernelSystemId); + } + memcpy(id_buf, osKernelSystemId, id_size); + } + + return osOK; +} + +osKernelState_t osKernelGetState(void) { + osKernelState_t state; + + switch (k_knl_state) { + case KNL_STATE_RUNNING: + state = osKernelRunning; + break; + default: + state = osKernelInactive; + break; + } + + return state; +} + +osStatus_t osKernelStart(void) { + return errno_knl2cmsis(tos_knl_start()); +} + +int32_t osKernelLock(void) { + tos_knl_sched_lock(); + if (knl_is_sched_locked()) { + return 1; + } else { + return 0; + } +} + +int32_t osKernelUnlock(void) { + tos_knl_sched_unlock(); + if (knl_is_sched_locked()) { + return 1; + } else { + return 0; + } +} + +int32_t osKernelRestoreLock(int32_t lock) { + if (lock == 1) { + tos_knl_sched_lock(); + } else if (lock == 0) { + tos_knl_sched_unlock(); + } else { + return -1; + } + + if (knl_is_sched_locked()) { + return 1; + } else { + return 0; + } +} + +uint32_t osKernelSuspend(void) { + // todo + return 0; +} + +void osKernelResume(uint32_t sleep_ticks) { + (void)sleep_ticks; + // todo +} + +uint32_t osKernelGetTickCount(void) { + return (uint32_t)tos_systick_get(); +} + +uint32_t osKernelGetTickFreq(void) { + return TOS_CFG_CPU_TICK_PER_SECOND; +} + +uint32_t osKernelGetSysTimerCount(void) { + k_tick_t ticks; + uint32_t val; + + ticks = osKernelGetTickCount(); + val = ticks * (TOS_CFG_CPU_CLOCK / TOS_CFG_CPU_TICK_PER_SECOND); + + return val; +} + +uint32_t osKernelGetSysTimerFreq(void) { + return TOS_CFG_CPU_CLOCK; +} + +/*---------------------------------------------------------------------------*/ + +osThreadId_t osThreadNew(osThreadFunc_t func, + void* argument, + const osThreadAttr_t* attr) { + k_err_t err; + uint32_t stack_size = K_TASK_STK_SIZE_MIN; + k_task_t* taskId = NULL; + k_prio_t prio; + + if (attr && func) { + if (attr->priority != osPriorityNone) { + prio = priority_cmsis2knl(attr->priority); + } + if (attr->stack_size > 0U) { + stack_size = attr->stack_size; + } + + if (attr->stack_mem && attr->cb_mem) { + err = tos_task_create((k_task_t*)attr->cb_mem, (char*)attr->name, + (k_task_entry_t)func, argument, prio, + attr->stack_mem, stack_size, 0); + taskId = err == K_ERR_NONE ? attr->cb_mem : NULL; + } else { +#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u + k_task_t* task; + err = tos_task_create_dyn(&task, attr->name, (k_task_entry_t)func, + argument, prio, stack_size, 0); + taskId = err == K_ERR_NONE ? task : NULL; +#endif + } + } + + return (osThreadId_t)taskId; +} + +const char* osThreadGetName(osThreadId_t thread_id) { + k_task_t* taskId = (k_task_t*)thread_id; + const char* name; + + if (taskId == NULL) { + name = NULL; + } else { + name = taskId->name; + } + + return name; +} + +osThreadId_t osThreadGetId(void) { + return (osThreadId_t)tos_task_curr_task_get(); +} + +osThreadState_t osThreadGetState(osThreadId_t thread_id) { + k_task_t* taskId = (k_task_t*)thread_id; + osThreadState_t state = osThreadError; + + if (taskId != NULL) { + if (tos_task_curr_task_get() == taskId) { + state = osThreadRunning; + } else if (task_state_is_sleeping(taskId)) { + state = osThreadBlocked; + } else if (task_state_is_pending(taskId)) { + state = osThreadBlocked; + } else if (task_state_is_suspended(taskId)) { + state = osThreadBlocked; + } else if (task_state_is_ready(taskId)) { + state = osThreadReady; + } else if (taskId->state == K_TASK_STATE_DELETED) { + state = osThreadTerminated; + } + } + + return state; +} + +uint32_t osThreadGetStackSize(osThreadId_t thread_id) { + k_task_t* taskId = (k_task_t*)thread_id; + return taskId->stk_size; +} + +uint32_t osThreadGetStackSpace(osThreadId_t thread_id) { + (void)thread_id; + // todo + return 0; +} + +osStatus_t osThreadSetPriority(osThreadId_t thread_id, osPriority_t priority) { + k_task_t* taskId = (k_task_t*)thread_id; + k_prio_t prio = priority_cmsis2knl(priority); + osStatus_t state; + + if (taskId == NULL || prio == K_TASK_PRIO_INVALID) { + state = osErrorParameter; + } else { + state = errno_knl2cmsis(tos_task_prio_change(taskId, prio)); + } + + return state; +} + +osPriority_t osThreadGetPriority(osThreadId_t thread_id) { + k_task_t* taskId = (k_task_t*)thread_id; + osPriority_t prio; + + if (taskId == NULL) { + prio = osPriorityError; + } else { + prio = priority_knl2cmsis(taskId->prio); + } + + return prio; +} + +osStatus_t osThreadYield(void) { + osStatus_t state; + + if (knl_is_inirq()) { + state = osErrorISR; + } else { + tos_task_yield(); + state = osOK; + } + + return state; +} + +osStatus_t osThreadSuspend(osThreadId_t thread_id) { + k_task_t* taskId = (k_task_t*)thread_id; + osStatus_t state; + + if (taskId == NULL) { + state = osErrorParameter; + } else { + state = errno_knl2cmsis(tos_task_suspend(taskId)); + } + + return state; +} + +osStatus_t osThreadResume(osThreadId_t thread_id) { + k_task_t* taskId = (k_task_t*)thread_id; + osStatus_t state; + + if (taskId == NULL) { + state = osErrorParameter; + } else { + state = errno_knl2cmsis(tos_task_resume(taskId)); + } + + return state; +} +osStatus_t osThreadDetach(osThreadId_t thread_id) { + (void)thread_id; + // todo + return osError; +} + +osStatus_t osThreadJoin(osThreadId_t thread_id) { + (void)thread_id; + // todo + return osError; +} + +__NO_RETURN void osThreadExit(void) { + tos_task_destroy(k_curr_task); + while (1) + ; +} + +osStatus_t osThreadTerminate(osThreadId_t thread_id) { + k_task_t* taskId = (k_task_t*)thread_id; + osStatus_t state; + + if (taskId == NULL) { + state = osErrorParameter; + } else { + if (taskId->state == K_TASK_STATE_DELETED) { + state = osErrorResource; + } else { + state = errno_knl2cmsis(tos_task_destroy(taskId)); + } + } + + return state; +} + +uint32_t osThreadGetCount(void) { + uint32_t count = 0; + + TOS_CPU_CPSR_ALLOC(); + k_task_t* task; + + TOS_CPU_INT_DISABLE(); + + TOS_LIST_FOR_EACH_ENTRY(task, k_task_t, stat_list, &k_stat_list) { + count += 1; + } + + TOS_CPU_INT_ENABLE(); + + return count; +} + +uint32_t osThreadEnumerate(osThreadId_t* thread_array, uint32_t array_items) { + uint32_t count = 0; + + if ((thread_array != NULL) && (array_items != 0U)) { + TOS_CPU_CPSR_ALLOC(); + k_task_t* task; + + TOS_CPU_INT_DISABLE(); + + TOS_LIST_FOR_EACH_ENTRY(task, k_task_t, stat_list, &k_stat_list) { + while (count < array_items) { + thread_array[count] = (osThreadId_t)task; + count += 1; + } + } + + TOS_CPU_INT_ENABLE(); + } + + return count; +} + +uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags) { + uint32_t rflags = 0xFFFFFFFF; + // todo + return rflags; +} + +uint32_t osThreadFlagsClear(uint32_t flags) { + uint32_t rflags = 0xFFFFFFFF; + // todo + return rflags; +} + +uint32_t osThreadFlagsGet(void) { + uint32_t rflags = 0xFFFFFFFF; + // todo + return rflags; +} + +uint32_t osThreadFlagsWait(uint32_t flags, uint32_t options, uint32_t timeout) { + uint32_t rflags = 0xFFFFFFFF; + // todo + return rflags; +} + +osStatus_t osDelay(uint32_t ticks) { + k_tick_t delay; + + if (ticks == osWaitForever) { + delay = TOS_TIME_FOREVER; + } else { + delay = (k_tick_t)ticks; + } + + return errno_knl2cmsis(tos_task_delay(delay)); +} + +osStatus_t osDelayUntil(uint32_t ticks) { + k_tick_t delay; + + if (ticks == osWaitForever) { + delay = TOS_TIME_FOREVER; + } else { + k_tick_t now = tos_systick_get(); + if ((k_tick_t)ticks < now) { + return osErrorParameter; + } + delay = (k_tick_t)ticks - now; + } + + return errno_knl2cmsis(tos_task_delay(delay)); +} + +/*---------------------------------------------------------------------------*/ + +osTimerId_t osTimerNew(osTimerFunc_t func, + osTimerType_t type, + void* argument, + const osTimerAttr_t* attr) { + k_err_t err; + k_opt_t opt = TOS_OPT_TIMER_ONESHOT; + k_timer_t* timerId = NULL; + + if (attr && func) { + if (type == osTimerPeriodic) { + opt = TOS_OPT_TIMER_PERIODIC; + } else if (type == osTimerOnce) { + opt = TOS_OPT_TIMER_ONESHOT; + } + + if (attr->cb_mem) { + err = tos_timer_create((k_timer_t*)attr->cb_mem, (k_tick_t)1000u, + (k_tick_t)1000u, (k_timer_callback_t)func, + argument, opt); + timerId = err == K_ERR_NONE ? attr->cb_mem : NULL; + } + } + + return (osTimerId_t)timerId; +} + +const char* osTimerGetName(osTimerId_t timer_id) { + (void)timer_id; + // todo + return NULL; +} + +osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks) { + k_timer_t* timerId = (k_timer_t*)timer_id; + osStatus_t state; + + if (timerId == NULL) { + state = osErrorParameter; + } else { + tos_timer_delay_change(timerId, ticks); + tos_timer_period_change(timerId, ticks); + state = errno_knl2cmsis(tos_timer_start(timerId)); + } + + return state; +} + +osStatus_t osTimerStop(osTimerId_t timer_id) { + k_timer_t* timerId = (k_timer_t*)timer_id; + osStatus_t state; + + if (timerId == NULL) { + state = osErrorParameter; + } else { + state = errno_knl2cmsis(tos_timer_stop(timerId)); + } + + return state; +} + +uint32_t osTimerIsRunning(osTimerId_t timer_id) { + k_timer_t* timerId = (k_timer_t*)timer_id; + uint32_t running; + + if (timerId == NULL) { + running = 0U; + } else { + running = timerId->state == TIMER_STATE_RUNNING; + } + + return running; +} + +osStatus_t osTimerDelete(osTimerId_t timer_id) { + k_timer_t* timerId = (k_timer_t*)timer_id; + + return errno_knl2cmsis(tos_timer_destroy(timerId)); +} + +/*---------------------------------------------------------------------------*/ + +osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t* attr) { + k_err_t err; + k_event_t* eventId = NULL; + + if (attr) { + if (attr->cb_mem) { + err = tos_event_create((k_event_t*)attr->cb_mem, 0); + eventId = err == K_ERR_NONE ? attr->cb_mem : NULL; + } + } + + return (osEventFlagsId_t)eventId; +} + +const char* osEventFlagsGetName(osEventFlagsId_t ef_id) { + (void)ef_id; + // todo + return NULL; +} + +uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags) { + k_event_t* eventId = (k_event_t*)ef_id; + k_err_t err; + uint32_t rflags; + + if (eventId == NULL) { + rflags = (uint32_t)osErrorParameter; + } else { + err = tos_event_post_keep(eventId, (k_event_flag_t)flags); + rflags = err == K_ERR_NONE ? (uint32_t)eventId->flag + : (uint32_t)errno_knl2cmsis(err); + } + + return rflags; +} + +uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags) { + k_event_t* eventId = (k_event_t*)ef_id; + k_err_t err; + uint32_t rflags; + + if (eventId == NULL) { + rflags = (uint32_t)osErrorParameter; + } else { + flags = eventId->flag & (~flags); + err = tos_event_post(eventId, (k_event_flag_t)flags); + rflags = err == K_ERR_NONE ? (uint32_t)eventId->flag + : (uint32_t)errno_knl2cmsis(err); + } + + return rflags; +} + +uint32_t osEventFlagsGet(osEventFlagsId_t ef_id) { + k_event_t* eventId = (k_event_t*)ef_id; + uint32_t rflags; + + if (ef_id == NULL) { + rflags = 0U; + } else { + rflags = (uint32_t)eventId->flag; + } + + return rflags; +} + +uint32_t osEventFlagsWait(osEventFlagsId_t ef_id, + uint32_t flags, + uint32_t options, + uint32_t timeout) { + k_event_t* eventId = (k_event_t*)ef_id; + k_err_t err; + uint32_t rflags; + + if (ef_id == NULL) { + rflags = (uint32_t)osErrorParameter; + } else { + k_event_flag_t flag_match; + k_opt_t opt_pend = 0; + k_tick_t timeout = + (timeout == 0 || timeout == osWaitForever) ? TOS_TIME_FOREVER : timeout; + if (options & 0x01 == 0) { + opt_pend |= TOS_OPT_EVENT_PEND_ANY; + } else { + opt_pend |= TOS_OPT_EVENT_PEND_ALL; + } + if (options & 0x02 == 0) { + opt_pend |= TOS_OPT_EVENT_PEND_CLR; + } + + err = tos_event_pend(eventId, (k_event_flag_t)flags, &flag_match, timeout, + opt_pend); + rflags = err == K_ERR_NONE ? (uint32_t)flag_match + : (uint32_t)errno_knl2cmsis(err); + } + + return rflags; +} + +osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id) { + k_event_t* eventId = (k_event_t*)ef_id; + + return errno_knl2cmsis(tos_event_destroy(eventId)); +} + +/*---------------------------------------------------------------------------*/ + +osMutexId_t osMutexNew(const osMutexAttr_t* attr) { + k_err_t err; + k_mutex_t* mutexId = NULL; + + if (attr) { + if (attr->cb_mem) { + err = tos_mutex_create((k_mutex_t*)attr->cb_mem); + mutexId = err == K_ERR_NONE ? attr->cb_mem : NULL; + } + } + + return (osEventFlagsId_t)mutexId; +} + +const char* osMutexGetName(osMutexId_t mutex_id) { + (void)mutex_id; + // todo + return NULL; +} + +osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout) { + k_mutex_t* mutexId = (k_mutex_t*)mutex_id; + + return errno_knl2cmsis(tos_mutex_pend_timed(mutexId, timeout)); +} + +osStatus_t osMutexRelease(osMutexId_t mutex_id) { + k_mutex_t* mutexId = (k_mutex_t*)mutex_id; + + return errno_knl2cmsis(tos_mutex_post(mutexId)); +} + +osThreadId_t osMutexGetOwner(osMutexId_t mutex_id) { + k_mutex_t* mutexId = (k_mutex_t*)mutex_id; + + return (osThreadId_t)mutexId->owner; +} + +osStatus_t osMutexDelete(osMutexId_t mutex_id) { + k_mutex_t* mutexId = (k_mutex_t*)mutex_id; + + return errno_knl2cmsis(tos_mutex_destroy(mutexId)); +} + +/*---------------------------------------------------------------------------*/ + +osSemaphoreId_t osSemaphoreNew(uint32_t max_count, + uint32_t initial_count, + const osSemaphoreAttr_t* attr) { + k_err_t err; + k_sem_t* semId = NULL; + + if (attr) { + if (attr->cb_mem) { + err = + tos_sem_create_max((k_sem_t*)attr->cb_mem, (k_sem_cnt_t)initial_count, + (k_sem_cnt_t)max_count); + semId = err == K_ERR_NONE ? attr->cb_mem : NULL; + } + } + + return (osEventFlagsId_t)semId; +} + +const char* osSemaphoreGetName(osSemaphoreId_t semaphore_id) { + (void)semaphore_id; + // todo + return NULL; +} + +osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout) { + k_sem_t* semId = (k_sem_t*)semaphore_id; + + return errno_knl2cmsis(tos_sem_pend(semId, timeout)); +} + +osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id) { + k_sem_t* semId = (k_sem_t*)semaphore_id; + + return errno_knl2cmsis(tos_sem_post(semId)); +} + +uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id) { + k_sem_t* semId = (k_sem_t*)semaphore_id; + + return (uint32_t)semId->count; +} + +osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id) { + k_sem_t* semId = (k_sem_t*)semaphore_id; + + return errno_knl2cmsis(tos_sem_destroy(semId)); +} + +/*---------------------------------------------------------------------------*/ + +osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count, + uint32_t block_size, + const osMemoryPoolAttr_t* attr) { + k_err_t err; + k_mmblk_pool_t* mpId = NULL; + + if (attr) { + if (attr->cb_mem) { + err = tos_mmblk_pool_create((k_mmblk_pool_t*)attr->cb_mem, attr->mp_mem, + block_count, block_size); + mpId = err == K_ERR_NONE ? attr->cb_mem : NULL; + } + } + + return (osMemoryPoolId_t)mpId; +} + +const char* osMemoryPoolGetName(osMemoryPoolId_t mp_id) { + (void)mp_id; + // todo + return NULL; +} + +void* osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout) { + k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id; + k_err_t err; + void* blk = NULL; + + err = tos_mmblk_alloc(mpId, &blk); + + return err == K_ERR_NONE ? blk : NULL; +} + +osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void* block) { + k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id; + + return errno_knl2cmsis(tos_mmblk_free(mpId, block)); +} +uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id) { + k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id; + return mpId->blk_max; +} +uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id) { + k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id; + return mpId->blk_size; +} +uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id) { + k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id; + return mpId->blk_max - mpId->blk_free; +} +uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id) { + k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id; + return mpId->blk_free; +} +osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id) { + k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id; + + return errno_knl2cmsis(tos_mmblk_pool_destroy(mpId)); +} + +/*---------------------------------------------------------------------------*/ + +#if TOS_CFG_MESSAGE_QUEUE_EN > 0u +osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, + uint32_t msg_size, + const osMessageQueueAttr_t* attr) { + k_err_t err; + k_msg_q_t* mqId = NULL; + + if (attr) { + if (attr->mq_mem && msg_size == sizeof(void*)) { + err = tos_msg_q_create((k_msg_q_t*)attr->cb_mem, attr->mq_mem, msg_count); + mqId = err == K_ERR_NONE ? attr->cb_mem : NULL; + } + } + + return mqId; +} + +const char* osMessageQueueGetName(osMessageQueueId_t mq_id) { + (void)mq_id; + // todo + return NULL; +} + +osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id, + const void* msg_ptr, + uint8_t msg_prio, + uint32_t timeout) { + k_msg_q_t* mqId = (k_msg_q_t*)mq_id; + + return errno_knl2cmsis(tos_msg_q_post(mqId, (void*)msg_ptr)); +} + +osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id, + void* msg_ptr, + uint8_t* msg_prio, + uint32_t timeout) { + k_msg_q_t* mqId = (k_msg_q_t*)mq_id; + + return errno_knl2cmsis(tos_msg_q_pend(mqId, &msg_ptr, timeout)); +} + +uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mq_id) { + k_msg_q_t* mqId = (k_msg_q_t*)mq_id; + uint32_t capacity; + + if (mqId == NULL) { + capacity = 0U; + } else { + capacity = mqId->ring_q.item_cnt; + } + + return capacity; +} + +uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id) { + k_msg_q_t* mqId = (k_msg_q_t*)mq_id; + uint32_t size; + + if (mqId == NULL) { + size = 0U; + } else { + size = mqId->ring_q.item_size; + } + + return size; +} + +uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id) { + k_msg_q_t* mqId = (k_msg_q_t*)mq_id; + uint32_t count; + + if (mqId == NULL) { + count = 0U; + } else { + count = mqId->ring_q.total; + } + + return count; +} + +uint32_t osMessageQueueGetSpace(osMessageQueueId_t mq_id) { + k_msg_q_t* mqId = (k_msg_q_t*)mq_id; + uint32_t space; + + if (mqId == NULL) { + space = 0U; + } else { + space = mqId->ring_q.item_cnt - mqId->ring_q.total; + } + + return space; +} + +osStatus_t osMessageQueueReset(osMessageQueueId_t mq_id) { + k_msg_q_t* mqId = (k_msg_q_t*)mq_id; + + return errno_knl2cmsis(tos_msg_q_flush(mqId)); +} + +osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id) { + k_msg_q_t* mqId = (k_msg_q_t*)mq_id; + + return errno_knl2cmsis(tos_msg_q_destroy(mqId)); +} +#endif + +/*---------------------------------------------------------------------------*/ diff --git a/osal/cmsis_os/cmsis_os2.h b/osal/cmsis_os/cmsis_os2.h new file mode 100644 index 00000000..5d231cdd --- /dev/null +++ b/osal/cmsis_os/cmsis_os2.h @@ -0,0 +1,799 @@ +/* + * Copyright (c) 2013-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 18. June 2018 + * $Revision: V2.1.3 + * + * Project: CMSIS-RTOS2 API + * Title: cmsis_os2.h header file + * + * Version 2.1.3 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osThreadGetId + * Version 2.1.2 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetInfo, osKernelGetState + * Version 2.1.1 + * Additional functions allowed to be called from Interrupt Service Routines: + * - osKernelGetTickCount, osKernelGetTickFreq + * Changed Kernel Tick type to uint32_t: + * - updated: osKernelGetTickCount, osDelayUntil + * Version 2.1.0 + * Support for critical and uncritical sections (nesting safe): + * - updated: osKernelLock, osKernelUnlock + * - added: osKernelRestoreLock + * Updated Thread and Event Flags: + * - changed flags parameter and return type from int32_t to uint32_t + * Version 2.0.0 + * Initial Release + *---------------------------------------------------------------------------*/ + +#ifndef CMSIS_OS2_H_ +#define CMSIS_OS2_H_ + +/* Kernel version and identification string definition */ +#define osCMSIS 0x20001U ///< API version (main[31:16].sub[15:0]) + +/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number. +#define osCMSIS_KERNEL 0x10000U ///< RTOS identification and version (main[31:16].sub[15:0]) + +/// \note CAN BE CHANGED: \b osKernelSystemId identifies the underlying RTOS kernel. +#define osKernelSystemId "TencentOS tiny V1.00" ///< RTOS identification string + +#ifndef __NO_RETURN +#if defined(__CC_ARM) +#define __NO_RETURN __declspec(noreturn) +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) +#define __NO_RETURN __attribute__((__noreturn__)) +#elif defined(__GNUC__) +#define __NO_RETURN __attribute__((__noreturn__)) +#elif defined(__ICCARM__) +#define __NO_RETURN __noreturn +#else +#define __NO_RETURN +#endif +#endif + +#include +#include +#include "tos_k.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// ==== Enumerations, structures, defines ==== + +/// Version information. +typedef struct { + uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec). + uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec). +} osVersion_t; + +/// Kernel state. +typedef enum { + osKernelInactive = 0, ///< Inactive. + osKernelReady = 1, ///< Ready. + osKernelRunning = 2, ///< Running. + osKernelLocked = 3, ///< Locked. + osKernelSuspended = 4, ///< Suspended. + osKernelError = -1, ///< Error. + osKernelReserved = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization. +} osKernelState_t; + +/// Thread state. +typedef enum { + osThreadInactive = 0, ///< Inactive. + osThreadReady = 1, ///< Ready. + osThreadRunning = 2, ///< Running. + osThreadBlocked = 3, ///< Blocked. + osThreadTerminated = 4, ///< Terminated. + osThreadError = -1, ///< Error. + osThreadReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osThreadState_t; + +/// Priority values. +typedef enum { + osPriorityNone = 0, ///< No priority (not initialized). + osPriorityIdle = 1, ///< Reserved for Idle thread. + osPriorityLow = 8, ///< Priority: low + osPriorityLow1 = 8+1, ///< Priority: low + 1 + osPriorityLow2 = 8+2, ///< Priority: low + 2 + osPriorityLow3 = 8+3, ///< Priority: low + 3 + osPriorityLow4 = 8+4, ///< Priority: low + 4 + osPriorityLow5 = 8+5, ///< Priority: low + 5 + osPriorityLow6 = 8+6, ///< Priority: low + 6 + osPriorityLow7 = 8+7, ///< Priority: low + 7 + osPriorityBelowNormal = 16, ///< Priority: below normal + osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1 + osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2 + osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3 + osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4 + osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5 + osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6 + osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7 + osPriorityNormal = 24, ///< Priority: normal + osPriorityNormal1 = 24+1, ///< Priority: normal + 1 + osPriorityNormal2 = 24+2, ///< Priority: normal + 2 + osPriorityNormal3 = 24+3, ///< Priority: normal + 3 + osPriorityNormal4 = 24+4, ///< Priority: normal + 4 + osPriorityNormal5 = 24+5, ///< Priority: normal + 5 + osPriorityNormal6 = 24+6, ///< Priority: normal + 6 + osPriorityNormal7 = 24+7, ///< Priority: normal + 7 + osPriorityAboveNormal = 32, ///< Priority: above normal + osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1 + osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2 + osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3 + osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4 + osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5 + osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6 + osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7 + osPriorityHigh = 40, ///< Priority: high + osPriorityHigh1 = 40+1, ///< Priority: high + 1 + osPriorityHigh2 = 40+2, ///< Priority: high + 2 + osPriorityHigh3 = 40+3, ///< Priority: high + 3 + osPriorityHigh4 = 40+4, ///< Priority: high + 4 + osPriorityHigh5 = 40+5, ///< Priority: high + 5 + osPriorityHigh6 = 40+6, ///< Priority: high + 6 + osPriorityHigh7 = 40+7, ///< Priority: high + 7 + osPriorityRealtime = 48, ///< Priority: realtime + osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1 + osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2 + osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3 + osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4 + osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5 + osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6 + osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7 + osPriorityISR = 56, ///< Reserved for ISR deferred thread. + osPriorityError = -1, ///< System cannot determine priority or illegal priority. + osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osPriority_t; + +/// Entry point of a thread. +typedef void (*osThreadFunc_t) (void *argument); + +/// Timer callback function. +typedef void (*osTimerFunc_t) (void *argument); + +/// Timer type. +typedef enum { + osTimerOnce = 0, ///< One-shot timer. + osTimerPeriodic = 1 ///< Repeating timer. +} osTimerType_t; + +// Timeout value. +#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value. + +// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait). +#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default). +#define osFlagsWaitAll 0x00000001U ///< Wait for all flags. +#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for. + +// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx). +#define osFlagsError 0x80000000U ///< Error indicator. +#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1). +#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2). +#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3). +#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4). +#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6). + +// Thread attributes (attr_bits in \ref osThreadAttr_t). +#define osThreadDetached 0x00000000U ///< Thread created in detached mode (default) +#define osThreadJoinable 0x00000001U ///< Thread created in joinable mode + +// Mutex attributes (attr_bits in \ref osMutexAttr_t). +#define osMutexRecursive 0x00000001U ///< Recursive mutex. +#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol. +#define osMutexRobust 0x00000008U ///< Robust mutex. + +/// Status code values returned by CMSIS-RTOS functions. +typedef enum { + osOK = 0, ///< Operation completed successfully. + osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits. + osErrorTimeout = -2, ///< Operation not completed within the timeout period. + osErrorResource = -3, ///< Resource not available. + osErrorParameter = -4, ///< Parameter error. + osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation. + osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines. + osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization. +} osStatus_t; + + +/// \details Thread ID identifies the thread. +typedef void *osThreadId_t; + +/// \details Timer ID identifies the timer. +typedef void *osTimerId_t; + +/// \details Event Flags ID identifies the event flags. +typedef void *osEventFlagsId_t; + +/// \details Mutex ID identifies the mutex. +typedef void *osMutexId_t; + +/// \details Semaphore ID identifies the semaphore. +typedef void *osSemaphoreId_t; + +/// \details Memory Pool ID identifies the memory pool. +typedef void *osMemoryPoolId_t; + +/// \details Message Queue ID identifies the message queue. +typedef void *osMessageQueueId_t; + + +#ifndef TZ_MODULEID_T +#define TZ_MODULEID_T +/// \details Data type that identifies secure software modules called by a process. +typedef uint32_t TZ_ModuleId_t; +#endif + + +/// Attributes structure for thread. +typedef struct { + const char *name; ///< name of the thread + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *stack_mem; ///< memory for stack + uint32_t stack_size; ///< size of stack + osPriority_t priority; ///< initial thread priority (default: osPriorityNormal) + TZ_ModuleId_t tz_module; ///< TrustZone module identifier + uint32_t reserved; ///< reserved (must be 0) +} osThreadAttr_t; + +/// Attributes structure for timer. +typedef struct { + const char *name; ///< name of the timer + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osTimerAttr_t; + +/// Attributes structure for event flags. +typedef struct { + const char *name; ///< name of the event flags + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osEventFlagsAttr_t; + +/// Attributes structure for mutex. +typedef struct { + const char *name; ///< name of the mutex + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osMutexAttr_t; + +/// Attributes structure for semaphore. +typedef struct { + const char *name; ///< name of the semaphore + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block +} osSemaphoreAttr_t; + +/// Attributes structure for memory pool. +typedef struct { + const char *name; ///< name of the memory pool + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mp_mem; ///< memory for data storage + uint32_t mp_size; ///< size of provided memory for data storage +} osMemoryPoolAttr_t; + +/// Attributes structure for message queue. +typedef struct { + const char *name; ///< name of the message queue + uint32_t attr_bits; ///< attribute bits + void *cb_mem; ///< memory for control block + uint32_t cb_size; ///< size of provided memory for control block + void *mq_mem; ///< memory for data storage + uint32_t mq_size; ///< size of provided memory for data storage +} osMessageQueueAttr_t; + + +// ==== Kernel Management Functions ==== + +/// Initialize the RTOS Kernel. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelInitialize (void); + +/// Get RTOS Kernel Information. +/// \param[out] version pointer to buffer for retrieving version information. +/// \param[out] id_buf pointer to buffer for retrieving kernel identification string. +/// \param[in] id_size size of buffer for kernel identification string. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size); + +/// Get the current RTOS Kernel state. +/// \return current RTOS Kernel state. +osKernelState_t osKernelGetState (void); + +/// Start the RTOS Kernel scheduler. +/// \return status code that indicates the execution status of the function. +osStatus_t osKernelStart (void); + +/// Lock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelLock (void); + +/// Unlock the RTOS Kernel scheduler. +/// \return previous lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelUnlock (void); + +/// Restore the RTOS Kernel scheduler lock state. +/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock. +/// \return new lock state (1 - locked, 0 - not locked, error code if negative). +int32_t osKernelRestoreLock (int32_t lock); + +/// Suspend the RTOS Kernel scheduler. +/// \return time in ticks, for how long the system can sleep or power-down. +uint32_t osKernelSuspend (void); + +/// Resume the RTOS Kernel scheduler. +/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode. +void osKernelResume (uint32_t sleep_ticks); + +/// Get the RTOS kernel tick count. +/// \return RTOS kernel current tick count. +uint32_t osKernelGetTickCount (void); + +/// Get the RTOS kernel tick frequency. +/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second. +uint32_t osKernelGetTickFreq (void); + +/// Get the RTOS kernel system timer count. +/// \return RTOS kernel current system timer count as 32-bit value. +uint32_t osKernelGetSysTimerCount (void); + +/// Get the RTOS kernel system timer frequency. +/// \return frequency of the system timer in hertz, i.e. timer ticks per second. +uint32_t osKernelGetSysTimerFreq (void); + + +// ==== Thread Management Functions ==== + +/// Create a Thread Definition with function, priority, and stack requirements. +/// \param name name of the thread function. +/// \param priority initial priority of the thread function. +/// \param instances number of possible thread instances. +/// \param stacksz stack size (in bytes) requirements for the thread function. +/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#if defined (osObjectsExternal) // object is external +#define osThreadDef(name, priority, instances, stacksz) \ + extern const osThreadAttr_t os_thread_def_##name +#else // define the object + +#define osThreadDef(name, priority, instances, stacksz) \ + k_task_t task_handler_##name; \ + k_stack_t task_stack_##name[(stacksz)]; \ + const osThreadAttr_t os_thread_def_##name = \ + { #name, 0, (&(task_handler_##name)), sizeof(k_task_t), (&((task_stack_##name)[0])), (stacksz), (osPriority_t)(priority) } + +#if (TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u) +#define osThreadDynamicDef(name, priority, instances, stacksz) \ + const osThreadAttr_t os_thread_def_##name = \ + { #name, 0, (K_NULL), sizeof(k_task_t), (K_NULL), (stacksz), (osPriority_t)(priority) } +#endif + +#endif + +/// Access a Thread definition. +/// \param name name of the thread definition object. +/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the +/// macro body is implementation specific in every CMSIS-RTOS. +#define osThread(name) \ + &os_thread_def_##name + +/// Create a thread and add it to Active Threads. +/// \param[in] func thread function. +/// \param[in] argument pointer that is passed to the thread function as start argument. +/// \param[in] attr thread attributes; NULL: default values. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr); + +/// Get name of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return name as null-terminated string. +const char *osThreadGetName (osThreadId_t thread_id); + +/// Return the thread ID of the current running thread. +/// \return thread ID for reference by other functions or NULL in case of error. +osThreadId_t osThreadGetId (void); + +/// Get current thread state of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current thread state of the specified thread. +osThreadState_t osThreadGetState (osThreadId_t thread_id); + +/// Get stack size of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return stack size in bytes. +uint32_t osThreadGetStackSize (osThreadId_t thread_id); + +/// Get available stack space of a thread based on stack watermark recording during execution. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return remaining stack space in bytes. +uint32_t osThreadGetStackSpace (osThreadId_t thread_id); + +/// Change priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] priority new priority value for the thread function. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority); + +/// Get current priority of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return current priority value of the specified thread. +osPriority_t osThreadGetPriority (osThreadId_t thread_id); + +/// Pass control to next thread that is in state \b READY. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadYield (void); + +/// Suspend execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadSuspend (osThreadId_t thread_id); + +/// Resume execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadResume (osThreadId_t thread_id); + +/// Detach a thread (thread storage can be reclaimed when thread terminates). +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadDetach (osThreadId_t thread_id); + +/// Wait for specified thread to terminate. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadJoin (osThreadId_t thread_id); + +/// Terminate execution of current running thread. +__NO_RETURN void osThreadExit (void); + +/// Terminate execution of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \return status code that indicates the execution status of the function. +osStatus_t osThreadTerminate (osThreadId_t thread_id); + +/// Get number of active threads. +/// \return number of active threads. +uint32_t osThreadGetCount (void); + +/// Enumerate active threads. +/// \param[out] thread_array pointer to array for retrieving thread IDs. +/// \param[in] array_items maximum number of items in array for retrieving thread IDs. +/// \return number of enumerated threads. +uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items); + + +// ==== Thread Flags Functions ==== + +/// Set the specified Thread Flags of a thread. +/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId. +/// \param[in] flags specifies the flags of the thread that shall be set. +/// \return thread flags after setting or error code if highest bit set. +uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags); + +/// Clear the specified Thread Flags of current running thread. +/// \param[in] flags specifies the flags of the thread that shall be cleared. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsClear (uint32_t flags); + +/// Get the current Thread Flags of current running thread. +/// \return current thread flags. +uint32_t osThreadFlagsGet (void); + +/// Wait for one or more Thread Flags of the current running thread to become signaled. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return thread flags before clearing or error code if highest bit set. +uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout); + + +// ==== Generic Wait Functions ==== + +/// Wait for Timeout (Time Delay). +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value +/// \return status code that indicates the execution status of the function. +osStatus_t osDelay (uint32_t ticks); + +/// Wait until specified time. +/// \param[in] ticks absolute time in ticks +/// \return status code that indicates the execution status of the function. +osStatus_t osDelayUntil (uint32_t ticks); + + +// ==== Timer Management Functions ==== + +/// Create and Initialize a timer. +/// \param[in] func function pointer to callback function. +/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior. +/// \param[in] argument argument to the timer callback function. +/// \param[in] attr timer attributes; NULL: default values. +/// \return timer ID for reference by other functions or NULL in case of error. +osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr); + +/// Get name of a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return name as null-terminated string. +const char *osTimerGetName (osTimerId_t timer_id); + +/// Start or restart a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks); + +/// Stop a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerStop (osTimerId_t timer_id); + +/// Check if a timer is running. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return 0 not running, 1 running. +uint32_t osTimerIsRunning (osTimerId_t timer_id); + +/// Delete a timer. +/// \param[in] timer_id timer ID obtained by \ref osTimerNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osTimerDelete (osTimerId_t timer_id); + + +// ==== Event Flags Management Functions ==== + +/// Create and Initialize an Event Flags object. +/// \param[in] attr event flags attributes; NULL: default values. +/// \return event flags ID for reference by other functions or NULL in case of error. +osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr); + +/// Get name of an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return name as null-terminated string. +const char *osEventFlagsGetName (osEventFlagsId_t ef_id); + +/// Set the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be set. +/// \return event flags after setting or error code if highest bit set. +uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags); + +/// Clear the specified Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags that shall be cleared. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags); + +/// Get the current Event Flags. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return current event flags. +uint32_t osEventFlagsGet (osEventFlagsId_t ef_id); + +/// Wait for one or more Event Flags to become signaled. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \param[in] flags specifies the flags to wait for. +/// \param[in] options specifies flags options (osFlagsXxxx). +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return event flags before clearing or error code if highest bit set. +uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout); + +/// Delete an Event Flags object. +/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id); + + +// ==== Mutex Management Functions ==== + +/// Create and Initialize a Mutex object. +/// \param[in] attr mutex attributes; NULL: default values. +/// \return mutex ID for reference by other functions or NULL in case of error. +osMutexId_t osMutexNew (const osMutexAttr_t *attr); + +/// Get name of a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return name as null-terminated string. +const char *osMutexGetName (osMutexId_t mutex_id); + +/// Acquire a Mutex or timeout if it is locked. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout); + +/// Release a Mutex that was acquired by \ref osMutexAcquire. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexRelease (osMutexId_t mutex_id); + +/// Get Thread which owns a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return thread ID of owner thread or NULL when mutex was not acquired. +osThreadId_t osMutexGetOwner (osMutexId_t mutex_id); + +/// Delete a Mutex object. +/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMutexDelete (osMutexId_t mutex_id); + + +// ==== Semaphore Management Functions ==== + +/// Create and Initialize a Semaphore object. +/// \param[in] max_count maximum number of available tokens. +/// \param[in] initial_count initial number of available tokens. +/// \param[in] attr semaphore attributes; NULL: default values. +/// \return semaphore ID for reference by other functions or NULL in case of error. +osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr); + +/// Get name of a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return name as null-terminated string. +const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id); + +/// Acquire a Semaphore token or timeout if no tokens are available. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout); + +/// Release a Semaphore token up to the initial maximum count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id); + +/// Get current Semaphore token count. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return number of tokens available. +uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id); + +/// Delete a Semaphore object. +/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id); + + +// ==== Memory Pool Management Functions ==== + +/// Create and Initialize a Memory Pool object. +/// \param[in] block_count maximum number of memory blocks in memory pool. +/// \param[in] block_size memory block size in bytes. +/// \param[in] attr memory pool attributes; NULL: default values. +/// \return memory pool ID for reference by other functions or NULL in case of error. +osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr); + +/// Get name of a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return name as null-terminated string. +const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id); + +/// Allocate a memory block from a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return address of the allocated memory block or NULL in case of no memory is available. +void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout); + +/// Return an allocated memory block back to a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \param[in] block address of the allocated memory block to be returned to the memory pool. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block); + +/// Get maximum number of memory blocks in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return maximum number of memory blocks. +uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id); + +/// Get memory block size in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return memory block size in bytes. +uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks used in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks used. +uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id); + +/// Get number of memory blocks available in a Memory Pool. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return number of memory blocks available. +uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id); + +/// Delete a Memory Pool object. +/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id); + + +// ==== Message Queue Management Functions ==== + +/// Create and Initialize a Message Queue object. +/// \param[in] msg_count maximum number of messages in queue. +/// \param[in] msg_size maximum message size in bytes. +/// \param[in] attr message queue attributes; NULL: default values. +/// \return message queue ID for reference by other functions or NULL in case of error. +osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr); + +/// Get name of a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return name as null-terminated string. +const char *osMessageQueueGetName (osMessageQueueId_t mq_id); + +/// Put a Message into a Queue or timeout if Queue is full. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[in] msg_ptr pointer to buffer with message to put into a queue. +/// \param[in] msg_prio message priority. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout); + +/// Get a Message from a Queue or timeout if Queue is empty. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \param[out] msg_ptr pointer to buffer for message to get from a queue. +/// \param[out] msg_prio pointer to buffer for message priority or NULL. +/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout); + +/// Get maximum number of messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum number of messages. +uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id); + +/// Get maximum message size in a Memory Pool. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return maximum message size in bytes. +uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id); + +/// Get number of queued messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of queued messages. +uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id); + +/// Get number of available slots for messages in a Message Queue. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return number of available slots for messages. +uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id); + +/// Reset a Message Queue to initial empty state. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id); + +/// Delete a Message Queue object. +/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew. +/// \return status code that indicates the execution status of the function. +osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id); + + +#ifdef __cplusplus +} +#endif + +#endif // CMSIS_OS2_H_ diff --git a/osal/cmsis_os/os_tick.h b/osal/cmsis_os/os_tick.h new file mode 100644 index 00000000..8f7cdf66 --- /dev/null +++ b/osal/cmsis_os/os_tick.h @@ -0,0 +1,71 @@ +/**************************************************************************//** + * @file os_tick.h + * @brief CMSIS OS Tick header file + * @version V1.0.1 + * @date 24. November 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OS_TICK_H +#define OS_TICK_H + +#include + +/// IRQ Handler. +#ifndef IRQHANDLER_T +#define IRQHANDLER_T +typedef void (*IRQHandler_t) (void); +#endif + +/// Setup OS Tick timer to generate periodic RTOS Kernel Ticks +/// \param[in] freq tick frequency in Hz +/// \param[in] handler tick IRQ handler +/// \return 0 on success, -1 on error. +int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler); + +/// Enable OS Tick timer interrupt +void OS_Tick_Enable (void); + +/// Disable OS Tick timer interrupt +void OS_Tick_Disable (void); + +/// Acknowledge execution of OS Tick timer interrupt +void OS_Tick_AcknowledgeIRQ (void); + +/// Get OS Tick timer IRQ number +/// \return OS Tick IRQ number +int32_t OS_Tick_GetIRQn (void); + +/// Get OS Tick timer clock frequency +/// \return OS Tick timer clock frequency in Hz +uint32_t OS_Tick_GetClock (void); + +/// Get OS Tick timer interval reload value +/// \return OS Tick timer interval reload value +uint32_t OS_Tick_GetInterval (void); + +/// Get OS Tick timer counter value +/// \return OS Tick timer counter value +uint32_t OS_Tick_GetCount (void); + +/// Get OS Tick timer overflow status +/// \return OS Tick overflow status (1 - overflow, 0 - no overflow). +uint32_t OS_Tick_GetOverflow (void); + +#endif /* OS_TICK_H */