zigbee中为什么消息发送和消息接收函数都要调用 osal_set_event()函数,不就重复了吗?
uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr ) {//消息被封装进msg_ptr中
if (msg_ptr == NULL) // 指针为空返回错误信息
return (INVALID_MSG_POINTER);
// 如果要发送的任务号大于系统定义的最大任务号
if (destination_task >= tasksCnt) {
osal_msg_deallocate( msg_ptr );
return ( INVALID_TASK );
}
// 检查元数据,是否为错误的消息
if ( OSAL_MSG_NEXT( msg_ptr ) != NULL ||
OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK ) {
osal_msg_deallocate( msg_ptr );
return ( INVALID_MSG_POINTER );
}
// 设置其元数据的目的地址
OSAL_MSG_ID( msg_ptr ) = destination_task;
// 将该消息进入队列中,然后任务事件处理函数中调用osal_msg_receive( GenericApp_TaskID );遍历队列,然后找到此任务的消息
osal_msg_enqueue( &osal_qHead, msg_ptr );
// 告知任务有消息需要处理,将这个任务的事件设置为系统事件,因为只有系统事件才能处理消息
osal_set_event( destination_task, SYS_EVENT_MSG );
return (SUCCESS)
}
uint8 *osal_msg_receive( uint8 task_id ) {//一次只从接收队列中找到一个发给此任务的消息,任务处理事件函数中有一个循环,可以不间断的一个一个的获取消息
osal_msg_hdr_t *listHdr; // 定义一个消息结构体指针
osal_msg_hdr_t *prevHdr = NULL;//
osal_msg_hdr_t *foundHdr = NULL;
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState); // 进入临界区,关中断。
listHdr = osal_qHead; // 指向队首指针
// 遍历队列
while ( listHdr != NULL ) {
// 如果某个消息的目的地是 task_id
if ((listHdr - 1)->dest_id == task_id) {
// 第一次找到
if ( foundHdr == NULL ) {
foundHdr = listHdr;
}
else break;
}
if (foundHdr == NULL) {
// 保存找到的消息之前的消息
// 方便进行删除操作
prevHdr = listHdr;//这句话为把找到的消息从队列中删除
}
listHdr = OSAL_MSG_NEXT( listHdr ); // 遍历
}
// 不为空,证明为遍历完,也就是存在多个消息
if ( listHdr != NULL ) {
// 告知任务还有消息在等待处理
osal_set_event( task_id, SYS_EVENT_MSG );
}
else {
osal_clear_event( task_id, SYS_EVENT_MSG );
}
// 找到了消息
if (foundHdr != NULL) {
// 提取出这个消息
osal_msg_extract( &osal_qHead, foundHdr, prevHdr );
}
HAL_EXIT_CRITICAL_SECTION(intState);// 退出临界区,开中断。
return ( (uint8*) foundHdr ); // 返回消息
}