mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-09-03 13:41:58 +00:00
Simplifies the nanokernel timer API so that the timeout parameter must be specified when invoking nano_isr_timer_test(), nano_fiber_timer_test(), nano_task_timer_test() and nano_timer_test(). This obsoletes the following APIs: nano_fiber_timer_wait() nano_task_timer_wait() nano_timer_wait() Note that even the though the new API requires that the timeout parameter be specified, there are currentl only two acceptable values: TICKS_NONE and TICKS_UNLIMITED Theoretically, the current implementation would allow one to supply a finite positive value for the timeout and the system would wait up to that many ticks for the timer to expire. However, it is thought that that unnecessarily complicates the nanokernel timer model and so it is left as an unsupported option. Should that change, then that feature could be enabled by updating the documentation. Change-Id: I8835c5342ab5025d6f70fdfbed54a50add7568d7 Signed-off-by: Peter Mitsis <peter.mitsis@windriver.com>
160 lines
3.6 KiB
C
160 lines
3.6 KiB
C
/* nano_timer.c - timer for nanokernel-only systems */
|
|
|
|
/*
|
|
* Copyright (c) 1997-2014 Wind River Systems, Inc.
|
|
*
|
|
* 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
|
|
*
|
|
* http://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.
|
|
*/
|
|
|
|
#include <nano_private.h>
|
|
|
|
struct nano_timer *_nano_timer_list;
|
|
|
|
|
|
void nano_timer_init(struct nano_timer *timer, void *data)
|
|
{
|
|
nano_lifo_init(&timer->lifo);
|
|
timer->userData = data;
|
|
DEBUG_TRACING_OBJ_INIT(struct nano_timer *, timer, _track_list_nano_timer);
|
|
}
|
|
|
|
|
|
FUNC_ALIAS(_timer_start, nano_isr_timer_start, void);
|
|
FUNC_ALIAS(_timer_start, nano_fiber_timer_start, void);
|
|
FUNC_ALIAS(_timer_start, nano_task_timer_start, void);
|
|
FUNC_ALIAS(_timer_start, nano_timer_start, void);
|
|
|
|
/**
|
|
*
|
|
* @brief Start a nanokernel timer (generic implementation)
|
|
*
|
|
* This function starts a previously initialized nanokernel timer object.
|
|
* The timer will expire in <ticks> system clock ticks.
|
|
*
|
|
* @return N/A
|
|
*/
|
|
void _timer_start(struct nano_timer *timer, /* timer to start */
|
|
int ticks /* number of system ticks
|
|
* before expiry
|
|
*/
|
|
)
|
|
{
|
|
unsigned int imask;
|
|
struct nano_timer *cur;
|
|
struct nano_timer *prev = NULL;
|
|
|
|
timer->ticks = ticks;
|
|
|
|
imask = irq_lock();
|
|
|
|
cur = _nano_timer_list;
|
|
|
|
while (cur && (timer->ticks > cur->ticks)) {
|
|
timer->ticks -= cur->ticks;
|
|
prev = cur;
|
|
cur = cur->link;
|
|
}
|
|
|
|
timer->link = cur;
|
|
if (cur != NULL)
|
|
cur->ticks -= timer->ticks;
|
|
|
|
if (prev != NULL)
|
|
prev->link = timer;
|
|
else
|
|
_nano_timer_list = timer;
|
|
|
|
irq_unlock(imask);
|
|
}
|
|
|
|
/**
|
|
* @brief Stop a nanokernel timer (generic implementation)
|
|
*
|
|
* This function stops a previously started nanokernel timer object.
|
|
* @param timer Timer to stop
|
|
* @return N/A
|
|
*/
|
|
static void _timer_stop(struct nano_timer *timer)
|
|
{
|
|
unsigned int imask;
|
|
struct nano_timer *cur;
|
|
struct nano_timer *prev = NULL;
|
|
|
|
imask = irq_lock();
|
|
|
|
cur = _nano_timer_list;
|
|
|
|
/* find prev */
|
|
while (cur && cur != timer) {
|
|
prev = cur;
|
|
cur = cur->link;
|
|
}
|
|
|
|
/* if found it, remove it */
|
|
if (cur) {
|
|
/* if it was first */
|
|
if (prev == NULL) {
|
|
_nano_timer_list = timer->link;
|
|
/* if not last */
|
|
if (_nano_timer_list)
|
|
_nano_timer_list->ticks += timer->ticks;
|
|
} else {
|
|
prev->link = timer->link;
|
|
/* if not last */
|
|
if (prev->link)
|
|
prev->link->ticks += timer->ticks;
|
|
}
|
|
}
|
|
|
|
/* now the timer can't expire since it is removed from the list */
|
|
|
|
irq_unlock(imask);
|
|
}
|
|
|
|
|
|
FUNC_ALIAS(_timer_stop_non_preemptible, nano_isr_timer_stop, void);
|
|
FUNC_ALIAS(_timer_stop_non_preemptible, nano_fiber_timer_stop, void);
|
|
void _timer_stop_non_preemptible(struct nano_timer *timer)
|
|
{
|
|
extern void _lifo_put_non_preemptible(struct nano_lifo *lifo, void *data);
|
|
|
|
_timer_stop(timer);
|
|
|
|
/* if there was a waiter, kick it */
|
|
if (timer->lifo.wait_q.head) {
|
|
_lifo_put_non_preemptible(&timer->lifo, (void *)0);
|
|
}
|
|
}
|
|
|
|
void nano_task_timer_stop(struct nano_timer *timer)
|
|
{
|
|
|
|
_timer_stop(timer);
|
|
|
|
/* if there was a waiter, kick it */
|
|
if (timer->lifo.wait_q.head) {
|
|
nano_task_lifo_put(&timer->lifo, (void *)0);
|
|
}
|
|
}
|
|
|
|
void nano_timer_stop(struct nano_timer *timer)
|
|
{
|
|
static void (*func[3])(struct nano_timer *) = {
|
|
nano_isr_timer_stop,
|
|
nano_fiber_timer_stop,
|
|
nano_task_timer_stop,
|
|
};
|
|
|
|
func[sys_execution_context_type_get()](timer);
|
|
}
|