zstack协议栈解读(转)

分类: 嵌入式学习 |
一个设备可以有240个端点,每个端点必须有一个端点描述符endPointDesc,端点描述符里包括一个简单描述符。在看Zstack的例子时应该详细看一下应用层,3个文件,SerialApp.h SerialApp.c OSAL_SerialApp.c
端点描述符结构:
typedef struct
{
} endPointDesc_t;
//初始化后的一个端点描述符结构
const endPointDesc_t SerialApp_epDesc =
{
};
简单描述符的结构
typedef struct
{
} SimpleDescriptionFormat_t;
//初始化后的一个简单描述符结构
const SimpleDescriptionFormat_t SerialApp_SimpleDesc ={
};
AF.c 中的afStatus_t afRegister( endPointDesc_t *epDesc ),//在AF层注册该端口描述符。
只有分别在两个节点的简单描述结构体中,同时注册了相同的命令标示符并且方向相反才能建立绑定。
SerialApp_TxBuf[0]存放的是发送的序列号SerialApp_TxSeq,即通过串口发送的数据SerialApp_TxBuf,是从SerialApp_TxBuf[1]开始的,同样接收数组SerialApp_RxBuf[0]存放的是接收的序列号SerialApp_RxSeq,为什么会这样?
其实这里加了个保险措施,其实就是发送设备将发送序列号加在数据中一块发送,接收设备接收到数据后,将发送序列号回传给发送设备,发送设备将该序列号和发送时的序列号比较一下,如果相等则说明数据发送成功。
通过上面的分析可知,接收设备收到数据后,将接数据有关的状态以及接收序列号(其实就是发送设备的发送序列号)等信息放在一个4字节的数组里面,然后将该数组发送给发送设备。
发送设备接收到接收设备回传的响应信息后,将发送序列号和接收序列号比较,如果相等,则说明原来的数据发送成功了。
参考http://www.feibit.com/forum.php?mod=viewthread&tid=2928
代码分析:
-
void
SerialApp_Init( uint8 task_id ) -
{
-
halUARTCfg_t uartConfig; -
-
-
SerialApp_TaskID = task_id; -
SerialApp_RxSeq = 0xC3;//不知为何???? -
//在AF层注册该端口描述符 -
afRegister( (endPointDesc_t *)&SerialApp_epDesc ); -
-
//按键事件交给本任务处理
-
RegisterForKeys( task_id ); -
-
//串口配置
-
uartConfig.configured = TRUE; // 2x30 don't care - see uart driver. -
uartConfig.baudRate = SERIAL_APP_BAUD; -
uartConfig.flowControl = FALSE; -
uartConfig.flowControlThreshold = SERIAL_APP_THRESH; // 2x30 don't care - see uart driver. -
uartConfig.rx.maxBufSize = SERIAL_APP_RX_SZ; // 2x30 don't care - see uart driver. -
uartConfig.tx.maxBufSize = SERIAL_APP_TX_SZ; // 2x30 don't care - see uart driver. -
uartConfig.idleTimeout = SERIAL_APP_IDLE; // 2x30 don't care - see uart driver. -
uartConfig.intEnable = TRUE; // 2x30 don't care - see uart driver.
-
uartConfig.callBackFunc
= SerialApp_CallBack;
-
HalUARTOpen (SERIAL_APP_PORT, &uartConfig); -
-
-
#if
defined ( LCD_SUPPORTED ) -
HalLcdWriteString( "SerialApp", HAL_LCD_LINE_2 ); -
#endif
-
//注册节点绑定响应事件和匹配描述符响应事件 -
ZDO_RegisterForZDOMsg( SerialApp_TaskID, End_Device_Bind_rsp ); -
ZDO_RegisterForZDOMsg( SerialApp_TaskID, Match_Desc_rsp ); -
#if
defined (ZDO_COORDINATOR)//有三种设备不知怎样定义???? -
HalUARTWrite(SERIAL_APP_PORT,szWelcomeMsgCoor,sizeof(szWelcomeMsgCoor)); -
#else
-
HalUARTWrite(SERIAL_APP_PORT,szWelcomeMsgRouter,sizeof(szWelcomeMsgRouter)); -
#endif
-
-
-
}
#define End_Device_Bind_rsp
#define
End_Device_Bind_req
#define
ZDO_RESPONSE_BIT
#define
Match_Desc_rsp
#define
Match_Desc_req
-
-
ZStatus_t
ZDO_RegisterForZDOMsg( uint8 taskID, uint16 clusterID ) -
{
-
ZDO_MsgCB_t *pList; -
ZDO_MsgCB_t *pLast; -
ZDO_MsgCB_t *pNew; -
-
// Look for duplicate -
pList = pLast = zdoMsgCBs; -
while ( pList ) -
{ -
if ( pList->taskID == taskID && pList->clusterID == clusterID ) -
return ( ZSuccess ); -
pLast = pList; -
pList = (ZDO_MsgCB_t *)pList->next; -
} -
-
// Add to the list -
pNew = (ZDO_MsgCB_t *)osal_mem_alloc( sizeof ( ZDO_MsgCB_t ) ); -
if ( pNew ) -
{ -
pNew->taskID = taskID; -
pNew->clusterID = clusterID; -
pNew->next = NULL; -
if ( zdoMsgCBs ) -
{ -
pLast->next = pNew; -
} -
else -
zdoMsgCBs = pNew; -
return ( ZSuccess ); -
} -
else -
return ( ZMemError ); -
}
#define ZDO_CB_MSG
什么时候会调用下面这个函数呢???是在UINT16 SerialApp_ProcessEvent( uint8 task_id, UINT16 events )中
-
-
static
void SerialApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg ) -
{
-
switch ( inMsg->clusterID ) -
{ -
case End_Device_Bind_rsp: -
if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess ) -
{ -
// Light LED -
HalLedSet( HAL_LED_4, HAL_LED_MODE_ON ); -
} -
#if
defined(BLINK_LEDS) -
else -
{ -
// Flash LED to show failure -
HalLedSet ( HAL_LED_4, HAL_LED_MODE_FLASH ); -
} -
#endif
-
break; -
-
case Match_Desc_rsp: -
{ -
ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg ); -
if ( pRsp ) -
{ -
if ( pRsp->status == ZSuccess && pRsp->cnt ) -
{ -
SerialApp_TxAddr.addrMode = (afAddrMode_t)Addr16Bit; -
SerialApp_TxAddr.addr.shortAddr = pRsp->nwkAddr; -
// Take the first endpoint, Can be changed to search through endpoints -
SerialApp_TxAddr.endPoint = pRsp->epList[0]; -
-
// Light LED -
HalLedSet( HAL_LED_4, HAL_LED_MODE_ON ); -
} -
osal_mem_free( pRsp ); -
} -
} -
break; -
} -
}
MT这又是哪一层?
开始时所有任务的状态都被初始化为0,代表了当前任务没有需要响应的事件。事件是如何被OSAL捕获的,即taskEvents数组中的元素是什么时候设定为非零的?
参考http://bbs.feibit.com/thread-280-1-1.html
以按键响应为例,处理按键响应的函数是
大体思路是这样的:
1、 // Final board initialization
2、在void
HalKeyConfig (bool interruptEnable, halKeyCBack_t
cback)中最后有
uint16 Hal_ProcessEvent( uint8 task_id, uint16 events )
3、在uint16
Hal_ProcessEvent( uint8 task_id, uint16 events
)中又调用了
static halKeyCBack_t
pHalKeyProcessFunction;
pHalKeyProcessFunction这个函数指针指向了 void OnBoard_KeyCallback ( uint8 keys, uint8 state ),在这个函数中,又调用了byte OnBoard_SendKeys( byte keys, byte state ),在这个函数中,按键的状态信息被封装到了一个消息结构体中(对于消息,我们稍后再说)。最后有一个极其重要的函数被调用了。osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );registeredKeysTaskID所指示的任务正是我们需要响应按键的SerialApp这个任务。在osal_msg_send函数中osal_set_event( destination_task, SYS_EVENT_MSG );
HalKeyPoll()获取当前按键的状态,并且通过调用OnBoard_KeyCallback函数向SerialApp任务发送一个按键消息,并且设置tasksEvents中SerialApp所对应的值为非零。
大神的解答:
-
第一、pHalKeyProcessFunction这个函数指针为何指向了OnBoard_KeyCallback函数。
-
在HAL\Commen\
hal_drivers.c这个文件中,我们找到了HalDriverInit这个函数,在这个函数中,按键的初始化函数HalKeyInit被调用。在HalKeyInit中有这样的语句: -
{
-
pHalKeyProcessFunction = NULL; -
}
-
这说明在初始化以后pHalKeyProcessFunction并没有指向任何一个函数。那pHalKeyProcessFunction是什么时候被赋值的呢?
-
就在HalKeyInit的下方有一个这样的函数HalKeyConfig。其中有这样一条语句:
-
pHalKeyProcessFunction
= cback; -
cback是HalKeyConfig所传进来的参数,所以,想要知道它所指向的函数,必须找到其调用的地方。经过简单的搜索我们不难找出答案。在main函数中有这样一个函数调用:InitBoard(
OB_READY );此函数中做了如下调用: -
{
-
HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback); -
}
-
第二、registeredKeysTaskID为什么标识了GenericApp这个任务?
-
由于OSAL是一个支持多任务的调度机制,所以在同一时间内将会有多个任务同时运行。但是从逻辑上来讲,一个事件只能由一个任务来处理。按键事件也不例外。
-
那么如何向OSAL声明处理按键事件的任务是GenericApp呢?
-
在GenericApp_Init(GenericApp的任务初始化函数)中有这么一个语句:
-
{
-
RegisterForKeys( GenericApp_TaskID ); -
}
-
RegisterForKeys函数向OSAL声明按键事件将由GenericApp任务来处理。在RegisterForKeys函数中:
-
{
-
registeredKeysTaskID = task_id; -
}
说实话下面这句不懂??是回调函数,就是要向SerialApp任务发送按键消息。
-
-
if (keys && (pHalKeyProcessFunction)) -
{ -
(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL); -
}