求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
嵌入式操作系统内核原理和开发(实时系统中的定时器)
 

作者:feixiaoxing ,发布于2012-11-15,来源:CSDN

 

关于定时器的内容,其实我们之前也讨论过,也书写过相应的代码,但是表达得比较晦涩,效率也比较低。所以我们这里重新再讲一下定时器的相关代码,看看嵌入式系统中的定时器是怎么实现的。在我们之前讨论线程延时的时候就使用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();
 	}
 } 

由于基本原理和之前的线程延时是一样的,所以这里就不重复了。定时器的基本操作其实也不多,主要包括定时器创建、启动定时器、修改定时器、关闭定时器、删除定时器共五个基本函数,大家可以和我一起慢慢看过来。

RAW_U16 raw_timer_create(RAW_TIMER *timer_ptr, RAW_U8  *name_ptr, 
             RAW_VOID  (*expiration_function)(RAW_U32), RAW_U32 expiration_input,
           RAW_U32 initial_ticks, RAW_U32 reschedule_ticks, RAW_U8 auto_activate)
 {
 	#if (RAW_TIMER_FUNCTION_CHECK > 0)
 	if (timer_ptr == 0) {
 		return RAW_NULL_OBJECT;
 	}
 	if (expiration_function == 0) {
 		return RAW_NULL_POINTER;
 	}
 	#endif
 	timer_ptr->name = name_ptr;
 	timer_ptr->raw_timeout_function = expiration_function;
 	timer_ptr->raw_timeout_param = expiration_input;
 	timer_ptr->init_count = initial_ticks;
 	timer_ptr->reschedule_ticks = reschedule_ticks;
 	timer_ptr->remain = 0;
 	timer_ptr->match = 0;
 	timer_ptr->timer_state = TIMER_DEACTIVE;
 	timer_ptr->to_head = 0;
 	
 	list_init(&timer_ptr->timer_list);
 	if (auto_activate) {
 		 raw_timer_activate(timer_ptr);
 	}
 	return RAW_SUCCESS;
 } 

创建定时器的操作很简单,主要是把输入的参数存入到RAW_TIMER结构里面。相关的参数包括名称、函数指针、函数参数、初始tick、循环tick、标志参数。当然,由于定时器分为单次定时和循环定时两种,所以这里会有两个参数,如果不是循环定时器,循环tick参数可以不用配置。

RAW_U16  raw_timer_activate(RAW_TIMER *timer_ptr)
 {
 	RAW_U16 position;
 	RAW_SR_ALLOC();
 
 	#if (RAW_TIMER_FUNCTION_CHECK > 0)
 	
 	if (timer_ptr == 0) {
 		return RAW_NULL_OBJECT;
 	}
 	
 	#endif
 
 	/*Timer state TIMER_ACTIVE TIMER_DELETED is not allowed to delete*/
 	if (timer_ptr->timer_state == TIMER_ACTIVE)
 		return RAW_TIMER_STATE_INVALID;	
 
 	if (timer_ptr->timer_state == TIMER_DELETED)
 		return RAW_TIMER_STATE_INVALID;
 	
 	RAW_CRITICAL_ENTER();
 	timer_ptr->match  = raw_timer_count + timer_ptr->init_count;
 	position   = (RAW_U16)(timer_ptr->match & (TIMER_HEAD_NUMBERS - 1) );
 	/*Sort by remain time*/
 	timer_ptr->remain = timer_ptr->init_count;
 	/*Used by timer delete*/
 	timer_ptr->to_head = &timer_head[position];
 	
 	timer_list_priority_insert(&timer_head[position], timer_ptr);
 	timer_ptr->timer_state = TIMER_ACTIVE;
 
 	RAW_CRITICAL_EXIT();
 	return RAW_SUCCESS;
 }

启动定时器,就是把tick加入到定时器队列当中,看看timer_list_priority_insert这个函数你就明白了。因为整个函数的处理过程涉及到 全局变量timer_head,所以需要在前后面添加中断的处理动作。

