MTK timer 小结 2

本文介绍了MTK平台中第三种timer——Event Scheduler Timer,它在时间精度上不如KAL Timer,但常用于上层应用程序。详细解析了如何创建和设置Event Scheduler Timer,包括new_evshed函数、evshed_set_event函数和evshed_timer_handler的用法。文中还讨论了MTK这套机制的特性,如依赖于Stack Timer和手动调用超时处理函数。最后,通过MMI Timer的实现为例,阐述了无对齐和对齐timer的区别,并提到了MMI内部使用的table结构,该结构结合链表和数组实现,有效减少了内存操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MTK timer 小结 1 提到了两种timer,KAL timer 和 stack timer, 这两种timer 在平时用的比较少,在驱动开发,或者时间要求特别精确的情况下,使用 KAL timer, 一般在task要管理一组timer,用 stack timer 加上 event scheduler,后者就是今天要介绍的第三种timer。

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

extern event_scheduler *new_evshed(void *timer_id,
                                   void (*start_timer)(void *, unsigned int),
                                   void (*stop_timer)(void *),
                                   kal_uint32 fuzz,
                                   malloc_fp_t alloc_fn_p,
                                   free_fp_t free_fn_p,
                                   kal_uint8 max_delay_ticks);

创建一个 event scheduler ,  timer_id 是stack timer 创建的timer id,一般称为base timer,start_timer 启动这个base timer, stop_timer 停止这个base timer,fuzz 校正timer 时间,alloc_fn_p 内存分配函数,free_fn_p 内存释放函数,max_delay_ticks timer 最大可延迟时间,这个表示timer的准确度,这个参数的作用主要是用于节省电池。

extern eventid evshed_set_event(event_scheduler *es,
                                kal_timer_func_ptr event_hf,
                                void *event_hf_param,
                                kal_uint32 elapse_time);

设置一个timer,es 用 new_evshed 创建的,event_hf, timer 超时后的回调函数,event_hf_param 回调函数传入的参数,elapse_time timer的时间。

extern void evshed_timer_handler(event_scheduler *es);

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

MTK 的这套机制让人感觉很别扭,像 evshed_timer_handler 这样的函数都要手动去调用,仔细想想,也只能这么来用,event scheduler 依赖于 stack timer, 而stack timer 又只能往相应的mod 里发送消息,而这个mod的消息处理又是自己手动写的,如果不开放 evshed_timer_handler 这个函数,那么超时了,event scheduler 也不知道。 不过还是别扭阿

下面举了个例子,就上面这么一说,估计也是晕晕的,我当时看了N遍代码,才慢慢明白些,也没有个资料可以参考。

就看MMI timer的实现,平时开发应用的时候,这个是用的最多的。

源文件:MMITimer.c

先来看初始化函数:

void L4InitTimer(void)
{
    
    TIMERTABLE *p;
    TIMERTABLE *pp;

    // 1 释放timer table 内存
    p = g_timer_table.next;
    pp = NULL;
    do
    {
        if (p != NULL)
        {
            pp = p->next;
            OslMfree(p);
        }
        p = pp;
    } while (p != NULL);
    /* reset g_timer_talbe */
    memset(&g_timer_table, 0, sizeof(TIMERTABLE));
    g_timer_table_size = SIMULTANEOUS_TIMER_NUM;
    g_timer_table_used = 0;

    /* Initiate the clock time callback function. */
    get_clocktime_callback_func = NULL;
    set_clocktime_callback_func = NULL;

    //2 初始化 stack timer 1
    /* Initate the no alignment stack timer */
    stack_init_timer(&base_timer1, "MMI_Base_Timer1", MOD_MMI);

    //3 根据 stack timer 1 ,创建 event scheduler 1
    /* Create a no alignment timer schedule */
    event_scheduler1_ptr = new_evshed(
                            &base_timer1,
                            L4StartBaseTimer,
                            L4StopBaseTimer,
                            0,
                            kal_evshed_get_mem,
                            kal_evshed_free_mem,
                            0);

    //4 初始化 stack timer 2
    /* Initate the alignment stack timer */
    stack_init_timer(&base_timer2, "MMI_Base_Timer2", MOD_MMI);

    //5 根据 stack timer 2 创建 event scheduler 2
    /* Create an alignment timer schedule */
    event_scheduler2_ptr = new_evshed(
                            &base_timer2,
                            L4StartBaseTimer,
                            L4StopBaseTimer,
                            0,
                            kal_evshed_get_mem,
                            kal_evshed_free_mem,
                            254);


}

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

两者的区别有两点:

1,前置不会延迟,也就是说相对于后来来说,精确很多,当然后者有可能延迟,也就是用后者创建了一个100ms timer  ,也许过了 150ms 才被回调 ,甚至 300ms。

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

在MMI timer 里面,这两种timer 分别对应  event_scheduler1_ptr 和  event_scheduler2_ptr。

在 MMI 实现timer 里面用了一种 table,用来存放每一个timer的信息,这种table 是一种 链表 加上 数组的实现。

这样实现 可以省去一些内存的频繁申请和释放。

(待续)

MTK PBMTimer(PBM Timer)通常与MediaTek平台上的电源管理或性能管理相关,可能用于控制或监测系统中某些特定模块的功耗或运行状态。虽然在提供的引用内容中没有直接提及 PBMTimer 的具体实现或使用方式,但可以结合MediaTek平台的一般开发和调试方法,推测其可能的用途和实现方式。 在MediaTek平台的系统开发和调试中,定时器(Timer)常用于任务调度、性能监控、功耗管理等场景。PBMTimer可能是用于某种特定的电源管理任务,例如周期性地检查系统负载、控制某些硬件模块的启用或关闭时间、或者用于调试和性能分析的计时机制。 在实现上,定时器通常会依赖于操作系统内核提供的定时机制,例如Linux内核中的`hrtimer`(高分辨率定时器)或`timer_setup`等接口。开发者可以在驱动程序或系统服务中注册定时器回调函数,以执行特定的处理逻辑。例如: ```c #include <linux/timer.h> #include <linux/jiffies.h> static struct timer_list pbm_timer; static void pbm_timer_callback(struct timer_list *t) { // 执行PBM相关的处理逻辑,例如读取功耗数据或调整系统状态 } void init_pbm_timer(void) { timer_setup(&pbm_timer, pbm_timer_callback, 0); pbm_timer.expires = jiffies + msecs_to_jiffies(1000); // 设置1秒后触发 add_timer(&pbm_timer); } ``` 此外,MediaTek平台的调试工具和系统属性设置也可以辅助开发者追踪定时器行为。例如,通过设置特定的调试属性(如`vendor.debug.camera.preview.dump`)来启用日志记录或数据抓取功能[^2],有助于分析定时器的运行状态和触发时机。 在实际开发中,若需进一步了解MTK PBMTimer的具体使用方式或实现细节,建议查阅MediaTek官方提供的SDK文档、内核源码中的相关模块(如`mtk_pbm.c`或类似的文件),或联系技术支持以获取更详细的资料。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值