zephyr/subsys/portability/cmsis_rtos_v2/timer.c

178 lines
3.3 KiB
C

/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <string.h>
#include "wrapper.h"
#define ACTIVE 1
#define NOT_ACTIVE 0
static void zephyr_timer_wrapper(struct k_timer *timer);
K_MEM_SLAB_DEFINE(cv2_timer_slab, sizeof(struct cv2_timer),
CONFIG_CMSIS_V2_TIMER_MAX_COUNT, 4);
static const osTimerAttr_t init_timer_attrs = {
.name = "ZephyrTimer",
.attr_bits = 0,
.cb_mem = NULL,
.cb_size = 0,
};
static void zephyr_timer_wrapper(struct k_timer *timer)
{
struct cv2_timer *cm_timer;
cm_timer = CONTAINER_OF(timer, struct cv2_timer, z_timer);
(cm_timer->callback_function)(cm_timer->arg);
}
/**
* @brief Create a Timer
*/
osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type,
void *argument, const osTimerAttr_t *attr)
{
struct cv2_timer *timer;
if (type != osTimerOnce && type != osTimerPeriodic) {
return NULL;
}
if (k_is_in_isr()) {
return NULL;
}
if (attr == NULL) {
attr = &init_timer_attrs;
}
if (k_mem_slab_alloc(&cv2_timer_slab, (void **)&timer, K_MSEC(100)) == 0) {
(void)memset(timer, 0, sizeof(struct cv2_timer));
} else {
return NULL;
}
timer->callback_function = func;
timer->arg = argument;
timer->type = type;
timer->status = NOT_ACTIVE;
k_timer_init(&timer->z_timer, zephyr_timer_wrapper, NULL);
if (attr->name == NULL) {
strncpy(timer->name, init_timer_attrs.name,
sizeof(timer->name) - 1);
} else {
strncpy(timer->name, attr->name, sizeof(timer->name) - 1);
}
return (osTimerId_t)timer;
}
/**
* @brief Start or restart a Timer
*/
osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)
{
struct cv2_timer *timer = (struct cv2_timer *)timer_id;
if (timer == NULL) {
return osErrorParameter;
}
if (k_is_in_isr()) {
return osErrorISR;
}
if (timer->type == osTimerOnce) {
k_timer_start(&timer->z_timer, K_TICKS(ticks), K_NO_WAIT);
} else if (timer->type == osTimerPeriodic) {
k_timer_start(&timer->z_timer,
K_TICKS(ticks), K_TICKS(ticks));
}
timer->status = ACTIVE;
return osOK;
}
/**
* @brief Stop the Timer
*/
osStatus_t osTimerStop(osTimerId_t timer_id)
{
struct cv2_timer *timer = (struct cv2_timer *)timer_id;
if (timer == NULL) {
return osErrorParameter;
}
if (k_is_in_isr()) {
return osErrorISR;
}
if (timer->status == NOT_ACTIVE) {
return osErrorResource;
}
k_timer_stop(&timer->z_timer);
timer->status = NOT_ACTIVE;
return osOK;
}
/**
* @brief Delete the timer that was created by osTimerCreate
*/
osStatus_t osTimerDelete(osTimerId_t timer_id)
{
struct cv2_timer *timer = (struct cv2_timer *) timer_id;
if (timer == NULL) {
return osErrorParameter;
}
if (k_is_in_isr()) {
return osErrorISR;
}
if (timer->status == ACTIVE) {
k_timer_stop(&timer->z_timer);
timer->status = NOT_ACTIVE;
}
k_mem_slab_free(&cv2_timer_slab, (void *)timer);
return osOK;
}
/**
* @brief Get name of a timer.
*/
const char *osTimerGetName(osTimerId_t timer_id)
{
struct cv2_timer *timer = (struct cv2_timer *)timer_id;
if (k_is_in_isr() || (timer == NULL)) {
return NULL;
}
return timer->name;
}
/**
* @brief Check if a timer is running.
*/
uint32_t osTimerIsRunning(osTimerId_t timer_id)
{
struct cv2_timer *timer = (struct cv2_timer *)timer_id;
if (k_is_in_isr() || (timer == NULL)) {
return 0;
}
return !(!(k_timer_remaining_get(&timer->z_timer)));
}