苏莫婷 2021-11-27 11:19 采纳率: 50%
浏览 38
已结题

zigbee中为什么消息发送和消息接收函数都要调用 osal_set_event()函数,不就重复了吗?

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 ); // 返回消息
}
  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 12月5日
    • 创建了问题 11月27日

    悬赏问题

    • ¥50 这Mac系统提示虚拟内存不足,怎么解决
    • ¥15 Rs232电路无法收发数据,求帮助
    • ¥15 百度cookie扫码登录器
    • ¥15 微机原理汇编语言debug调试实验
    • ¥23 matlab可以把相图转换为庞加莱映射吗
    • ¥20 有偿,学生成绩信息管理系统
    • ¥15 Arduino电机和openmv连接异常
    • ¥15 Arcgis河网分级报错
    • ¥200 java+appium2.1+idea
    • ¥20 请帮我做一个EXE的去重TXT文本