/* * 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 #include #include #include #include #include void _legacy_sleep(int32_t ticks) { __ASSERT(!_is_in_isr(), ""); __ASSERT(ticks != TICKS_UNLIMITED, ""); if (ticks <= 0) { k_yield(); return; } int key = irq_lock(); _mark_thread_as_timing(_current); _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, PRIMARY, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS); ktimer_t task_timer_alloc(void) { k_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); k_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) { k_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; }