MTK timer

mtk 中断 MTK平台有个图层的概念。每个层的数据存放在不同的buffer中,这些buffer可以从LCD对应的寄存器中读出。具体的自己去查对应平台的规格书吧。MTK的平台是你在blockwrite中通过STARTLCDTRANSFER打开这个寄存器对应的位,然后硬件把每一层图像中对应的像素点取出,然后通过硬件合成,把合成后的数据通过你在LCD_DATA_ADDR中设置的端口地址找到LCD接口,送入L 阅读详情

MTK timer有很多种,从最低层的KAL(kernel adpat layer)到MMI,都有timer的身影。
第一种timer即KAL timer,KAL timer是非常底层的timer,它的实现是直接封装MTK的RTOS(nuleus)的timer,实现方式是由HISR,从而这种timer具有很高的优先级,也就是说,当这个timer超时时,就会触发一个HISR(高级中断 High Level ISR (Interrupt Service Routine)),这个中断会回调注册的回调函数。所以这种timer 使用时,要比较小心,它的优先级很高,在回调函数运行时,其他事件是得不到处理的。
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);   
功能:设置timer 超时时间;
参数:timer_id 是create返回值;
          handler_func_ptr 是回调函数;
          handler_param_ptr 是回调函数返回的参数(一般回调函数都是这么设置,这样很灵活);
          delay 是超时时间,注意这个参数的单位是ticks 不是ms;
          reschedule_time 表示是否循环使用timer,0表示timer超时一次就停止,1表示自动循环启动timer。

第二种timer是stack timer,这种timer与KAL timer最大的区别是:stack timer 超时后,发送一个超时消息到相应task的消息队列,由task的消息队列来处理这个消息,而不像KAL timer,直接在中断状态回调注册函数。从时间的精确性来说,stack timer 可能没有KAL timer 精确(发送消息,task 切换等都要花费时间),但是 stack 更加的安全(在 task 里处理这个消息),提高并发性(stack timer 到期后只是发送了一个消息,具体并不处理)。当然stack timer 底层具体实现还是依靠KAL timer。有一点需要注意的是,当stack timer 超时后,向消息队列发送了消息,但是这个消息还没有来的处理,这个时候取消了这个timer,需要特别处理,虽然这种情况发生的概率很小。
void stack_init_timer(stack_timer_struct *stack_timer, kal_char *timer_name, module_type module_id);
// stack timer初始化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, kal_uint16 timer_indx, kal_uint32 init_time);
//启动定时期,timer_index timer索引,超时时间。

