128 lines
2.8 KiB
C
128 lines
2.8 KiB
C
/*
|
|
* Copyright (c) 2016 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 <kernel.h>
|
|
#include <init.h>
|
|
#include <ksched.h>
|
|
#include <wait_q.h>
|
|
#include <misc/__assert.h>
|
|
#include <misc/util.h>
|
|
|
|
void _legacy_sleep(int32_t ticks)
|
|
{
|
|
__ASSERT(!_is_in_isr(), "");
|
|
__ASSERT(ticks != TICKS_UNLIMITED, "");
|
|
|
|
if (ticks <= 0) {
|
|
k_yield();
|
|
return;
|
|
}
|
|
|
|
int key = irq_lock();
|
|
|
|
_remove_thread_from_ready_q(_current);
|
|
_add_thread_timeout(_current, NULL, ticks);
|
|
|
|
_Swap(key);
|
|
}
|
|
|
|
#if (CONFIG_NUM_DYNAMIC_TIMERS > 0)
|
|
|
|
static struct k_timer dynamic_timers[CONFIG_NUM_DYNAMIC_TIMERS];
|
|
static sys_dlist_t timer_pool;
|
|
|
|
static void timer_sem_give(struct k_timer *timer)
|
|
{
|
|
k_sem_give((ksem_t)timer->_legacy_data);
|
|
}
|
|
|
|
static int init_dyamic_timers(struct device *dev)
|
|
{
|
|
ARG_UNUSED(dev);
|
|
|
|
int i;
|
|
int n_timers = ARRAY_SIZE(dynamic_timers);
|
|
|
|
sys_dlist_init(&timer_pool);
|
|
for (i = 0; i < n_timers; i++) {
|
|
k_timer_init(&dynamic_timers[i], timer_sem_give, NULL);
|
|
sys_dlist_append(&timer_pool,
|
|
&dynamic_timers[i].timeout.node);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
SYS_INIT(init_dyamic_timers, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS);
|
|
|
|
ktimer_t task_timer_alloc(void)
|
|
{
|
|
_sched_lock();
|
|
|
|
/*
|
|
* This conversion works only if timeout member
|
|
* variable is the first in time structure.
|
|
*/
|
|
struct k_timer *timer = (struct k_timer *)sys_dlist_get(&timer_pool);
|
|
|
|
k_sched_unlock();
|
|
return timer;
|
|
}
|
|
|
|
void task_timer_free(ktimer_t timer)
|
|
{
|
|
k_timer_stop(timer);
|
|
_sched_lock();
|
|
sys_dlist_append(&timer_pool, &timer->timeout.node);
|
|
k_sched_unlock();
|
|
}
|
|
|
|
void task_timer_start(ktimer_t timer, int32_t duration,
|
|
int32_t period, ksem_t sema)
|
|
{
|
|
if (duration < 0 || period < 0 || (duration == 0 && period == 0)) {
|
|
k_timer_stop(timer);
|
|
return;
|
|
}
|
|
|
|
timer->_legacy_data = (void *)sema;
|
|
|
|
k_timer_start(timer, _ticks_to_ms(duration), _ticks_to_ms(period));
|
|
}
|
|
|
|
bool _timer_pool_is_empty(void)
|
|
{
|
|
_sched_lock();
|
|
|
|
bool is_empty = sys_dlist_is_empty(&timer_pool);
|
|
|
|
k_sched_unlock();
|
|
return is_empty;
|
|
}
|
|
|
|
#endif /* (CONFIG_NUM_DYNAMIC_TIMERS > 0) */
|
|
|
|
void *nano_timer_test(struct nano_timer *timer, int32_t timeout_in_ticks)
|
|
{
|
|
uint32_t (*test_fn)(struct k_timer *timer);
|
|
|
|
if (timeout_in_ticks == TICKS_NONE) {
|
|
test_fn = k_timer_status_get;
|
|
} else {
|
|
test_fn = k_timer_status_sync;
|
|
}
|
|
return test_fn(timer) ? timer->_legacy_data : NULL;
|
|
}
|