关于定时器的内容,其实我们之前也讨论过,也书写过相应的代码,但是表达得比较晦涩,效率也比较低。所以我们这里重新再讲一下定时器的相关代码,看看嵌入式系统中的定时器是怎么实现的。在我们之前讨论线程延时的时候就使用hash的方法,将不同的线程归类到不同的延时队列当中,并且按照时间长短先后排列,这样在最短的时间内就可以寻找到最合适的线程了。本质上,线程延时和定时器的基本原理是一样的。唯一的区别就是,线程延时响应的优先级要高一些,而定时器一般由独立线程完成,rawos也是这么做的。
void timer_task(void *pa) { RAW_U16 position; LIST *timer_head_ptr; LIST *iter; LIST *iter_temp; RAW_TIMER *timer_ptr; timer_sem.count = 0; while (1) { /*timer task will be blocked after call this function*/ raw_semaphore_get(&timer_sem, RAW_WAIT_FOREVER); /*Disable the system schedule we do not need disable interrupt since nothing to do with interrupt*/ raw_disable_sche(); /*calculate which timer_head*/ raw_timer_count++; position = (RAW_U16)(raw_timer_count & (TIMER_HEAD_NUMBERS - 1) ); timer_head_ptr = &timer_head[position]; iter =timer_head_ptr->next; while (RAW_TRUE) { /*if timer exits*/ if (iter !=timer_head_ptr) { /*Must use iter_temp because iter may be remove later.*/ iter_temp = iter->next; timer_ptr = list_entry(iter, RAW_TIMER, timer_list); /*if timeout*/ if (raw_timer_count == timer_ptr->match) { /*remove form timer list*/ timer_list_remove(timer_ptr); /*if timer is reschedulable*/ if (timer_ptr->reschedule_ticks) { /*Sort by remain time*/ timer_ptr->remain = timer_ptr->reschedule_ticks; timer_ptr->match = raw_timer_count + timer_ptr->remain; position = (RAW_U16)(timer_ptr->match & (TIMER_HEAD_NUMBERS - 1)); timer_ptr->to_head = &timer_head[position]; timer_list_priority_insert(&timer_head[position], timer_ptr); } /*Any way both condition need to call registered timer function*/ if (timer_ptr->raw_timeout_function) { timer_ptr->raw_timeout_function(timer_ptr->raw_timeout_param); } iter = iter_temp; } else { break; } } /*exit because timer is not exit*/ else { break; } } raw_enable_sche(); } } |