Rex (Real-Time Executive)
高通平台的结构
Rex 简介 REX是一个实时的抢占式操作系统. 每个REX任务都独立地由REX内核调度,每个任务都有一个数据结构rex_tcb_struct.TCBs按优先级顺序编排在一个单一的链表中 ----活动的和挂起的任务在同一个列表中.每个任务将一直执行到下列事件之一发生而进行上下文的切换. 自愿挂起如执行rex_wait or rex_timed_wiat 在高优先级的挂起任务里设置了一个信号 产生了一个更高优先级的任务. 一个正在执行的任务使另外一个任务的优先级比它的优先级高 中断产生并且ISR切换进优先级比被中断的任务优先级高的任务中 REX的允许任务的优先级范围为1到65535,1是最低优先级,优先级为0预留给空闲任务使用.没有两个及两个以上的任务具有相同的优先级.
Rex操作系统 任务API: rex_def_task 优先级API: rex_set_pri,rex_task_pri,rex_get_pri. REX的信号工作原理:Rex的信号主要集中在TCB的两个Field: Sigs:是一个掩码,包括给定任务已经设置的信号 Wait:是一个掩码,包括一些信号,一旦这些信号被设置,任务就挂起. 信号的函数有: rex_wait(), rex_set_sigs().rex_get_sigs(),rex_clr_sigs() REX Timers:活动的REX计时器是一个具有rex_timer_struct结构的双向链表.使用REX计时器的任务先分配一个rex_timer_struct,然后调用rex_def_timer. Rex_set_timer启动一个计时器. 中断处理:IRQ处理器调用tramp_isr,然后决定哪个中断产生.
Rex task之间交互 任务间的通信是通过队列和信号量来完成的. 想丛其他任务接受消息的任务生成一个全局命令队列和一个与队列相关的信号 想丛其他任务发送消息的任务: 获取目标任务相关的类型的一个命令的Buffer. 完成合适区域的填充 把消息排队到命令队列中 为该命令设置相关的信号
Rex task之间交互(Cont.) 通常,队列操作和设置信号被封装成一个函数。
Rex task之间交互(Cont.)
Rex task与BREW之间交互 方法一:postEvent方法,在Rex某个task中直接调用ISHELL_PostEventEx或者ISHELL_PostEvent <注1> ISHELL_PostEventEx主要的区别在于,此函数允许向同一个小程序传递同一类型的多个事件(同一事件代码)并让事件排队等待分发。
Rex task与BREW之间交互(Cont.) <注2>如果ISHELL_PostEventEx最后一个参数为一个指针的话,一定要注意该指针指向的内存。在高通平台中调用不同的malloc或者MALLOC分配的内存可能来自不同的堆,释放的时候,必须到用相应的释放函数。所以我们在调用ISHELL_PostEventEx之前,先要把数据拷贝一份,到上层app收到这个消息的时候,释放该备份的内存。
Rex task与BREW之间交互(Cont.)
Rex task与BREW之间交互(Cont.) eg: void WMSAPP_CfgCb(uint16 event, wms_cfg *pInfo) { sms_cfg=MALLOC(sizeof(wms_cfg)); MEMCPY(sms_cfg, pInfo, sizeof(wms_cfg)); ISHELL_PostEventEx(pShell, EVTFLG_ASYNC, clsID, event, sms_cfg); } 初始化的时候,调用wms_client_reg_msg_cb(ID, WMSAPP_CfgCb);
Rex task与BREW之间交互(Cont.) 方法二:基本同方法,回调中调用AEE_ResumeCallback而 不是PostEventEx
BREW与Service交互实例 struct IWMS{ AEEVTBL(IWMS) *pvt; IShell *m_pIShell; AEECLSID m_cls; //no use uint32 m_uRefs; //引用计数 }; typedef struct{ AEEApplet a; IWMS *m_pwms; … }CWMSAPP; ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_WMS, (void **)&pMe->m_pwms); //创建wms接口,首先通过 gOEMStaticClassList找到OEMWMS_New
BREW与Service交互实例(Cont.) static const AEEStaticClass gOEMStaticCLassList[] = { {AEECLSID_WMS, ASCF_PRIV, 0, NULL, OEMWMS_New}, }; OEMWMS_New分析(OEMWMS.) static struct IWMS *IWMSobj = NULL;//局部全局变量 int OEMWMS_New(IShell *pIShell, AEECLSID cls,void **ppif) ... ;//参数合法性检查 if (IWMSobj == NULL) if ((IWMSobj = (IWMS*)OEM_Malloc(sizeof(IWMS))) == NULL) { return ENOMEMORY; }
BREW与Service交互实例(Cont.) IWMSobj->pvt = (IWMSVtbl *)&gOEMWMSFuncs; IWMSobj->m_pIShell = pIShell; IWMSobj->m_cls = cls; IWMSobj->m_uRefs = 1; *ppif = IWMSobj; } else { (void *)OEMWMS_AddRef(IWMSobj); *ppif = IWMSobj; } return AEE_SUCCESS
BREW与Service交互实例(Cont.) static const AEEVTBL(IWMS) gOEMWMSFuncs = { OEMWMS_AddRef ,OEMWMS_Release ,OEMWMS_QueryInterface ,OEMWMS_Init ,... OEMWMS_MsgDeleteAllExt };
BREW与Service交互实例(Cont.) #define IWMS_AddRef(p) \ AEEGETPVTBL(p, IWMS)->AddRef(p) 调用IWMS_AddRef实际上就是调用OEMWMS_AddRef
BREW与Service交互实例(Cont.) 上层BREW应用调用IWMS_MsgRead (AEEWMS.h),属于BREW AEE层。 IWMS_MsgRead实际上就是调用OEMWMS_MsgRead (OEMWMS.c),属于BREW OEM层。 在OEMWMS_MsgRead函数中,调用wms_msg_read (wms.c, 属于service层)给wms_task发一个CMD。 wms_status_e_type wms_msg_read( wms_client_id_type client_id, wms_cmd_cb_type cmd_cb, const void *user_data, wms_memory_store_e_type mem_store, wms_message_index_type index)
BREW与Service交互实例(Cont.) { wms_status_e_type st = WMS_OK_S; wms_cmd_type *cmd_ptr; cmd_backup.hdr.cmd_id = WMS_CMD_MSG_READ; cmd_backup.hdr.client_id = client_id; cmd_backup.hdr.cmd_cb = cmd_cb; cmd_backup.hdr.user_data = (void*)user_data; cmd_backup.cmd.msg_read.mem_store = mem_store; cmd_backup.cmd.msg_read.index = index; //cmd_backup赋值 cmd_ptr = wms_get_cmd_buf(); //从队列中取出一个元素
BREW与Service交互实例(Cont.) if (cmd_ptr != NULL) { *cmd_ptr = cmd_backup; wms_put_cmd(cmd_ptr); //消息插入到到队列中,并设置信号 }else{ wms_client_cmd_status(&cmd_backup, WMS_CMD_ERR_NO_RESOURCE); //回调错误消息 st = WMS_OUT_OF_RESOURCES_S; } return st;
BREW与Service交互实例(Cont.) 以上函数的执行环境为ui_task,当调用wms_put_cmd这个函数的时候, wms_task会收到WMS_CMD_Q_SIG,其相应的环境会转化wms_task。 当wms_task处理完毕后,会调用app注册的回调函数(向app层事件) void WMSAPP_CfgCb(uint16 event, wms_cfg *pInfo) { sms_cfg=MALLOC(sizeof(wms_cfg)); MEMCPY(sms_cfg, pInfo, sizeof(wms_cfg)); ISHELL_PostEventEx(pShell, EVTFLG_ASYNC, clsID, event, sms_cfg); }
BREW与Service交互实例(Cont.) ISHELL_PostEventEx发的事件,BREW收到事件(执行环境从wms_task转到ui_task)
BREW与Service交互实例(Cont.)
Thanks!