20static ak_timer_t *free_list_timer_pool;
21static uint8_t timer_pool_used;
23static uint32_t timer_counter;
25static list_t timer_list_1;
26static list_t timer_list_2;
28static list_t *
volatile timer_list_ptr;
29static list_t *
volatile overflow_timer_list_ptr;
31static volatile uint32_t next_tick_to_unblock_timer = (uint32_t)
OS_CFG_DELAY_MAX;
36static void timer_pool_init()
40 free_list_timer_pool = (ak_timer_t *)timer_pool;
46 timer_pool[index].next = NULL;
50 timer_pool[index].next = (ak_timer_t *)&timer_pool[index + 1];
60static void init_timer_lists(
void)
65 timer_list_ptr = &timer_list_1;
66 overflow_timer_list_ptr = &timer_list_2;
73static void timer_switch_lists()
76 p_list_temp = timer_list_ptr;
77 timer_list_ptr = overflow_timer_list_ptr;
78 overflow_timer_list_ptr = p_list_temp;
80 if (list_is_empty(timer_list_ptr) == OS_TRUE)
86 next_tick_to_unblock_timer = 0u;
93static void add_timer_to_list(ak_timer_t *p_timer)
95 AKOS_CORE_ENTER_CRITICAL();
98 uint32_t tick_to_trigger = list_item_get_value(&(p_timer->timer_list_item));
99 if (tick_to_trigger < const_tick)
112 AKOS_CORE_EXIT_CRITICAL();
117static void update_next_tick_to_unblock()
121 if (list_is_empty(timer_list_ptr) == OS_TRUE)
127 p_timer = list_get_owner_of_head_item(timer_list_ptr);
128 item_value = list_item_get_value(&(p_timer->timer_list_item));
129 if (item_value < next_tick_to_unblock_timer)
131 next_tick_to_unblock_timer = item_value;
152 core_assert(0,
"OS_ERR_DES_THREAD_ID_INVALID");
158 core_assert(0,
"OS_ERR_CAN_NOT_SET_DES_TO_ITSELF");
164 core_assert(0,
"OS_ERR_TIMER_NOT_ACECPT_ZERO_PERIOD");
168 AKOS_CORE_ENTER_CRITICAL();
171 AKOS_CORE_EXIT_CRITICAL();
172 core_assert(0,
"OS_ERR_TIMER_POOL_IS_FULL");
175 p_timer = free_list_timer_pool;
176 free_list_timer_pool = p_timer->next;
178 AKOS_CORE_EXIT_CRITICAL();
182 p_timer->func_cb = func_cb;
183 p_timer->des_thread_id = des_thread_id;
192 p_timer->period = period;
199 list_item_set_owner(&(p_timer->timer_list_item), (
void *)p_timer);
213 AKOS_CORE_ENTER_CRITICAL();
214 if (timer_pool_used == 0u)
216 AKOS_CORE_EXIT_CRITICAL();
217 core_assert(0,
"OS_ERR_TIMER_POOL_UNDERFLOW");
221 p_timer->next = free_list_timer_pool;
222 free_list_timer_pool = p_timer;
225 if (list_item_get_list_contain(&(p_timer->timer_list_item)) != NULL)
228 AKOS_CORE_EXIT_CRITICAL();
252 static uint32_t last_time = (uint32_t)0U;
254 if (time_now < last_time)
257 timer_switch_lists();
259 if (time_now >= next_tick_to_unblock_timer)
263 if (list_is_empty(timer_list_ptr) == OS_TRUE)
270 p_timer = list_get_owner_of_head_item(timer_list_ptr);
271 item_value = list_item_get_value(&(p_timer->timer_list_item));
272 if (item_value > time_now)
275 next_tick_to_unblock_timer = item_value;
280 if (p_timer->func_cb != NULL)
284 if (p_timer->period != 0)
286 list_item_set_value(&(p_timer->timer_list_item), p_timer->period + time_now);
287 add_timer_to_list(p_timer);
291 update_next_tick_to_unblock();
295 last_time = time_now;
310 list_item_set_value(&(p_timer->timer_list_item), tick_to_wait + time_now);
312 add_timer_to_list(p_timer);
313 update_next_tick_to_unblock();
323 if (list_item_get_list_contain(&(p_timer->timer_list_item)) == NULL)
326 core_assert(0,
"OS_ERR_TIMER_IS_NOT_RUNNING");
331 if (p_timer->period != 0)
333 list_item_set_value(&(p_timer->timer_list_item), p_timer->period + time_now);
334 add_timer_to_list(p_timer);
338 update_next_tick_to_unblock();
#define OS_CFG_TIMER_POOL_SIZE
Kernel control and critical-section API.
Doubly-linked list types and APIs for scheduler internals.
void akos_list_item_init(list_item_t *const p_list_item)
Initialize list item linkage and ownership metadata.
void akos_list_init(list_t *const p_list)
Initialize list metadata and sentinel.
void akos_list_insert(list_t *const p_list, list_item_t *const p_list_item)
Insert item in ascending order by list_item::value.
uint16_t akos_list_remove(list_item_t *const p_list_item)
Remove item from containing list.
Message object and message queue APIs.
void akos_message_free(msg_t *p_msg)
Return message to message pool.
Thread scheduling and thread messaging APIs.
msg_t * akos_thread_wait_for_msg(uint32_t time_out)
Wait for message from current thread queue.
uint8_t akos_thread_get_timer_thread_id(void)
Get the runtime thread ID assigned to the timer thread.
uint32_t akos_thread_get_tick(void)
Get current system tick.
uint8_t akos_thread_get_app_thread_count(void)
Get number of application threads defined via AKOS_THREAD_DEFINE.
void akos_thread_post_msg_pure(uint8_t des_thread_id, int32_t sig)
Post pure signal message to destination thread.
void akos_timer_remove(ak_timer_t *p_timer)
Remove timer from lists and return it to pool.
void akos_timer_processing()
Timer-task processing function.
ak_timer_t * akos_timer_create(timer_id_t id, int32_t sig, timer_cb func_cb, uint8_t des_thread_id, uint32_t period, timer_type_t type)
Create a timer object from timer pool.
void akos_timer_reset(ak_timer_t *p_timer)
Reset a running timer to its next period.
void akos_timer_init(void)
Initialize timer module state.
void akos_timer_start(ak_timer_t *p_timer, uint32_t tick_to_wait)
Start timer with initial delay.
uint8_t timer_id_t
Timer identifier type.
void(* timer_cb)()
Timer callback signature.