diff --git a/lib/cmsis_rtos_v1/CMakeLists.txt b/lib/cmsis_rtos_v1/CMakeLists.txt index af5649b5ffb8cd..f24da51bd1f3b8 100644 --- a/lib/cmsis_rtos_v1/CMakeLists.txt +++ b/lib/cmsis_rtos_v1/CMakeLists.txt @@ -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) diff --git a/lib/cmsis_rtos_v1/Kconfig b/lib/cmsis_rtos_v1/Kconfig index b55e7d61fb2a52..26fd43297f27f5 100644 --- a/lib/cmsis_rtos_v1/Kconfig +++ b/lib/cmsis_rtos_v1/Kconfig @@ -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 diff --git a/lib/cmsis_rtos_v1/cmsis_timer.c b/lib/cmsis_rtos_v1/cmsis_timer.c new file mode 100644 index 00000000000000..d6165639b53ff0 --- /dev/null +++ b/lib/cmsis_rtos_v1/cmsis_timer.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#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; +}