zephyr/lib/cmsis_rtos_v2/kernel.c
Andy Ross ee4c23cc1f CMSIS v2: Work around time unit confusion
The current CMSIS v2 implementation is clearly assuming that timeout
arguments being passed to e.g. osDelay() are in units of Zephyr ticks,
not milliseconds as specified by ARM or (inconsistently) assumed by
our test code.

Most tests work with the ~100 Hz default tick rate, but they tend to
fail on precision issues at higher tick rates.  Force the CMSIS v2
applications to be 1000 Hz for now as a workaround, and detect the
mismatch as a build failure.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
2019-07-02 22:52:29 -04:00

157 lines
2.7 KiB
C

/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include <kernel_structs.h>
#include <ksched.h>
#include <cmsis_os2.h>
/* Currently the timing implementations for timeouts and osDelay
* assume that the arguments are in Zephyr ticks, even though ARM
* documentation and at least some of our test code assume they are
* milliseconds. They must match for now.
*/
BUILD_ASSERT(CONFIG_SYS_CLOCK_TICKS_PER_SEC == 1000);
extern u32_t z_tick_get_32(void);
/**
* @brief Get RTOS Kernel Information.
*/
osStatus_t osKernelGetInfo(osVersion_t *version, char *id_buf, uint32_t id_size)
{
u32_t ver = sys_kernel_version_get();
if (version != NULL) {
version->api = ver;
version->kernel = ver;
}
if ((id_buf != NULL) && (version != NULL)) {
snprintf(id_buf, id_size,
"Zephyr V%2"PRIu32".%2"PRIu32".%2"PRIu32,
SYS_KERNEL_VER_MAJOR(version->kernel),
SYS_KERNEL_VER_MINOR(version->kernel),
SYS_KERNEL_VER_PATCHLEVEL(version->kernel));
}
return osOK;
}
/**
* @brief Lock the RTOS Kernel scheduler.
*/
int32_t osKernelLock(void)
{
int temp = _current->base.sched_locked;
if (k_is_in_isr()) {
return osErrorISR;
}
k_sched_lock();
return temp;
}
/**
* @brief Unlock the RTOS Kernel scheduler.
*/
int32_t osKernelUnlock(void)
{
int temp = _current->base.sched_locked;
if (k_is_in_isr()) {
return osErrorISR;
}
k_sched_unlock();
return temp;
}
/**
* @brief Restore the RTOS Kernel scheduler lock state.
*/
int32_t osKernelRestoreLock(int32_t lock)
{
_current->base.sched_locked = lock;
if (k_is_in_isr()) {
return osErrorISR;
}
if (lock < 0) {
return 1; /* locked */
} else {
return 0; /* not locked */
}
}
/**
* @brief Get the RTOS kernel tick count.
*/
uint32_t osKernelGetTickCount(void)
{
return z_tick_get_32();
}
/**
* @brief Get the RTOS kernel tick frequency.
*/
uint32_t osKernelGetTickFreq(void)
{
return CONFIG_SYS_CLOCK_TICKS_PER_SEC;
}
/**
* @brief Get the RTOS kernel system timer count.
*/
uint32_t osKernelGetSysTimerCount(void)
{
return k_cycle_get_32();
}
/**
* @brief Get the RTOS kernel system timer frequency.
*/
uint32_t osKernelGetSysTimerFreq(void)
{
return sys_clock_hw_cycles_per_sec();
}
/**
* @brief Wait for Timeout (Time Delay).
*/
osStatus_t osDelay(uint32_t ticks)
{
if (k_is_in_isr()) {
return osErrorISR;
}
k_sleep(__ticks_to_ms(ticks));
return osOK;
}
/**
* @brief Wait until specified time.
*/
osStatus_t osDelayUntil(uint32_t ticks)
{
u32_t ticks_elapsed;
if (k_is_in_isr()) {
return osErrorISR;
}
ticks_elapsed = osKernelGetTickCount();
k_sleep(__ticks_to_ms(ticks - ticks_elapsed));
return osOK;
}