Skip to content

Commit

Permalink
lib/cmsis_rtos_v1: Implement support for timer APIs
Browse files Browse the repository at this point in the history
These APIs provide the support of virtual timers. All timers
can be started, restarted, or stopped. Timers can be configured
as one-shot or periodic.

Signed-off-by: Rajavardhan Gundi <rajavardhan.gundi@intel.com>
  • Loading branch information
rgundi authored and nashif committed Aug 13, 2018
1 parent b2b5319 commit 7d3a539
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/cmsis_rtos_v1/CMakeLists.txt
Expand Up @@ -9,6 +9,7 @@ zephyr_library_sources_ifdef(
cmsis_thread.c
cmsis_wait.c
cmsis_kernel.c
cmsis_timer.c
)

zephyr_library_link_libraries(CMSIS)
Expand Down
8 changes: 8 additions & 0 deletions lib/cmsis_rtos_v1/Kconfig
Expand Up @@ -30,6 +30,14 @@ config CMSIS_THREAD_MAX_STACK_SIZE
help
Mention max stack size threads can be allocated in CMSIS RTOS application.

config CMSIS_TIMER_MAX_COUNT
int
prompt "Maximum timer count in CMSIS application"
default 5
range 0 255
help
Mention maximum number of timers in CMSIS compliant application.

config NUM_PREEMPT_PRIORITIES
int
default 7
Expand Down
137 changes: 137 additions & 0 deletions lib/cmsis_rtos_v1/cmsis_timer.c
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2018 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <kernel_structs.h>
#include <cmsis_os.h>

#define ACTIVE 1
#define NOT_ACTIVE 0

static void zephyr_timer_wrapper(struct k_timer *timer);

struct timer_obj {
struct k_timer ztimer;
os_timer_type type;
u32_t status;
void (*callback_function)(void const *argument);
void *arg;
};

K_MEM_SLAB_DEFINE(cmsis_timer_slab, sizeof(struct timer_obj),
CONFIG_CMSIS_TIMER_MAX_COUNT, 4);

static void zephyr_timer_wrapper(struct k_timer *timer)
{
struct timer_obj *cm_timer;

cm_timer = CONTAINER_OF(timer, struct timer_obj, ztimer);
(cm_timer->callback_function)(cm_timer->arg);
}

/**
* @brief Create a Timer
*/
osTimerId osTimerCreate(const osTimerDef_t *timer_def, os_timer_type type,
void *argument)
{
struct timer_obj *timer;

if (timer_def == NULL) {
return NULL;
}

if (type != osTimerOnce && type != osTimerPeriodic) {
return NULL;
}

if (k_mem_slab_alloc(&cmsis_timer_slab, (void **)&timer, 100) == 0) {
memset(timer, 0, sizeof(struct timer_obj));
} else {
return NULL;
}

timer->callback_function = timer_def->ptimer;
timer->arg = argument;
timer->type = type;
timer->status = NOT_ACTIVE;

k_timer_init(&timer->ztimer, zephyr_timer_wrapper, NULL);

return (osTimerId)timer;
}

/**
* @brief Start or restart a Timer
*/
osStatus osTimerStart(osTimerId timer_id, uint32_t millisec)
{
struct timer_obj *timer = (struct timer_obj *) timer_id;

if (timer == NULL) {
return osErrorParameter;
}

if (_is_in_isr()) {
return osErrorISR;
}

if (timer->type == osTimerOnce) {
k_timer_start(&timer->ztimer, millisec, 0);
} else if (timer->type == osTimerPeriodic) {
k_timer_start(&timer->ztimer, 0, millisec);
}

timer->status = ACTIVE;
return osOK;
}

/**
* @brief Stop the Timer
*/
osStatus osTimerStop(osTimerId timer_id)
{
struct timer_obj *timer = (struct timer_obj *) timer_id;

if (timer == NULL) {
return osErrorParameter;
}

if (_is_in_isr()) {
return osErrorISR;
}

if (timer->status == NOT_ACTIVE) {
return osErrorResource;
}

k_timer_stop(&timer->ztimer);
timer->status = NOT_ACTIVE;
return osOK;
}

/**
* @brief Delete the timer that was created by osTimerCreate
*/
osStatus osTimerDelete(osTimerId timer_id)
{
struct timer_obj *timer = (struct timer_obj *) timer_id;

if (timer == NULL) {
return osErrorParameter;
}

if (_is_in_isr()) {
return osErrorISR;
}

if (timer->status == ACTIVE) {
k_timer_stop(&timer->ztimer);
timer->status = NOT_ACTIVE;
}

k_mem_slab_free(&cmsis_timer_slab, (void *) &timer);
return osOK;
}

0 comments on commit 7d3a539

Please sign in to comment.