Initial commit
This commit is contained in:
631
external/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_timer.c
vendored
Normal file
631
external/CMSIS_5/CMSIS/RTOS2/RTX/Source/rtx_timer.c
vendored
Normal file
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2023 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Project: CMSIS-RTOS RTX
|
||||
* Title: Timer functions
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "rtx_lib.h"
|
||||
|
||||
|
||||
// OS Runtime Object Memory Usage
|
||||
#ifdef RTX_OBJ_MEM_USAGE
|
||||
osRtxObjectMemUsage_t osRtxTimerMemUsage \
|
||||
__attribute__((section(".data.os.timer.obj"))) =
|
||||
{ 0U, 0U, 0U };
|
||||
#endif
|
||||
|
||||
|
||||
// ==== Helper functions ====
|
||||
|
||||
/// Insert Timer into the Timer List sorted by Time.
|
||||
/// \param[in] timer timer object.
|
||||
/// \param[in] tick timer tick.
|
||||
static void TimerInsert (os_timer_t *timer, uint32_t tick) {
|
||||
os_timer_t *prev, *next;
|
||||
|
||||
prev = NULL;
|
||||
next = osRtxInfo.timer.list;
|
||||
while ((next != NULL) && (next->tick <= tick)) {
|
||||
tick -= next->tick;
|
||||
prev = next;
|
||||
next = next->next;
|
||||
}
|
||||
timer->tick = tick;
|
||||
timer->prev = prev;
|
||||
timer->next = next;
|
||||
if (next != NULL) {
|
||||
next->tick -= timer->tick;
|
||||
next->prev = timer;
|
||||
}
|
||||
if (prev != NULL) {
|
||||
prev->next = timer;
|
||||
} else {
|
||||
osRtxInfo.timer.list = timer;
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove Timer from the Timer List.
|
||||
/// \param[in] timer timer object.
|
||||
static void TimerRemove (const os_timer_t *timer) {
|
||||
|
||||
if (timer->next != NULL) {
|
||||
timer->next->tick += timer->tick;
|
||||
timer->next->prev = timer->prev;
|
||||
}
|
||||
if (timer->prev != NULL) {
|
||||
timer->prev->next = timer->next;
|
||||
} else {
|
||||
osRtxInfo.timer.list = timer->next;
|
||||
}
|
||||
}
|
||||
|
||||
/// Unlink Timer from the Timer List Head.
|
||||
/// \param[in] timer timer object.
|
||||
static void TimerUnlink (const os_timer_t *timer) {
|
||||
|
||||
if (timer->next != NULL) {
|
||||
timer->next->prev = timer->prev;
|
||||
}
|
||||
osRtxInfo.timer.list = timer->next;
|
||||
}
|
||||
|
||||
/// Verify that Timer object pointer is valid.
|
||||
/// \param[in] timer timer object.
|
||||
/// \return true - valid, false - invalid.
|
||||
static bool_t IsTimerPtrValid (const os_timer_t *timer) {
|
||||
#ifdef RTX_OBJ_PTR_CHECK
|
||||
//lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
|
||||
uint32_t cb_start = (uint32_t)&__os_timer_cb_start__;
|
||||
uint32_t cb_length = (uint32_t)&__os_timer_cb_length__;
|
||||
|
||||
// Check the section boundaries
|
||||
if (((uint32_t)timer - cb_start) >= cb_length) {
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return FALSE;
|
||||
}
|
||||
// Check the object alignment
|
||||
if ((((uint32_t)timer - cb_start) % sizeof(os_timer_t)) != 0U) {
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return FALSE;
|
||||
}
|
||||
#else
|
||||
// Check NULL pointer
|
||||
if (timer == NULL) {
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
// ==== Library functions ====
|
||||
|
||||
/// Timer Tick (called each SysTick).
|
||||
static void osRtxTimerTick (void) {
|
||||
os_thread_t *thread_running;
|
||||
os_timer_t *timer;
|
||||
osStatus_t status;
|
||||
|
||||
timer = osRtxInfo.timer.list;
|
||||
if (timer == NULL) {
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return;
|
||||
}
|
||||
|
||||
thread_running = osRtxThreadGetRunning();
|
||||
|
||||
timer->tick--;
|
||||
while ((timer != NULL) && (timer->tick == 0U)) {
|
||||
TimerUnlink(timer);
|
||||
status = osMessageQueuePut(osRtxInfo.timer.mq, &timer->finfo, 0U, 0U);
|
||||
if (status != osOK) {
|
||||
const os_thread_t *thread = osRtxThreadGetRunning();
|
||||
osRtxThreadSetRunning(osRtxInfo.thread.run.next);
|
||||
(void)osRtxKernelErrorNotify(osRtxErrorTimerQueueOverflow, timer);
|
||||
if (osRtxThreadGetRunning() == NULL) {
|
||||
if (thread_running == thread) {
|
||||
thread_running = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((timer->attr & osRtxTimerPeriodic) != 0U) {
|
||||
TimerInsert(timer, timer->load);
|
||||
} else {
|
||||
timer->state = osRtxTimerStopped;
|
||||
}
|
||||
timer = osRtxInfo.timer.list;
|
||||
}
|
||||
|
||||
osRtxThreadSetRunning(thread_running);
|
||||
}
|
||||
|
||||
/// Setup Timer Thread objects.
|
||||
//lint -esym(714,osRtxTimerSetup) "Referenced from library configuration"
|
||||
//lint -esym(759,osRtxTimerSetup) "Prototype in header"
|
||||
//lint -esym(765,osRtxTimerSetup) "Global scope"
|
||||
int32_t osRtxTimerSetup (void) {
|
||||
int32_t ret = -1;
|
||||
|
||||
if (osRtxMessageQueueTimerSetup() == 0) {
|
||||
osRtxInfo.timer.tick = osRtxTimerTick;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// Timer Thread
|
||||
//lint -esym(714,osRtxTimerThread) "Referenced from library configuration"
|
||||
//lint -esym(759,osRtxTimerThread) "Prototype in header"
|
||||
//lint -esym(765,osRtxTimerThread) "Global scope"
|
||||
__NO_RETURN void osRtxTimerThread (void *argument) {
|
||||
os_timer_finfo_t finfo;
|
||||
osStatus_t status;
|
||||
osMessageQueueId_t mq = (osMessageQueueId_t)argument;
|
||||
|
||||
for (;;) {
|
||||
//lint -e{934} "Taking address of near auto variable"
|
||||
status = osMessageQueueGet(mq, &finfo, NULL, osWaitForever);
|
||||
if (status == osOK) {
|
||||
EvrRtxTimerCallback(finfo.func, finfo.arg);
|
||||
(finfo.func)(finfo.arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Destroy a Timer object.
|
||||
/// \param[in] timer timer object.
|
||||
static void osRtxTimerDestroy (os_timer_t *timer) {
|
||||
|
||||
// Mark object as inactive and invalid
|
||||
timer->state = osRtxTimerInactive;
|
||||
timer->id = osRtxIdInvalid;
|
||||
|
||||
// Free object memory
|
||||
if ((timer->flags & osRtxFlagSystemObject) != 0U) {
|
||||
#ifdef RTX_OBJ_PTR_CHECK
|
||||
(void)osRtxMemoryPoolFree(osRtxInfo.mpi.timer, timer);
|
||||
#else
|
||||
if (osRtxInfo.mpi.timer != NULL) {
|
||||
(void)osRtxMemoryPoolFree(osRtxInfo.mpi.timer, timer);
|
||||
} else {
|
||||
(void)osRtxMemoryFree(osRtxInfo.mem.common, timer);
|
||||
}
|
||||
#endif
|
||||
#ifdef RTX_OBJ_MEM_USAGE
|
||||
osRtxTimerMemUsage.cnt_free++;
|
||||
#endif
|
||||
}
|
||||
|
||||
EvrRtxTimerDestroyed(timer);
|
||||
}
|
||||
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
/// Delete a Timer safety class.
|
||||
/// \param[in] safety_class safety class.
|
||||
/// \param[in] mode safety mode.
|
||||
void osRtxTimerDeleteClass (uint32_t safety_class, uint32_t mode) {
|
||||
os_timer_t *timer;
|
||||
uint32_t length;
|
||||
|
||||
//lint --e{923} --e{9078} "cast from pointer to unsigned int" [MISRA Note 7]
|
||||
timer = (os_timer_t *)(uint32_t)&__os_timer_cb_start__;
|
||||
length = (uint32_t)&__os_timer_cb_length__;
|
||||
while (length >= sizeof(os_timer_t)) {
|
||||
if ( (timer->id == osRtxIdTimer) &&
|
||||
((((mode & osSafetyWithSameClass) != 0U) &&
|
||||
((timer->attr >> osRtxAttrClass_Pos) == (uint8_t)safety_class)) ||
|
||||
(((mode & osSafetyWithLowerClass) != 0U) &&
|
||||
((timer->attr >> osRtxAttrClass_Pos) < (uint8_t)safety_class)))) {
|
||||
if (timer->state == osRtxTimerRunning) {
|
||||
TimerRemove(timer);
|
||||
}
|
||||
osRtxTimerDestroy(timer);
|
||||
}
|
||||
length -= sizeof(os_timer_t);
|
||||
timer++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// ==== Service Calls ====
|
||||
|
||||
/// Create and Initialize a timer.
|
||||
/// \note API identical to osTimerNew
|
||||
static osTimerId_t svcRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
|
||||
os_timer_t *timer;
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
const os_thread_t *thread = osRtxThreadGetRunning();
|
||||
uint32_t attr_bits;
|
||||
#endif
|
||||
uint8_t flags;
|
||||
const char *name;
|
||||
|
||||
// Check parameters
|
||||
if ((func == NULL) || ((type != osTimerOnce) && (type != osTimerPeriodic))) {
|
||||
EvrRtxTimerError(NULL, (int32_t)osErrorParameter);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Process attributes
|
||||
if (attr != NULL) {
|
||||
name = attr->name;
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
attr_bits = attr->attr_bits;
|
||||
#endif
|
||||
//lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
|
||||
timer = attr->cb_mem;
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
if ((attr_bits & osSafetyClass_Valid) != 0U) {
|
||||
if ((thread != NULL) &&
|
||||
((thread->attr >> osRtxAttrClass_Pos) <
|
||||
(uint8_t)((attr_bits & osSafetyClass_Msk) >> osSafetyClass_Pos))) {
|
||||
EvrRtxTimerError(NULL, (int32_t)osErrorSafetyClass);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (timer != NULL) {
|
||||
if (!IsTimerPtrValid(timer) || (attr->cb_size != sizeof(os_timer_t))) {
|
||||
EvrRtxTimerError(NULL, osRtxErrorInvalidControlBlock);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (attr->cb_size != 0U) {
|
||||
EvrRtxTimerError(NULL, osRtxErrorInvalidControlBlock);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
name = NULL;
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
attr_bits = 0U;
|
||||
#endif
|
||||
timer = NULL;
|
||||
}
|
||||
|
||||
// Allocate object memory if not provided
|
||||
if (timer == NULL) {
|
||||
if (osRtxInfo.mpi.timer != NULL) {
|
||||
//lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
|
||||
timer = osRtxMemoryPoolAlloc(osRtxInfo.mpi.timer);
|
||||
#ifndef RTX_OBJ_PTR_CHECK
|
||||
} else {
|
||||
//lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
|
||||
timer = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_timer_t), 1U);
|
||||
#endif
|
||||
}
|
||||
#ifdef RTX_OBJ_MEM_USAGE
|
||||
if (timer != NULL) {
|
||||
uint32_t used;
|
||||
osRtxTimerMemUsage.cnt_alloc++;
|
||||
used = osRtxTimerMemUsage.cnt_alloc - osRtxTimerMemUsage.cnt_free;
|
||||
if (osRtxTimerMemUsage.max_used < used) {
|
||||
osRtxTimerMemUsage.max_used = used;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
flags = osRtxFlagSystemObject;
|
||||
} else {
|
||||
flags = 0U;
|
||||
}
|
||||
|
||||
if (timer != NULL) {
|
||||
// Initialize control block
|
||||
timer->id = osRtxIdTimer;
|
||||
timer->state = osRtxTimerStopped;
|
||||
timer->flags = flags;
|
||||
if (type == osTimerPeriodic) {
|
||||
timer->attr = osRtxTimerPeriodic;
|
||||
} else {
|
||||
timer->attr = 0U;
|
||||
}
|
||||
timer->name = name;
|
||||
timer->prev = NULL;
|
||||
timer->next = NULL;
|
||||
timer->tick = 0U;
|
||||
timer->load = 0U;
|
||||
timer->finfo.func = func;
|
||||
timer->finfo.arg = argument;
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
if ((attr_bits & osSafetyClass_Valid) != 0U) {
|
||||
timer->attr |= (uint8_t)((attr_bits & osSafetyClass_Msk) >>
|
||||
(osSafetyClass_Pos - osRtxAttrClass_Pos));
|
||||
} else {
|
||||
// Inherit safety class from the running thread
|
||||
if (thread != NULL) {
|
||||
timer->attr |= (uint8_t)(thread->attr & osRtxAttrClass_Msk);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
EvrRtxTimerCreated(timer, timer->name);
|
||||
} else {
|
||||
EvrRtxTimerError(NULL, (int32_t)osErrorNoMemory);
|
||||
}
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
/// Get name of a timer.
|
||||
/// \note API identical to osTimerGetName
|
||||
static const char *svcRtxTimerGetName (osTimerId_t timer_id) {
|
||||
os_timer_t *timer = osRtxTimerId(timer_id);
|
||||
|
||||
// Check parameters
|
||||
if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer)) {
|
||||
EvrRtxTimerGetName(timer, NULL);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EvrRtxTimerGetName(timer, timer->name);
|
||||
|
||||
return timer->name;
|
||||
}
|
||||
|
||||
/// Start or restart a timer.
|
||||
/// \note API identical to osTimerStart
|
||||
static osStatus_t svcRtxTimerStart (osTimerId_t timer_id, uint32_t ticks) {
|
||||
os_timer_t *timer = osRtxTimerId(timer_id);
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
const os_thread_t *thread;
|
||||
#endif
|
||||
|
||||
// Check parameters
|
||||
if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer) || (ticks == 0U)) {
|
||||
EvrRtxTimerError(timer, (int32_t)osErrorParameter);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
// Check running thread safety class
|
||||
thread = osRtxThreadGetRunning();
|
||||
if ((thread != NULL) &&
|
||||
((thread->attr >> osRtxAttrClass_Pos) < (timer->attr >> osRtxAttrClass_Pos))) {
|
||||
EvrRtxTimerError(timer, (int32_t)osErrorSafetyClass);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return osErrorSafetyClass;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (timer->state == osRtxTimerRunning) {
|
||||
timer->load = ticks;
|
||||
TimerRemove(timer);
|
||||
} else {
|
||||
if (osRtxInfo.timer.tick == NULL) {
|
||||
EvrRtxTimerError(timer, (int32_t)osErrorResource);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return osErrorResource;
|
||||
} else {
|
||||
timer->state = osRtxTimerRunning;
|
||||
timer->load = ticks;
|
||||
}
|
||||
}
|
||||
|
||||
TimerInsert(timer, ticks);
|
||||
|
||||
EvrRtxTimerStarted(timer);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/// Stop a timer.
|
||||
/// \note API identical to osTimerStop
|
||||
static osStatus_t svcRtxTimerStop (osTimerId_t timer_id) {
|
||||
os_timer_t *timer = osRtxTimerId(timer_id);
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
const os_thread_t *thread;
|
||||
#endif
|
||||
|
||||
// Check parameters
|
||||
if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer)) {
|
||||
EvrRtxTimerError(timer, (int32_t)osErrorParameter);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
// Check running thread safety class
|
||||
thread = osRtxThreadGetRunning();
|
||||
if ((thread != NULL) &&
|
||||
((thread->attr >> osRtxAttrClass_Pos) < (timer->attr >> osRtxAttrClass_Pos))) {
|
||||
EvrRtxTimerError(timer, (int32_t)osErrorSafetyClass);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return osErrorSafetyClass;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check object state
|
||||
if (timer->state != osRtxTimerRunning) {
|
||||
EvrRtxTimerError(timer, (int32_t)osErrorResource);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return osErrorResource;
|
||||
}
|
||||
|
||||
timer->state = osRtxTimerStopped;
|
||||
|
||||
TimerRemove(timer);
|
||||
|
||||
EvrRtxTimerStopped(timer);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
/// Check if a timer is running.
|
||||
/// \note API identical to osTimerIsRunning
|
||||
static uint32_t svcRtxTimerIsRunning (osTimerId_t timer_id) {
|
||||
os_timer_t *timer = osRtxTimerId(timer_id);
|
||||
uint32_t is_running;
|
||||
|
||||
// Check parameters
|
||||
if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer)) {
|
||||
EvrRtxTimerIsRunning(timer, 0U);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return 0U;
|
||||
}
|
||||
|
||||
if (timer->state == osRtxTimerRunning) {
|
||||
EvrRtxTimerIsRunning(timer, 1U);
|
||||
is_running = 1U;
|
||||
} else {
|
||||
EvrRtxTimerIsRunning(timer, 0U);
|
||||
is_running = 0;
|
||||
}
|
||||
|
||||
return is_running;
|
||||
}
|
||||
|
||||
/// Delete a timer.
|
||||
/// \note API identical to osTimerDelete
|
||||
static osStatus_t svcRtxTimerDelete (osTimerId_t timer_id) {
|
||||
os_timer_t *timer = osRtxTimerId(timer_id);
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
const os_thread_t *thread;
|
||||
#endif
|
||||
|
||||
// Check parameters
|
||||
if (!IsTimerPtrValid(timer) || (timer->id != osRtxIdTimer)) {
|
||||
EvrRtxTimerError(timer, (int32_t)osErrorParameter);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
||||
#ifdef RTX_SAFETY_CLASS
|
||||
// Check running thread safety class
|
||||
thread = osRtxThreadGetRunning();
|
||||
if ((thread != NULL) &&
|
||||
((thread->attr >> osRtxAttrClass_Pos) < (timer->attr >> osRtxAttrClass_Pos))) {
|
||||
EvrRtxTimerError(timer, (int32_t)osErrorSafetyClass);
|
||||
//lint -e{904} "Return statement before end of function" [MISRA Note 1]
|
||||
return osErrorSafetyClass;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (timer->state == osRtxTimerRunning) {
|
||||
TimerRemove(timer);
|
||||
}
|
||||
|
||||
osRtxTimerDestroy(timer);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
||||
// Service Calls definitions
|
||||
//lint ++flb "Library Begin" [MISRA Note 11]
|
||||
SVC0_4(TimerNew, osTimerId_t, osTimerFunc_t, osTimerType_t, void *, const osTimerAttr_t *)
|
||||
SVC0_1(TimerGetName, const char *, osTimerId_t)
|
||||
SVC0_2(TimerStart, osStatus_t, osTimerId_t, uint32_t)
|
||||
SVC0_1(TimerStop, osStatus_t, osTimerId_t)
|
||||
SVC0_1(TimerIsRunning, uint32_t, osTimerId_t)
|
||||
SVC0_1(TimerDelete, osStatus_t, osTimerId_t)
|
||||
//lint --flb "Library End"
|
||||
|
||||
|
||||
// ==== Public API ====
|
||||
|
||||
/// Create and Initialize a timer.
|
||||
osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
|
||||
osTimerId_t timer_id;
|
||||
|
||||
EvrRtxTimerNew(func, type, argument, attr);
|
||||
if (IsException() || IsIrqMasked()) {
|
||||
EvrRtxTimerError(NULL, (int32_t)osErrorISR);
|
||||
timer_id = NULL;
|
||||
} else {
|
||||
timer_id = __svcTimerNew(func, type, argument, attr);
|
||||
}
|
||||
return timer_id;
|
||||
}
|
||||
|
||||
/// Get name of a timer.
|
||||
const char *osTimerGetName (osTimerId_t timer_id) {
|
||||
const char *name;
|
||||
|
||||
if (IsException() || IsIrqMasked()) {
|
||||
name = svcRtxTimerGetName(timer_id);
|
||||
} else {
|
||||
name = __svcTimerGetName(timer_id);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/// Start or restart a timer.
|
||||
osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks) {
|
||||
osStatus_t status;
|
||||
|
||||
EvrRtxTimerStart(timer_id, ticks);
|
||||
if (IsException() || IsIrqMasked()) {
|
||||
EvrRtxTimerError(timer_id, (int32_t)osErrorISR);
|
||||
status = osErrorISR;
|
||||
} else {
|
||||
status = __svcTimerStart(timer_id, ticks);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/// Stop a timer.
|
||||
osStatus_t osTimerStop (osTimerId_t timer_id) {
|
||||
osStatus_t status;
|
||||
|
||||
EvrRtxTimerStop(timer_id);
|
||||
if (IsException() || IsIrqMasked()) {
|
||||
EvrRtxTimerError(timer_id, (int32_t)osErrorISR);
|
||||
status = osErrorISR;
|
||||
} else {
|
||||
status = __svcTimerStop(timer_id);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/// Check if a timer is running.
|
||||
uint32_t osTimerIsRunning (osTimerId_t timer_id) {
|
||||
uint32_t is_running;
|
||||
|
||||
if (IsException() || IsIrqMasked()) {
|
||||
EvrRtxTimerIsRunning(timer_id, 0U);
|
||||
is_running = 0U;
|
||||
} else {
|
||||
is_running = __svcTimerIsRunning(timer_id);
|
||||
}
|
||||
return is_running;
|
||||
}
|
||||
|
||||
/// Delete a timer.
|
||||
osStatus_t osTimerDelete (osTimerId_t timer_id) {
|
||||
osStatus_t status;
|
||||
|
||||
EvrRtxTimerDelete(timer_id);
|
||||
if (IsException() || IsIrqMasked()) {
|
||||
EvrRtxTimerError(timer_id, (int32_t)osErrorISR);
|
||||
status = osErrorISR;
|
||||
} else {
|
||||
status = __svcTimerDelete(timer_id);
|
||||
}
|
||||
return status;
|
||||
}
|
Reference in New Issue
Block a user