RAW_U16 raw_timer_change(RAW_TIMER *timer_ptr, RAW_U32 initial_ticks, RAW_U32  reschedule_ticks)
 {
 	RAW_SR_ALLOC();
 	
 	#if (RAW_TIMER_FUNCTION_CHECK > 0)
 	
 	if (timer_ptr == 0) {
 		return RAW_NULL_OBJECT;
 	}
 	
 	#endif
 	
 	/*Only timer state TIMER_DEACTIVE is not allowed here*/	
 	if (timer_ptr->timer_state != TIMER_DEACTIVE) {
 		return RAW_TIMER_STATE_INVALID;
 	}
 	
 	if (timer_ptr->timer_state == TIMER_DELETED) {
 		return RAW_TIMER_STATE_INVALID;
 	}
 	
 	RAW_CRITICAL_ENTER();
 	timer_ptr->init_count = initial_ticks;
 	timer_ptr->reschedule_ticks = reschedule_ticks;
 	RAW_CRITICAL_EXIT();
 	return RAW_SUCCESS;
 } 

定时器修改函数就是把初始tick和循环tick修改一下,当然如果此时定时器还没有运行,初始tick还有用。但是一旦定时器起作用了,起作用的就只能是循环tick了,这一点大家要好好注意。

RAW_U16 raw_timer_deactivate(RAW_TIMER *timer_ptr)
 {
 	RAW_SR_ALLOC();
 
 	#if (RAW_TIMER_FUNCTION_CHECK > 0)
 	
 	if (timer_ptr == 0) {
 		return RAW_NULL_OBJECT;
 	}
 	
 	#endif
 	
 	/*Timer state TIMER_DEACTIVE  TIMER_DELETED is not allowed to delete*/
 	if (timer_ptr->timer_state == TIMER_DEACTIVE) {
 		return RAW_TIMER_STATE_INVALID;
 	}
 	
 	if (timer_ptr->timer_state == TIMER_DELETED) {
 		return RAW_TIMER_STATE_INVALID;
 
 	}
 	
 	RAW_CRITICAL_ENTER();
 	timer_list_remove(timer_ptr);
 	timer_ptr->timer_state = TIMER_DEACTIVE;
 	RAW_CRITICAL_EXIT();
 	
 	return RAW_SUCCESS;
 
 }

停止定时器,顾名思义就是将定时器从队列中删除,同时设置状态为TIMER_DEACTIVE。当然在进行操作之前需要判断一下当前定时器的属性,如果定时器本身已经删除或者停止,那什么也不用做了。

RAW_U16 raw_timer_delete(RAW_TIMER *timer_ptr)
 {
 	RAW_SR_ALLOC();
 	
 	#if (RAW_TIMER_FUNCTION_CHECK > 0)
 	
 	if (timer_ptr == 0) {
 		return RAW_NULL_OBJECT;
 	}
 	
 	#endif
 	
 	if (timer_ptr->timer_state == TIMER_DELETED) {
 		
 		return RAW_TIMER_STATE_INVALID;
 		
 	}
 	
 	RAW_CRITICAL_ENTER();
 	
 	timer_list_remove(timer_ptr);
 	timer_ptr->timer_state = TIMER_DELETED;
 	
 	RAW_CRITICAL_EXIT();
    
 	return RAW_SUCCESS;
 
 } 

定时器的删除函数和定时器的停止函数是一样的,主要是判断逻辑不一样的。删除定时器,只要定时器的状态不是已经删除就可以了,其他的操作都是一样的。


 
分享到
 
 


基于模型的整车电子电气架构设计
嵌入式设备上的 Linux 系统开发
Linux 的并发可管理工作队列
ARM嵌入式系统的问题总结分析
嵌入式系统设计与实例开发
WinCE6.0的EBOOT概要
更多...   


UML +RoseRealtime+嵌入式
C++嵌入式系统开发
嵌入式白盒测试
手机软件测试
嵌入式软件测试
嵌入式操作系统VxWorks


中国航空 嵌入式C高质量编程
使用EA和UML进行嵌入式系统分析设计
基于SysML和EA的嵌入式系统建模
上海汽车 嵌入式软件架构设计
北京 嵌入式C高质量编程
北京 高质高效嵌入式开发
Nagra linux内核与设备驱动原理
更多...