MTK TASK创建实例以及消息处理机制浅析

时间:2022-10-27 19:43:15

一、如何创建一个task


创建一个task 分为 以下几步:

1 增加一个task index 到 custom_task_indx_type


#ifdef __BTX_CDMA_MODEM__
INDX_CDMA_MODEM_TASK,
#endif


2 增加一个mod index 到 custom_module_type


#ifdef __BTX_CDMA_MODEM__
MOD_CDMA_MODEM_TASK,
#endif


3 挂载mod 到 task上


#ifdef __BTX_CDMA_MODEM__
INDX_CDMA_MODEM_TASK,
#endif

这样就把 MOD_CDMA_MODEM_TASK 挂载到 INDX_CDMA_MODEM_TASK上面了,这里的映射关系是通过index 来控制的,也就是说要的到MOD_CDMA_MODEM_TASK 对应的 task index,只要这样 INDX_CDMA_MODEM_TASK = custom_mod_task_g[MOD_CDMA_MODEM_TASK]; ,所以创建过程中,顺序一定要对应好,不然容易出错。


4 创建task 信息 custom_comp_config_tbl


#ifdef __BTX_CDMA_MODEM__
/*INDX_CDMA_MODEM_TASK*/
{ "CDMA MODEM", "CUSTOM MODEM Q", 168,4096,40,3,
cdma_modem_create, KAL_FALSE
},
#endif


168表示优先级,4096栈空间大小,40表示外部消息最大数目,3表示内部消息最大数目

cdma_modem_create是Task创建的主函数,初始化以及流程处理都在这里进行的。


5 定义消息队列

如果TASK需要与别的TASK交互,要使用消息,消息ID在文件custom_sap.h中定义,该头文件被包含在文件stack_msgs.h中,最终合并入msg_type枚举中


  1. ifdef __BTX_CDMA_MODEM__

MSG_ID_CDMA_MODEM_UP_UART_READY_TO_READ_IND,MSG_ID_CDMA_MODEM_UP_UART_READY_TO_WRITE_IND,MSG_ID_CDMA_MODEM_DOWN_UART_READY_TO_READ_IND,MSG_ID_CDMA_MODEM_DOWN_UART_READY_TO_WRITE_IND,

  1. endif


Task的创建基本上就这4个步骤,下面是Task初始化以及内部流程处理等过程。


二、TASK消息机制以及处理流程


先看一下 cdma_modem_create 函数体


   static const comptask_handler_struct cdma_modem_handler_info = 
{
cdma_modem_task_main, /* task entry function */
cdma_modem_init, /* task initialization function */
NULL, /* task configuration function */
cdma_modem_reset, /* task reset handler */
cdma_modem_deinit /* task termination handler */
};

*handle = (comptask_handler_struct*)(&cdma_modem_handler_info);
return KAL_TRUE;



cdma_modem_task_main是主要的流程处理函数,cdma_modem_init主要做一些变量初始化等操作,后面3个函数不是一定必要的。


cdma_modem_task_main是用消息循环处理机制对Task接收到的消息进行处理,while (1)是不断循环并接收消息,接收到之后就进行处理。


   ilm_struct current_ilm;
kal_uint32 my_index = 0;
kal_get_my_task_index(&my_index);
while (1) {
receive_msg_ext_q( task_info_g[task_entry_ptr->task_indx].task_ext_qid, &current_ilm);
stack_set_active_module_id( my_index, current_ilm.dest_mod_id );
cdma_modem_main((void *) &current_ilm);
free_ilm( &current_ilm);
}



处理流程如下:


case MSG_ID_CDMA_MODEM_UP_UART_READY_TO_READ_IND:

               ......

break;

case MSG_ID_CDMA_MODEM_UP_UART_READY_TO_WRITE_IND:

               ......

break;


三、消息发送机制以及处理流程


不同Task之间的消息通讯:msg_send_ext_queue


ilm_struct *ilm_ptr = allocate_ilm(MOD_MMI);

ilm_ptr->src_mod_id = MOD_MMI;

ilm_ptr->dest_mod_id = MOD_HT_AT_TASK;

ilm_ptr->msg_id = msgId;

ilm_ptr->sap_id = HT_MMI_AT_SAP;

ilm_ptr->peer_buff_ptr = NULL;

ilm_ptr->local_para_ptr = pData;

msg_send_ext_queue(ilm_ptr);




相同Task之间的消息通讯:msg_send_int_queue


ilm_struct *ilm_ptr = allocate_ilm(MOD_HT_AT_TASK);

ilm_ptr->src_mod_id = MOD_HT_AT_TASK;

ilm_ptr->dest_mod_id = MOD_HT_AT_TASK;

ilm_ptr->msg_id = msgId;

ilm_ptr->sap_id = HT_AT_AT_SAP;

ilm_ptr->peer_buff_ptr = NULL;

ilm_ptr->local_para_ptr = pData;

msg_send_int_queue(ilm_ptr);



src_mod_id 设置了请求服务的模块id

dest_mod_id 接收请求的模块id

sap_id 服务请求标志,如果没有定义可以填0

msg_id 请求的消息id,就是TASK要进行处理的ID

local_para_ptr 请求需要提供的附加信息,没有则为NULL

peer_buff_ptr 请求需要提供的附加信息,没有则为NULL



消息发送出去后,过一段时间(应该很短),相应模块就在循环调度中接受到了消息并进行相应的处理。