220 lines
4.8 KiB
C
Executable File
220 lines
4.8 KiB
C
Executable File
#include "os/os.h"
|
|
#include "os_util.h"
|
|
#include "timers.h"
|
|
|
|
/* TODO: what block time should be used ? */
|
|
#define OS_TIMER_WAIT_FOREVER portMAX_DELAY
|
|
#define OS_TIMER_WAIT_NONE 0
|
|
|
|
/* Timer private data definition */
|
|
typedef struct OS_TimerPriv
|
|
{
|
|
TimerHandle_t handle; /* Timer handle */
|
|
os_timer_cb_fn callback; /* Timer expire callback function */
|
|
void *argument; /* Argument of timer expire callback function */
|
|
} OS_TimerPriv_t;
|
|
|
|
static void _os_timer_cb(TimerHandle_t xTimer)
|
|
{
|
|
OS_TimerPriv_t *priv;
|
|
|
|
priv = pvTimerGetTimerID(xTimer);
|
|
if (priv && priv->callback)
|
|
{
|
|
priv->callback(priv->argument);
|
|
}
|
|
else
|
|
{
|
|
OS_WRN("Invalid timer callback\n");
|
|
}
|
|
}
|
|
|
|
os_state os_timer_create(os_timer_t *timer, os_timer_cb_fn cb, void *arg)
|
|
{
|
|
OS_TimerPriv_t *priv;
|
|
|
|
OS_ASS_HDL(!os_timer_is_valid(timer), timer->handle);
|
|
|
|
priv = os_malloc(sizeof(OS_TimerPriv_t));
|
|
if (priv == NULL)
|
|
{
|
|
return OS_E_NOMEM;
|
|
}
|
|
|
|
priv->callback = cb;
|
|
priv->argument = arg;
|
|
priv->handle = xTimerCreate("",
|
|
os_calc_msec_to_ticks(OS_WAIT_FOREVER),
|
|
pdFALSE,
|
|
priv,
|
|
_os_timer_cb);
|
|
if (priv->handle == NULL)
|
|
{
|
|
OS_ERR("err %p\r\n", priv->handle);
|
|
os_free(priv);
|
|
return OS_FAIL;
|
|
}
|
|
timer->handle = priv;
|
|
return OS_OK;
|
|
}
|
|
|
|
static TimerHandle_t _os_timer_get_handle(os_timer_t *timer)
|
|
{
|
|
OS_TimerPriv_t *priv = timer->handle;
|
|
return priv->handle;
|
|
}
|
|
|
|
os_state os_timer_delete(os_timer_t *timer)
|
|
{
|
|
TimerHandle_t handle;
|
|
int ret;
|
|
|
|
OS_ASS_HDL(os_timer_is_valid(timer), timer->handle);
|
|
|
|
handle = _os_timer_get_handle(timer);
|
|
ret = xTimerDelete(handle, OS_TIMER_WAIT_FOREVER);
|
|
if (ret != pdPASS)
|
|
{
|
|
OS_ERR("err %d\r\n", ret);
|
|
return OS_FAIL;
|
|
}
|
|
|
|
OS_TimerPriv_t *priv = timer->handle;
|
|
timer->handle = NULL;
|
|
|
|
os_free(priv);
|
|
|
|
return OS_OK;
|
|
}
|
|
|
|
os_state os_timer_start(os_timer_t *timer)
|
|
{
|
|
TimerHandle_t handle;
|
|
int ret;
|
|
BaseType_t taskWoken;
|
|
|
|
OS_ASS_HDL(os_timer_is_valid(timer), timer->handle);
|
|
|
|
handle = _os_timer_get_handle(timer);
|
|
|
|
if (os_is_isr_context())
|
|
{
|
|
taskWoken = pdFALSE;
|
|
ret = xTimerStartFromISR(handle, &taskWoken);
|
|
if (ret != pdPASS)
|
|
{
|
|
OS_ERR("err %d\r\n", ret);
|
|
return OS_FAIL;
|
|
}
|
|
portYIELD_FROM_ISR(taskWoken);
|
|
}
|
|
else
|
|
{
|
|
ret = xTimerStart(handle, OS_TIMER_WAIT_NONE);
|
|
if (ret != pdPASS)
|
|
{
|
|
OS_ERR("err %d\r\n", ret);
|
|
return OS_FAIL;
|
|
}
|
|
}
|
|
|
|
return OS_OK;
|
|
}
|
|
|
|
os_state os_timer_set_period(os_timer_t *timer, os_timer_type_t type, os_time_t period_ms)
|
|
{
|
|
TimerHandle_t handle;
|
|
TickType_t ticks;
|
|
int ret;
|
|
|
|
OS_ASS_HDL(os_timer_is_valid(timer), timer->handle);
|
|
|
|
handle = _os_timer_get_handle(timer);
|
|
ticks = os_calc_msec_to_ticks(period_ms);
|
|
|
|
if (os_is_isr_context())
|
|
{
|
|
BaseType_t taskWoken = pdFALSE;
|
|
ret = xTimerChangePeriodFromISR(handle, ticks, &taskWoken);
|
|
if (ret != pdPASS)
|
|
{
|
|
OS_ERR("err %d\r\n", ret);
|
|
return OS_FAIL;
|
|
}
|
|
portYIELD_FROM_ISR(taskWoken);
|
|
}
|
|
else
|
|
{
|
|
ret = xTimerChangePeriod(handle, ticks, OS_TIMER_WAIT_NONE);
|
|
if (ret != pdPASS)
|
|
{
|
|
OS_ERR("err %d\r\n", ret);
|
|
return OS_FAIL;
|
|
}
|
|
}
|
|
|
|
vTimerSetReloadMode(handle, type == OS_TIMER_PERIODIC ? pdTRUE : pdFALSE);
|
|
|
|
return OS_OK;
|
|
}
|
|
|
|
os_state os_timer_stop(os_timer_t *timer)
|
|
{
|
|
TimerHandle_t handle;
|
|
int ret;
|
|
BaseType_t taskWoken;
|
|
|
|
OS_ASS_HDL(os_timer_is_valid(timer), timer->handle);
|
|
|
|
handle = _os_timer_get_handle(timer);
|
|
|
|
if (os_is_isr_context())
|
|
{
|
|
taskWoken = pdFALSE;
|
|
ret = xTimerStopFromISR(handle, &taskWoken);
|
|
if (ret != pdPASS)
|
|
{
|
|
OS_ERR("err %d\r\n", ret);
|
|
return OS_FAIL;
|
|
}
|
|
portYIELD_FROM_ISR(taskWoken);
|
|
}
|
|
else
|
|
{
|
|
ret = xTimerStop(handle, OS_TIMER_WAIT_FOREVER);
|
|
if (ret != pdPASS)
|
|
{
|
|
OS_ERR("err %d\r\n", ret);
|
|
return OS_FAIL;
|
|
}
|
|
}
|
|
|
|
return OS_OK;
|
|
}
|
|
|
|
bool os_timer_is_pending(os_timer_t *timer)
|
|
{
|
|
TimerHandle_t handle;
|
|
|
|
if (!os_timer_is_valid(timer))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
handle = _os_timer_get_handle(timer);
|
|
|
|
return (xTimerIsTimerActive(handle) != pdFALSE);
|
|
}
|
|
|
|
bool os_timer_is_valid(os_timer_t *timer)
|
|
{
|
|
if (timer && timer->handle)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|