第三种timer,一般在task要管理一组timer,用stack timer加上event scheduler;
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);
timer超时后,统一处理超时回调函数。也就是说,当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)
{
    /* Try to free TIMERTABLE list exclude g_timer_table */
    //释放g_timer_table的内存
    TIMERTABLE *p;
    TIMERTABLE *pp;
    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;

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

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

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

    /* Create an alignment timer schedule */
    //根据 stack timer 2 ,创建 event scheduler 2(即event_scheduler2_ptr)
    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是用一种链表加上数组的实现的,这样实现其可以省去一些内存的频繁申请和释放。


在MMI层,启动一个timer,最终都会调用到L4StartTimer这个函数。具体来分析一下这个函数:
参数:nTimerId 是要自己定义一个timer id,在 timerEvents.h 里的 MMI_TIMER_IDS 定义,用来区分timer
         TimerExpiry 超时的回调函数;
         funcArg 回调函数回传的参数;
         nTimeDuration 超时时间,单位ms;
         alignment alignment或者non-alignment,在 MTK timer小结2说明过;

static void L4StartTimer(
        unsigned short nTimerId,
        oslTimerFuncPtr TimerExpiry,
        void *funcArg,
        unsigned long nTimeDuration,
        unsigned char alignment)
{
    TIMERTABLE *pTable = NULL;
    U16 i = 0;
    U32 temp;

    if (TimerExpiry == NULL)
    {   /* If TimerExpiry is NULL, we don't start the timer */
        MMI_ASSERT(0);
        return;
    }
    MMI_ASSERT(nTimerId < MAX_TIMERS);
    if (L4TimerUsePreciseTick(nTimerId))
    {
        alignment = TIMER_IS_NO_ALIGNMENT;
    }
    // 把ticks转化为ms
    // mtk底层的timer的单位都是ticks
    if (nTimeDuration == 1000)
    {
        temp = KAL_TICKS_1_SEC - 4;
    }
    else
    {
        temp = (U32)((nTimeDuration / 5) * MMI_TICKS_5_MSEC);
    }

    if (temp == 0)
    {
        /* Cause by by rounding. If expire immediately, MoDIS boot-up failure because MMI keeps running and block NVRAM task */
        temp = (U32)MMI_TICKS_5_MSEC;
    }
    // 取得存放所有MMI timer 的table(上文提到这个table是list + array的组合)
    // 如果只用存数组的话,初始化大小不好确定,而且要array relloc. 如果考虑内存回收还容易引起数组震荡
    // 如果只用list的话,一个timer如果很频繁的话,会不停的malloc 和 free
    pTable = &g_timer_table;
    // 判断timer是否已经满了,如果满了,那么需要在timer table后面增加一个timer node
    if (g_timer_table_used >= g_timer_table_size)
    {
        do
        {
            if (pTable->next == NULL)
            {
                pTable->next = OslMalloc(sizeof(TIMERTABLE));
                memset(pTable->next, 0, sizeof(TIMERTABLE));
                g_timer_table_size += SIMULTANEOUS_TIMER_NUM;
                pTable = pTable->next;
                i = 0;
                break;
            }
            pTable = pTable->next;
        } while (pTable != NULL);
    }
    else
    {
        //寻找空的 timer node
        i = 0;
        do
        {
            if (pTable->tm[i].event_id == NULL)
            {   /* find the empty space */
                break;
            }
            i++;
            if (i >= SIMULTANEOUS_TIMER_NUM)
            {
                pTable = pTable->next;
                i = 0;
            }
        } while (pTable != NULL);

        if (pTable == NULL)
        {
            /* Can't find the empty space in TIMERTABLE list, assert!!! */
            MMI_ASSERT(0);
        }
    }/* if (g_timer_table_used >= g_timer_table_size) */

    // 根据 algigment 属性,分别创建一个 event scheduler timer
    // 把 timer 的信息保存到 timer node 里面
    if (alignment == TIMER_IS_NO_ALIGNMENT)
    {
        /* MSB(Most Significant Bit) is align_timer_mask */
        pTable->tm[i].timer_info = nTimerId | NO_ALIGNMENT_TIMER_MASK;
        pTable->tm[i].event_id = evshed_set_event(
                                    event_scheduler1_ptr,
                                    (kal_timer_func_ptr) L4CallBackTimer,
                                    (void*)&(pTable->tm[i]),
                                    temp);
        pTable->tm[i].arg = funcArg;
        pTable->tm[i].callback_func = TimerExpiry;
        g_timer_table_used++;
    }
    else if (alignment == TIMER_IS_ALIGNMENT)
    {
        /* MSB(Most Significant Bit) is align_timer_mask */
        pTable->tm[i].timer_info = nTimerId | ALIGNMENT_TIMER_MASK;
        pTable->tm[i].event_id = evshed_set_event(
                                    event_scheduler2_ptr,
                                    (kal_timer_func_ptr) L4CallBackTimer,
                                    (void*)&(pTable->tm[i]),
                                    temp);
        pTable->tm[i].arg = funcArg;
        pTable->tm[i].callback_func = TimerExpiry;
        g_timer_table_used++;
    }
}
再说一句timer table,其实也可以用timer pool来实现,把超时或者stop的timer node,放入到free pool中,需要时再拿出来,也可以避免重复的malloc和free。在设置event scheduler timer中,设置了一个回调函数L4CallBackTimer,这个回调函数就是在stack timer超时需要回调的函数。那具体在哪里回调?上文提到,event scheduler依赖于stack timer,当stack timer超时后要向相应的mod发送消息。在初始化L4InitTimer函数中,stack timer初始化(stack_init_timer(&base_timer1, "MMI_Base_Timer1", MOD_MMI))时mod是 MOD_MMI,那么超时后,就会向mmi task发送超时消息。MMI层在MMI_task函数中处理所有的消息,while消息处理中,可以看到:
case MSG_ID_TIMER_EXPIRY:
{
    kal_uint16 msg_len;
    EvshedMMITimerHandler(get_local_para_ptr(Message.oslDataPtr, &msg_len));
}
break;
这个就是处理stack timer地方。也就是stack timer超时后,回回调EvshedMMITimerHandler函数。
void EvshedMMITimerHandler(void *dataPtr)
{
    stack_timer_struct *stack_timer_ptr;
    stack_timer_ptr = (stack_timer_struct*) dataPtr;
    // 判断是哪个 stack timer
    if (stack_timer_ptr == &base_timer1)
    {
        // 这里需要判断 这 stack timer 是否还是有效,也就是否被stop
        // 这种情况出现环境在 MTK timer 小结 1 中介绍过
        // 如果无效,就不要触发这个timer
        if (stack_is_time_out_valid(&base_timer1))
        {
            //调用这个函数,处罚注册的 event scheduler timer
            evshed_timer_handler(event_scheduler1_ptr);
        }
        stack_process_time_out(&base_timer1);
    }
    else if (stack_timer_ptr == &base_timer2)
    {
        if (stack_is_time_out_valid(&base_timer2))
        {
            evshed_timer_handler(event_scheduler2_ptr);
        }
        stack_process_time_out(&base_timer2);
    }
}
这个函数在调用evshed_timer_handler函数是,就会回调由evshed_set_event注册的timer回调函数L4CallBackTimer。
static void L4CallBackTimer(void *p)
{
    // 在evshed_set_event 第三个参数中传得timer noder
    // 这里转换这个指针
    mmi_frm_timer_type *pTimer = (mmi_frm_timer_type *)p;
    // 得到timer id
    U32 nTimerId = pTimer->timer_info & (~NO_ALIGNMENT_TIMER_MASK);
    // 得到回调函数
    oslTimerFuncPtr pTimerExpiry = pTimer->callback_func;
    // 得到回调函数参数
    void * arg = pTimer->arg;
    // timer 个数减少
    g_timer_table_used--;
    // 清空这个 timer node
    memset( pTimer, 0, sizeof(mmi_frm_timer_type));   
    // 回调 timer 的回调函数
    // 注意:现在这个回调函数是在 MMI task环境下执行的
    if (pTimerExpiry)
    {
        pTimerExpiry((void *)arg);
    }
    // 这个的作用是 把 mmi task 外部循环队列的消息 放入到内部消息循环
    // 具体在下次 分析 MMI task 时解释
    // 这里真么做主要是 让消息及时得到处理
    mmi_frm_fetch_msg_from_extQ_to_circularQ();

}
这样整个MMI timer梳理通了,从初始化timer到设置timer到最后的触发timer。还有几个需要注意的地方,上文说到, MMI timer 有两种,其中alignment timer 在手机休眠时会被挂起。具体函数如下:

void mmi_frm_suspend_timers(U32 type)
{
    event_scheduler *ev = NULL;
    // 判断是哪一种 timer,实际中,只使用 alignment
    switch(type)
    {
    case TIMER_IS_NO_ALIGNMENT:

        ev = event_scheduler1_ptr;
        break;
       
    case TIMER_IS_ALIGNMENT:
        ev = event_scheduler2_ptr;
        break;

    default:
        /* undefined type */
        MMI_ASSERT(0);
        break;
    }
    // 挂起所有 alignment timer
    evshed_suspend_all_events(ev);
}
具体调用改函数的地方在 BacklightTimerHdlr 里面,这个函数具体实现以后分析主要作用就是控制屏不背光灯,当屏幕背光灯关闭时,关闭alignment timer.有挂起,就由恢复,函数 mmi_frm_resume_timers 调用地方在 TurnOnBacklight 等几个函数里,具体就不在分析。

MTK开机详解 MTK笔记 L4是MMI/AT和协议栈的适配层。 ATCI是AT命令解析器。 UEM是用于抽象如键盘、LED、通用输入/输出等基本设备,是用户设备模块。 PHB就是电话本。 SMU是安全管理单元(SIM、STK)。 CSM是呼叫服务管理。 RAC是登记访问控制。 SMSAL是SMS应用层。 内核服务包括定时器、任务管理和进程间通信、资源和内存管理、日志和异常处理。 阅读详情

相关推荐

MTK timer 小结 1

MTK timer 有很多种,从最低层的KAL(kernel adpat layer)到MMI,都有timer的身影。 先来看一下KAL的timer KAL timer 是非常底层的timer, 它的实现是直接封装MTK的RTOS(nuleus)的timer,实现方式是由HISR,从而这种timer具有很高的优先级, 也就是说,当这个timer 超时时,就会触发一个HISR(高级中断 High Level ISR (Interrupt Service Routine)),这个中断会回

懒人 7809

MMI_TASK相关

/***************************************************************************** * FUNCTION *  mmi_frm_fetch_msg_from_extQ_to_circularQ * DESCRIPTION *  fetch the message from external queue and put * 

陶野的窝 1283

避坑指南:ArcGIS 做莫兰指数分析,你的‘空间关系概念化’选对了吗?

本文深入解析了ArcGIS中莫兰指数分析的关键参数——'空间关系概念化'的选择策略。通过对比反距离法、固定距离法和K最近邻法的适用场景与影响机制,帮助研究者避免常见误区,提升空间自相关分析的准确性和解释力。特别针对全域莫兰指数和局域莫兰指数的计算差异提供了实用建议。

weixin_30872157的博客 806

MTK(6225)定时器源代分析

MTK(6225)定时器源代分析转载注明出处,版权归作者所有lyzaily@126.comyanzhong.lee http://blog.163.com/lyzaily@126/blog/static/424388372009290535834/ 最近在网上看了一些MTK定时器的有关博文,但是没有结合源代分析所以一下子可能看的不是太明白,我现在结合MTK6225源代码进行简单的说明,以便于大家交流!(一)首先我想给出几个有关定时器的重要全局变量:1:static TIMERTABLE g_timer_

liuqg的专栏 987

Hifiasm参数调优实战:当N50不理想时的7个排查方向与解决方案

本文详细解析了Hifiasm参数调优实战,针对基因组组装中N50不理想的7个排查方向与解决方案。通过调整--hom-cov、-D、-N等核心参数,结合HiFi数据和参考基因组分析,有效提升组装质量。文章以猪毛菜基因组为例,展示了从2.1MB到4.3MB的N50优化过程,为生物信息学研究者提供实用指南。

weixin_30642561的博客 426

Overleaf+EndNote+BibTeX:手把手搞定Elsevier期刊投稿的参考文献格式(避坑指南)

本文详细介绍了如何利用Overleaf、EndNote和BibTeX三大工具无缝协作,解决Elsevier期刊投稿中的参考文献格式问题。从工具链配置、文献库导出、BibTeX文件优化到Overleaf集成与编译,提供全流程指南和常见问题解决方案,帮助学术新手高效完成Elsevier期刊投稿。

weixin_30616969的博客 512

(转)MTK 消息分发及窗口管理

一、总体结构 1. Software Architecture MediaTek Inc . (MTK) 2. MMI Architecture MTK 平台采用的是Pixtel Communications,Inc. 的PIXTEL MMI (现已被MTK 收购,作 为MTK 印度研发中心) 。MMI 的基本工作方式是消息驱动,整个MMI 就是一个任务,不 停的从消息队列中取出消息进行处理。...

qq_34810707的博客 902

k-shape时间序列聚类实战:从理论到tslearn实现

本文深入探讨了k-shape时间序列聚类算法,从核心原理到tslearn库的实战应用。k-shape通过标准化互相关系数衡量序列形状相似性,专注于识别波动模式而非绝对数值。文章详细介绍了算法流程、Python环境搭建、数据预处理、最佳K值确定方法,并通过完整代码示例展示了模型训练与结果可视化,帮助读者掌握这一强大的“形状捕手”工具。

weixin_29061465的博客 175

MTK timer 小结 3

在 MTK timer 小结 2 说道最常用的MMI timer 实现机制的初始化过程。今天继续忘下说,下面要说的是创建一个timer。MMI 层,启动一个timer,最终都会调用到 L4StartTimer 这个函数。具体来分析一下这个函数 // 参数 nTimerId 是要自己定义一个timer id,在 timerEvents.h 里的 MMI_TIMER_IDS 定义,用来区分timer // TimerExpiry 超时的回调函数 // funcArg 回调函数回传的参数 // nTim

懒人 5269

中文顶刊《会计研究》文本分析技术最新进展总结盘点

会计研究》是由中华人民共和国财政部主管、中国会计学会主办的国家一级学术期刊,为会计领域中文顶级期刊。随着大数据技术的日益成熟, 社交网络类文本 、上市公司披露类文本、媒体报道类文本、 其他类文本 、网络搜索数据、P2P 网络借贷文 本与分析师报告等文本数据逐渐成为财务会计的研究素材。

qq_52891550的博客 2892

LED单元板驱动(HUB75接口)

开始之前先吐槽一下,搜这个的资料。要么都是Arduino,要么单片机的收费。小小的一个LED单元板,凭什么? 用Arduino是你速度快还是我ST,树莓派不好用?收费更离谱,这点东西还藏私?给你个中指凸。把原理都写出来看你怎么收费。 一、接口定义及原理 如图,有两个RGB通道,共占用6个IO。剩下的ABCDE为地址通道,LAT为行数据锁存通道,CLK为数据时钟,OE为低电平使能LED显示。图片这里没有E,证明它是16扫的,有E就会把B上面的地改为E。这样就是5位,2的5次方32扫。1.

a3748622的博客 3万+

MTK timer 小结 2

在 MTK timer 小结 1 提到了两种timer,KAL timer 和 stack timer, 这两种timer 在平时用的比较少,在驱动开发,或者时间要求特别精确的情况下,使用 KAL timer, 一般在task要管理一组timer,用 stack timer 加上 event scheduler,后者就是今天要介绍的第三种timer。 event scheduler 处理的timer 时间精确性上来说,相对不是那么精确,对于上层app应用来说,是必不可少的。MMI 层的tim

懒人 5858

EU 2021/646 eCall工程拆解:MSD、测试模式与型式核准

紧急呼叫系统(eCall)是车载通信中面向事故救援的安全功能,其原理是在碰撞或人工触发后,通过蜂窝网络向公共安全应答点发送最小数据集(MSD),并建立语音链路。技术价值在于缩短救援响应时间、提升事故后生存率,应用场景覆盖乘用车、轻型商用车及车载T-Box等前装通信模块。面向欧盟市场时,EU 2021/646把eCall从安装要求推进到型式核准测试,关注触发链路、备用电源、GNSS定位、MSD字段、音频质量与回拨能力。工程落地需要围绕测试模式、字段校验、配置管理和送检样件建立可交付合规方案。

weixin_31815843的博客 209

MTK timer 小结 1

MTK timer 有很多种,从最低层的KAL(kernel adpat layer)到MMI,都有timer的身影。 先来看一下KAL的timer KAL timer 是非常底层的timer, 它的实现是直接封装MTK的RTOS(nuleus)的timer,实现方式是由HISR,从而这种timer具有很高的优先级, 也就是说,当这个timer 超时时,就会触发一个HISR(高级...

helpbs 116

uniapp - 微信小程序接入官方人脸识别认证详细流程及示例源码,Uniapp微信小程序项目集成官方提供的人脸识别身份验证插件接口(多种示例:人脸核验、身份证件与人脸是否匹配、是否活体、实名认证等)

uni-app微信小程序人脸识别认证,使用uniapp开发微信小程序的人脸采集功能/人脸识别功能,uniapp vue3微信小程序活体人脸识别,Uni-app微信小程序实名认证,uniApp微信小程序人脸认证,UniApp的微信小程序实名认证与人脸识别系统开发,人脸核身微信小程序uni-app接入流程,wx.startFacialRecognitionVerify,uniapp开发微信小程序-人脸采集功能、微信人脸识别实名认证集成指南,识别失败,人脸识别接口怎么调用,前后端完整示例代码demo,人脸检测功能

🏆 前端领域优质创作者 3284

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

MTK timer 小结 4

昨天说到回调函数 L4CallBackTimer。 static void L4CallBackTimer(void *p) { // 在evshed_set_event 第三个参数中传得 timer noder // 这里转换这个指针 mmi_frm_timer_type *pTimer = (mmi_frm_timer_type *)p; // 得到timer id U32 nTimerId = pTimer->timer_info & (~N

懒人 3636

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

MTK timer 小结 3

在 MTK timer 小结 2 说道最常用的MMI timer 实现机制的初始化过程。今天继续忘下说,下面要说的是创建一个timer。MMI 层,启动一个timer,最终都会调用到 L4StartTimer 这个函数。具体来分析一下这个函数// 参数 nTimerId 是要自己定义一个timer id,在 timerEvents.h 里的 MMI_TIMER_IDS 定义,用来区分timer

bravoon的专栏 707

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

MTK Timer

1. GPTI_StartItem 要精准很多,但是只能提供总数不超过32个GPTI,所以使用时需要注意成对申请和释放GPTI,否则可能会出现ASSERT.GPTI用的是GPT timer。这个是用HISR的方式去响应. 2. StartTime S

Sheldon4090's Blog 779

Mtk.Timer

待续...

Dr.Abel的专栏 491

MTK timer 小结

MTK   timer  小结           MTK  tiemr有很多种,从最底层的KAL到MMI,都有timer的身影。 KAL 的 timer          KAL  timer是非常底层的timer,它的实现是直接封装MTK的RTOS(nuleus)的ti

xiaoweiboy的专栏 3865

MTK使用系统timer

//首先,定义自己的Timertypedef struct MyTimerItem{        const int       index;//多个timer时使用,在这个例子里是没有用的    int             delay;//1000相当于1秒    unsigned char   used;//是否被使用,    FuncPtr         timerFunc;//执行

吴遥的专栏 2478
上一篇: MTK MMI event
下一篇: OSI
Jackalfly
博客等级 码龄17年 96粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值