消息
WSF的消息服务用于传递消息到对应的事件处理句柄。
实现机制和使用方法
- 基于内存管理,从内存中申请sizeof(wsfMsg_t) + 消息长度的内存。添加头部描述,返回给申请者除去头部的指针位置。
- 将消息添加到对应事件处理具柄上去。
- 对应任务取出列队,处理完毕后将消息释放。
//消息队列的管理结构。
typedef struct wsfMsg_tag
{
struct wsfMsg_tag *pNext; //指向下一个消息的指针
wsfHandlerId_t handlerId; //消息对应的处理句柄
} wsfMsg_t;
//为当前消息申请len 长度消息和 tailroom长度消息内容
void *WsfMsgDataAlloc(uint16_t len, uint8_t tailroom)
{
return WsfMsgAlloc(len + tailroom);
}
//申请一个消息的长度
void *WsfMsgAlloc(uint16_t len)
{
wsfMsg_t *pMsg;
//申请的长度包含本身消息结构的长度
pMsg = WsfBufAlloc(len + sizeof(wsfMsg_t));
/* 返回的地址需要去除消息头的长度 */
if (pMsg != NULL)
{
pMsg++;
}
return pMsg;
}
//消息使用完毕后,将消息占用的内存释放
void WsfMsgFree(void *pMsg)
{
//释放时同时要将消息头部的内存释放
WsfBufFree(((wsfMsg_t *) pMsg) - 1);
}
消息的发送
将消息添加到handleID对应的列队中,并给这个handleID设置消息队列的事件。
//将消息发送给对应的处理句柄
void WsfMsgSend(wsfHandlerId_t handlerId, void *pMsg)
{
WSF_TRACE_MSG1("WsfMsgSend handlerId:%u", handlerId);
/* 根据handleId获取当前任务的msg_queue,然后将消息添加到队列中 */
WsfMsgEnq(WsfTaskMsgQueue(handlerId), handlerId, pMsg);
/* 向对应的task发送有列队的事件,以保证后续可以处理改消息 */
WsfTaskSetReady(handlerId, WSF_MSG_QUEUE_EVENT);
}
消息的管理
主要进行消息的出队和如队的操作。操作的时候需要注意消息头部的管理。入队时需要找到消息的头部节点,出队时需要将头部节点去除后将消息传递给用户。
//将消息添加到消息队列
void WsfMsgEnq(wsfQueue_t *pQueue, wsfHandlerId_t handlerId, void *pMsg)
{
wsfMsg_t *p;
WSF_ASSERT(pMsg != NULL);
/* 需要找到从消息头部开始的地方 */
p = ((wsfMsg_t *) pMsg) - 1;
/* 设置消息处理的handleId */
p->handlerId = handlerId;
WsfQueueEnq(pQueue, p);
}
//从消息队列中取出一个消息
void *WsfMsgDeq(wsfQueue_t *pQueue, wsfHandlerId_t *pHandlerId)
{
wsfMsg_t *pMsg;
if ((pMsg = WsfQueueDeq(pQueue)) != NULL)
{
*pHandlerId = pMsg->handlerId;
/* 需要去除消息的头部 */
pMsg++;
}
return pMsg;
}
//从消息队列中取出一个消息,但不从列队中删除
void *WsfMsgPeek(wsfQueue_t *pQueue, wsfHandlerId_t *pHandlerId)
{
wsfMsg_t *pMsg = pQueue->pHead;
if (pMsg != NULL)
{
*pHandlerId = pMsg->handlerId;
/* 需要去除消息的头部 */
pMsg++;
}
return pMsg;
}