MTK task 小结 1

来源:互联网 发布:ntfs for mac 10.7 编辑:程序博客网 时间:2024/05/16 08:05

MTK 的 基本执行单元是task,

从操作系统的角度来理解,task 有些像线程而不是进程,进程之间的地址空间是相互隔离的,说白点就是进程之间的全局变量是不相互干扰的,

而线程之间则是用同一个地址空间,MTK 的task 之间的地址空间也是共同的,也就是在MTK 编程里,定义了一个全局变量,那么在任何一个task里面都能引用,

(这里举个例子,在实际编程过程中最好不要用全局变量,实在没有办法避开,那么全局变量也要分模块化,进行封装,  扯远了)。

所以说,MTK 的task 更像线程,

MTK 用的是实时操作系统 nucleus,是非抢占式操作系统,也就是当高优先级的task 在运行时,底优先级的task是得不到运行时间的,除非等高优先级的task 因为种种原因挂起。

MTK 还有一个跟task 想关的概念 叫 module,它跟task 之间的关系是:一个task 可以对应多个module。task 主要表示是一个执行单元,module 主要是用于传递消息,在MTK 中,消息传递是module 为单位 src_mod – > des_mod,而不是以task为单位。

虽然MTK手机,是feature phone(功能机),不像symbian 6 那样可以同时运行多个应用。但是MTK还是 有许多task组成。平时MTK的后台播放MP3就是一由一个task 完成的。具体以后分析。现在来看看MTK 最主要的task,MMI task,MTK 的应用程序都是在该task里面运行,它有一整套开发MTK 应用的framework。

先来看创建MMI task的函数

kal_bool mmi_create(comptask_handler_struct **handle) {     /*----------------------------------------------------------------*/     /* Local Variables                                                */     /*----------------------------------------------------------------*/      static comptask_handler_struct mmi_handler_info =      {         MMI_task,   /* task entry function */         MMI_Init,   /* task initialization function */         NULL,         NULL,       /* task reset handler */         NULL,       /* task termination handler */     };      /*----------------------------------------------------------------*/     /* Code Body                                                      */     /*----------------------------------------------------------------*/     *handle = &mmi_handler_info;     return KAL_TRUE; }

这个函数的结构,是MTK 创建task的基本结构,系统初始化时,会调用该函数。看里面的结构体

