现在的位置: 首页 > 综合 > 正文

MTK定时器消息机制分析

2013年01月13日 ⁄ 综合 ⁄ 共 3671字 ⁄ 字号 评论关闭

MTK中有两种timerKAL timer stack timer. 一般在task要管理一组timer,用 stack timer 加上 event scheduler.现在主要介绍这种

KAL timer 是非常底层的timer 它的实现是直接封装MTKRTOS(nuleus)timer,实现方式是由HISR,从而这种timer具有很高的优先级,当这个timer 超时时,就会触发一个HISR(高级中断 High Level ISR (Interrupt Service Routine)),这个中断会回调注册的回调函数。

kal_timerid kal_create_timer(kal_char* timer_name_ptr);         //创建一个timer 参数是timer的名字

void kal_set_timer(kal_timerid timer_id,                                       //

kal_timer_func_ptr handler_func_ptr,      //是回调函数

void* handler_param_ptr,                                     //是回调函数返回的参数

                   kal_uint32 delay,                                          //是超时时间

kal_uint32 reschedule_time);                  //表示是否循环使用timer0 表示 timer 超时一次就停止,1 表示自动循环启动timer

stack timer KAL timer 最大的区别是:stack timer 超时后,发送一个超时消息到 相应task的消息队列,由task的消息队列来处理这个消息,而不像KAL timer,直接在中断状态回调注册函数。从时间的精确性来说,stack timer 可能没有KAL timer 精确(发送消息,task 切换等都要花费时间),但是 stack 更加的安全( task 里处理这个消息),提高并发性(stack timer 到期后只是发送了一个消息,具体并不处理)。当然 stack timer 底层具体实现还是依靠KAL timer

 

1. 常用函数

//函数作用:初始化定时器

void stack_init_timer(stack_timer_struct *stack_timer, //此为stack_timer_struct结构体指针

kal_char *timer_name,    //名称,自己取

module_type module_id);         //是要接受消息的 mdoule,也就是当stack timer 超时,会向该model 发送消息。

//函数作用:判断这个消息是否继续有效,也就是是否需要处理

kal_bool stack_is_time_out_valid(stack_timer_struct *stack_timer);

//函数作用:这个函数与上面的函数成对使用

void stack_process_time_out(stack_timer_struct *stack_timer);

///函数作用:启动定时期

void stack_start_timer(stack_timer_struct *stack_timer,       //此为stack_timer_struct结构体指针

kal_uint16 timer_indx,                   // timer 索引

kal_uint32 init_time);                     // 超时时间

 

event scheduler 处理的timer 时间精确性上来说,相对不是那么精确,对于上层app应用来说,是必不可少的。MMI 层的timer(StartTimer 系列函数) 就是用event scheduler + stack timer 来实现的。

//函数作用:创建一个 event scheduler

extern event_scheduler *new_evshed(void *timer_id,  //对应stack_init_timer函数中的struct_timer指针

                                  void (*start_timer)(void *, unsigned int), //启动这个base timer

                                  void (*stop_timer)(void *),      //停止这个base timer

                                  kal_uint32 fuzz,                       //校正timer 时间

                                  malloc_fp_t alloc_fn_p,        //内存分配函数

                                  free_fp_t free_fn_p,               //内存释放函数

                                  kal_uint8 max_delay_ticks);  //最大可延迟时间,这个表示timer的准确度

//函数作用:设置一个timer

extern eventid evshed_set_event(event_scheduler *es,           // new_evshed 创建的

                              kal_timer_func_ptr event_hf, // timer 超时后的回调函数

                              void *event_hf_param,                   //回调函数传入的参数

                              kal_uint32 elapse_time);       // timer的时间。

 

//函数作用: 时间超时后,统一处理超时回调函数。也就是说,当stack timer 相应的mod 发送 MSG_ID_TIMER_EXPIRY后,需要调用该函数,该函数会处理相应的回调函数。

extern void evshed_timer_handler(event_scheduler *es);

 

2.   数据结构
     (1). stack_timer_struct 
         //定时器类型的信息结构( 其主要作用似乎是用以装载待发送的定时器消息数据 )

(2). mmi_frm_timer_type   //定时器信息结构 。如下图:
     (
3). TIMERTABLE                  //TIMERTABLE 是一种 链表 加上 数组的实现。具体结构如下:
 
         
定时器队列节点结构( 其由主要元素mmi_frm_timer_type结构及链表指针两个元素组成 )
     (3). event_scheduler
         
队列信息结构,是一个双向循环链表
   
3.   L4定时器初始化
     (1).
步骤
         
 创建MMI Task -> 设置MMI Task初始化函数 -> 在该函数中调用 L4InitTimer
     (2).
作用:初始化定时器队列并设置基本定时器1,2 
4.   发送定时器消息
     (1).
步骤     

StartTimer -> L4StartTimer
      (2). MTK
中有两种类型的定时器说明

     *说明:MMI 共有两种timer,一种是 no alignment timer ,一种叫 alignment timer

         *两者的区别有两点:

         *1,前置不会延迟,非队列式的,即要求立即执行的定时器,时间到了就自动被reset.
.也就是说相对于后来来说,精确很多,当然后者有可能延迟,也就是用后者创建了一个100ms timer  ,也许过了 150ms 才被回调

         *2,前置在手机休眠时不会被关起,二后会被挂起,也就是如果用后者创建了一个timer,还没有到期,这个时候手机休眠了,那么这个timer就不会被触发了,知道手机再次唤醒。

         *MMI timer 里面,这两种timer 分别对应  event_scheduler1_ptr   event_scheduler2_ptr

         *3 .除了触摸屏和手写,其他情况下的定时器一般都是队列式的.   

5. 定时器消息的处理

(1)MMI MMI_task 函数中处理所有的消息,while 消息处理中,可以看到

case MSG_ID_TIMER_EXPIRY:

{

               kal_uint16 msg_len;

               

抱歉!评论已关闭.