开发环境:IAR 8.10 Z-stack 2.5
功能:协调器与终端节点组网,实现点对点通信。终端向协调器发送“D1”,协调器LED灯闪烁。
流程图:
具体代码:
- 定义所需要的变量
- 端点描述符
endPointDesc_t GenericApp_epDesc;
- 任务ID,应用层的优先级
byte GenericApp_TaskID;
- 定义简单端点描述符
SimpleDescriptionFormat_t 是一个结构体,我们可以具体分析一下,这里是它的定义:
const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{GENERICAPP_ENDPOINT, //端口号GENERICAPP_PROFID, //Profile的IDGENERICAPP_DEVICEID, //设备IDGENERICAPP_DEVICE_VERSION, //设备版本号,只占前四位GENERICAPP_FLAGS, //预留位,只占前四位GENERICAPP_MAX_CLUSTERS, //输入命令数(cId_t *)GenericApp_ClusterList, //输入命令地址0, //输出命令数(cId_t *)NULL //输出命令地址
};
由于在本次实验中协调器节点角度(被命令的一方)所以要求是输入命令
- 定义输入命令集列表
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{GENERICAPP_CLUSTERID //命令号
};
- 重新定义一些函数
- 初始化函数 void GenericApp_Init( byte task_id )
在这个函数里只做了三件事 保存系统分配的任务ID、填充端口描述符和注册端点描述符
//任务初始化函数, 系统初始化时会被调用
void GenericApp_Init( byte task_id )
{GenericApp_TaskID = task_id; // Fill out the endpoint description.//填充端点描述符GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;GenericApp_epDesc.task_id = &GenericApp_TaskID;GenericApp_epDesc.simpleDesc= (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;GenericApp_epDesc.latencyReq = noLatencyReqs; //这个是固定的,不需要修改// Register the endpoint description with the AF//注册端点描述符, 如果没有,不能使用OSAL提供的服务afRegister( &GenericApp_epDesc );
}
- 任务处理函数 UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
//应用层事件函数,系统自动调用
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{afIncomingMSGPacket_t *MSGpkt; //消息包指针if ( events & SYS_EVENT_MSG ) //判断是否是系统事件{//从消息队列中读取(接收)当前任务的消息MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );while ( MSGpkt ) //循环处理消息{switch ( MSGpkt->hdr.event ){AF_INCOMING_MSG_CMD是用来不同设备之间通讯的原语,目的是用来收到报文时的处理case AF_INCOMING_MSG_CMD:GenericApp_MessageMSGCB( MSGpkt );break;default:break;}// Release the memoryosal_msg_deallocate( (uint8 *)MSGpkt );// Next 再次读取当前任务的消息MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );}// return unprocessed eventsreturn (events ^ SYS_EVENT_MSG);}//用户事件// Discard unknown eventsreturn 0;
}
{afIncomingMSGPacket_t *MSGpkt; //消息包指针if ( events & SYS_EVENT_MSG ) //判断是否是系统事件{//从消息队列中读取(接收)当前任务的消息MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );while ( MSGpkt ) //循环处理消息{switch ( MSGpkt->hdr.event ){case AF_INCOMING_MSG_CMD:GenericApp_MessageMSGCB( MSGpkt );break;default:break;}// Release the memoryosal_msg_deallocate( (uint8 *)MSGpkt );// Next 再次读取当前任务的消息MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );}// return unprocessed eventsreturn (events ^ SYS_EVENT_MSG);}//用户事件// Discard unknown eventsreturn 0;
}
- 接收到射频消息处理函数(回调函数)
//接收到射频消息处理函数(回调函数)
static void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{uint8 buffer[10];switch ( pkt->clusterId ) //得到命令号{case GENERICAPP_CLUSTERID: //终端节点的消息osal_memcpy(buffer, pkt->cmd.Data, 2);if(buffer[0] == 'D' && buffer[1] == '1') //判断消息是否是D1{//接收到了"D1"//LED1闪烁HalLedBlink(HAL_LED_1, 0, 50, 1000);}break;default:break;}
}
Coordinator.h
#ifndef COORDINATOR_H_
#define COORDINATOR_H_#define GENERICAPP_MAX_CLUSTERS 1 //输入簇的个数#define GENERICAPP_CLUSTERID 0001 //输入簇的ID#define GENERICAPP_ENDPOINT 10 //端点ID
#define GENERICAPP_PROFID 0x0F04 //规约ID
#define GENERICAPP_DEVICEID 0x0001 //设备ID
#define GENERICAPP_DEVICE_VERSION 0 //版本号
#define GENERICAPP_FLAGS 0 //保留位UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events );
void GenericApp_Init( byte task_id );#endif
注意:
- 函数名必须和OSAL_Genericapp.c里面一致,要修改初始化函数名和事件处理函数名必须也要修改OSAL_Genericapp.c里面的相应的函数名。
本文是看里B站视频做的笔记,这里是链接:https://www.bilibili.com/video/av54057090?p=22