typedef struct {    kal_task_func_ptr    comp_entry_func;  //task 的入口函数    task_init_func_ptr   comp_init_func;   //task 的初始化函数    task_cfg_func_ptr    comp_cfg_func;    //task 的配置函数    task_reset_func_ptr  comp_reset_func;  //task 的重置函数    task_end_func_ptr    comp_end_func;    //task 的终止函数 } comptask_handler_struct;

task 的入口函数是必须的,这个函数告诉系统,初始化完相应的task 控制块后,就要进入该函数来运行。

task 初始化函数,是在进入 task 入口函数之前被调用,用来初始化可能需要的资源,可选。

task 终止函数是,当task 结束是要调用,用来释放资源,可选。

其他两个函数我也不清楚干什么,希望知道的共享下 

先看MMI task 的初始化函数.

MMI_BOOL MMI_Init(task_indx_type task_indx) {        //创建一个mutex(互斥体)     mmi_mutex_trace = kal_create_mutex("mmi_trace");     //这个是初始化 2step 按键, 2step 按键是指 有一些按键具有半按下状态     //比如照相功能,按下一半进行聚焦,再按下一半拍照      mmi_frm_get_2step_keys();           //初始化timer,具体可以看 MTK timer 小结 系列     L4InitTimer();          //初始化 UI 相关信息,里面有许多画点,图等函数     setup_UI_wrappers();      return MMI_TRUE; }

初始化函数比较简单。

下面来看MMI 的入口函数,这个函数是整个MMI 运行的核心。

//为了简单,删除了大部分宏控制程序 void MMI_task(oslEntryType *entry_param) {      MYQUEUE Message;     oslMsgqid qid;      U32 my_index;     U32 count = 0;     U32 queue_node_number = 0;       // 获得task的外部消息队列id,通过这个id,获得别的task 往MMI task发送的消息     // MMI task 有两个消息,外部消息队列和内部消息队列     // 外部消息队列的消息不直接处理,只是简单的存放到内部消息队列,     // 这样使内部消息队列的优先级稍微高一点     qid = task_info_g[entry_param->task_indx].task_ext_qid;     mmi_ext_qid = qid;     // 初始化 event 处理函数,这个几个event 必须在获得消息前就进行注册     // 不让可能使得这个event 丢弃。具体event 事件,下次介绍     InitEventHandlersBeforePowerOn();      //进入task 的while 循环     // task 的while(1) 循环使得这个task 不会结束,只有挂起或者运行     while (1)     {         {             // 判断是否有 key 事件需要处理             if (g_keypad_flag == MMI_TRUE)             {                 mmi_frm_key_handle(NULL);             }              // 获得外部消息队列里,消息的个数             msg_get_ext_queue_info(mmi_ext_qid, &queue_node_number);              // 如果没有任何消息需要处理(内部消息和外部消息都没有,同时也没有按键需要处理)             // OslNumOfCircularQMsgs 获得内部消息队列消息的个数             if ((queue_node_number == 0) && (OslNumOfCircularQMsgs() == 0) && (g_keypad_flag == MMI_FALSE))             {                 U8 flag = 0;                 ilm_struct ilm_ptr;                 //去外部消息队列里获得消息,这是一个阻塞函数,也就是说,如果外部消息队列里,                 //没有任何消息,那么这个task 将被阻塞,或者说挂起,也就是不在运行,                 //直到有消息到达,才会被唤醒, 看过操作系统原理的,应该不难理解这个意思和这个本质                 OslReceiveMsgExtQ(qid, &Message);                  //如果有消息,获得task 的index                 OslGetMyTaskIndex(&my_index);                 // 设置该task的获得mod 为MMI mod.                  OslStackSetActiveModuleID(my_index, MOD_MMI);                  //保存该消息,用于放入到内部队列                 ilm_ptr.src_mod_id = Message.src_mod_id;                 ilm_ptr.dest_mod_id = Message.dest_mod_id;                 ilm_ptr.msg_id = Message.msg_id;                 ilm_ptr.sap_id = Message.sap_id;                 ilm_ptr.local_para_ptr = Message.local_para_ptr;                 ilm_ptr.peer_buff_ptr = Message.peer_buff_ptr;                  //放入内部队列                 // 这个内部队列是个简单的循环队列                 flag = OslWriteCircularQ(&ilm_ptr);                                // 对 timer 消息进行特殊处理                 if (Message.src_mod_id != MOD_TIMER)                 {                     hold_local_para(ilm_ptr.local_para_ptr);                     hold_peer_buff(ilm_ptr.peer_buff_ptr);                     OslFreeInterTaskMsg(&Message);                 }             }             else             {                 // 把外部消息放入到内部消息                 mmi_frm_fetch_msg_from_extQ_to_circularQ();             }              //处理内部消息             count = OslNumOfCircularQMsgs();             while (count > 0)             {                 OslGetMyTaskIndex(&my_index);                 OslStackSetActiveModuleID(my_index, MOD_MMI);                  if (OslReadCircularQ(&Message))                 {                     CheckAndPrintMsgId((U16) (Message.msg_id));                     //是否是 wap 的消息                     // 这里就体现了一个task 可以对应多个mod                     if (Message.dest_mod_id == MOD_WAP)                     {                                         }                                         else                     {                         switch (Message.msg_id)                         {                             //timer 消息 具体看 MTK timer 小结 2                             case MSG_ID_TIMER_EXPIRY:                             {                                 kal_uint16 msg_len;                                 //处理stack timer消息                                 EvshedMMITimerHandler(get_local_para_ptr(Message.oslDataPtr, &msg_len));                             }                                 break;                                                   //开机消息                             //具体分析 见后文                              case MSG_ID_MMI_EQ_POWER_ON_IND:                             {                                 mmi_eq_power_on_ind_struct *p = (mmi_eq_power_on_ind_struct*) Message.oslDataPtr;                                  /* To initialize data/time */                                 SetDateTime((void*)&(p->rtc_time));                                 gdi_init();                                  g_pwr_context.PowerOnMMIStatus = MMI_POWER_ON_INDICATION;                                                                 switch (p->poweron_mode)                                 {                                     case POWER_ON_KEYPAD:                                                                             OslMemoryStart(MMI_TRUE);                                         g_charbat_context.PowerOnCharger = 0;                                         g_pwr_context.PowerOnMode = POWER_ON_KEYPAD;                                                                             DTGetRTCTime(&StartUpTime);                                         memset(&LastDuration, 0, sizeof(LastDuration));                                         mmi_bootup_entry_disk_check();                                                                                 break;                                                                           case POWER_ON_PRECHARGE:                                     case POWER_ON_CHARGER_IN:                                                                                                       g_pwr_context.PowerOnMode = p->poweron_mode;                                            InitializeChargingScr();                                         if (!g_charbat_context.isChargerConnected)                                         {                                             QuitSystemOperation();                                         }                                                                                  break;                                      case POWER_ON_ALARM:                                                                                                             g_pwr_context.PowerOnMode = POWER_ON_ALARM;                                                                            gdi_layer_clear(GDI_COLOR_BLACK);                                         AlmInitRTCPwron();                                                                                 break;                                     case POWER_ON_EXCEPTION:                                                                                                                 g_pwr_context.PowerOnMode = POWER_ON_EXCEPTION;                                                                              gdi_layer_clear(GDI_COLOR_BLACK);                                         OslMemoryStart(MMI_TRUE);                                         SetAbnormalReset();                                         InitializeAll();                                         OslDumpDataInFile();                                                                                 ClearInputEventHandler(MMI_DEVICE_ALL);                                         ClearKeyHandler(KEY_END, KEY_LONG_PRESS);                                                                     InitNvramData();                                         InitAllApplications();                                                                 mmi_pwron_exception_check_display();                                          break;                                     default:                                         break;                                 }                             }                                 break;                             // event 时间,这个也是MMI task 的一个重点                             default:                                 ProtocolEventHandler(                                     (U16) Message.oslMsgId,                                     (void*)Message.oslDataPtr,                                     (int)Message.oslSrcId,                                     (void*)&Message);                                 break;                         }                      }                      OslFreeInterTaskMsg(&Message);                                     }                    msg_get_ext_queue_info(mmi_ext_qid, &queue_node_number);                 count--;             }         }          } }
转自:http://blog.csdn.net/yanwuxufeng/archive/2010/07/24/5762361.aspx

原创粉丝点击