问题出现可以参看从零开始学习ZSTACK9文章
http://www.yyytech.cn/Tech/Read.aspx?id=264
提问:
“每次发射开始时候会发送乱码出来? <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
我跟踪代码发现是DMA开始的时候发出来的?
难道是FIFO里面的随机数?
但是为什么每次都一样呢?
百思不得其解!!!!寻求帮忙~“
解答:
下面我们来跟踪下串口发送程序:
1、首先看看SimpleApp.c文件的函数zb_ReceiveDataIndication()最后一句话为向串口发数据的。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
2、debug_str
void debug_str( byte *str_ptr )
{
mtDebugStr_t *msg;
byte mln;
byte sln;
// Text string length
sln = (byte)osal_strlen( (void*)str_ptr );
// Debug string message length
mln = sizeof ( mtDebugStr_t ) + sln;
// Get a message buffer to build the debug message
msg = (mtDebugStr_t *)osal_msg_allocate( mln );
if ( msg )
{
// Message type, length
msg->hdr.event = CMD_DEBUG_STR;
msg->sln = sln;
// Append message, no terminator
msg->pString = (uint8 *)(msg+1);
osal_memcpy ( msg->pString, str_ptr, sln );
osal_msg_send( MT_TaskID, (uint8 *)msg );
}
} // debug_str()
这里我比较关系结构
typedef struct
{
osal_event_hdr_t hdr;
uint8 sln; // String length
uint8 *pString;
} mtDebugStr_t;
这个结构有三个参数:事件句柄、长度、数据指针
3、osal_msg_send( MT_TaskID, (uint8 *)msg );
byte osal_msg_send( byte destination_task, byte *msg_ptr )
{
if ( msg_ptr == NULL )
return ( INVALID_MSG_POINTER );
if ( destination_task >= tasksCnt )
{
osal_msg_deallocate( msg_ptr );
return ( INVALID_TASK );
}
// Check the message header
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;
// queue message
osal_msg_enqueue( &osal_qHead, msg_ptr );
// Signal the task that a message is waiting
osal_set_event( destination_task, SYS_EVENT_MSG );
return ( ZSUCCESS );
}
这个函数就是发送事件,这里不做讨论,因为这涉及到OS的内容,比较麻烦!
只要知道这个时间发送到MT去了,然后只需要去看看MT的处理事件函数就可以了。
4、MTEL.C
UINT16 MT_ProcessEvent( byte task_id, UINT16 events )
{
uint8 *msg_ptr;
// Could be multiple events, so switch won't work
if ( events & SYS_EVENT_MSG )
{
while ( (msg_ptr = osal_msg_receive( MT_TaskID )) )
{
MT_ProcessCommand( (mtOSALSerialData_t *)msg_ptr );
}
// Return unproccessed events
return (events ^ SYS_EVENT_MSG);
}
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
if ( events & MT_ZTOOL_SERIAL_RCV_BUFFER_FULL )
{
// Do sometype of error processing
MT_SendErrorNotification(RECEIVE_BUFFER_FULL);
// Return unproccessed events
return (events ^ MT_ZTOOL_SERIAL_RCV_BUFFER_FULL);
}
#endif
// Discard or make more handlers
return 0;
} /* MT_ProcessEvent() */
5、MT_ProcessCommand( (mtOSALSerialData_t *)msg_ptr );
void MT_ProcessCommand( mtOSALSerialData_t *msg )
{
byte deallocate;
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
byte *msg_ptr;
byte len;
// A little setup for AF, CB_FUNC and MT_SYS_APP_RSP_MSG
msg_ptr = msg->msg;
#endif // ZTOOL
deallocate = true;
// Use the first byte of the message as the command ID
switch ( msg->hdr.event )
{
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
case CMD_SERIAL_MSG:
MT_ProcessSerialCommand( msg->msg );
break;
case CMD_DEBUG_MSG:
MT_ProcessDebugMsg( (mtDebugMsg_t *)msg );
break;
case CMD_DEBUG_STR:
MT_ProcessDebugStr( (mtDebugStr_t *)msg );
break;
case CB_FUNC:
/*
Build SPI message here instead of redundantly calling MT_BuildSPIMsg
because we have copied data already in the allocated message
*/
/* msg_ptr is the beginning of the intended SPI message */
len = SPI_0DATA_MSG_LEN + msg_ptr[DATALEN_FIELD];
/*
FCS goes to the last byte in the message and is calculated over all
the bytes except FCS and SOP
*/
msg_ptr[len-1] = SPIMgr_CalcFCS( msg_ptr + 1 , (byte)(len-2) );
#ifdef SPI_MGR_DEFAULT_PORT
HalUARTWrite ( SPI_MGR_DEFAULT_PORT, msg_ptr, len );
#endif
break;
#if !defined ( NONWK )
case MT_SYS_APP_RSP_MSG:
len = SPI_0DATA_MSG_LEN + msg_ptr[DATALEN_FIELD];
MTProcessAppRspMsg( msg_ptr, len );
break;
#endif // NONWK
#endif // ZTOOL
default:
break;
}
if ( deallocate )
{
osal_msg_deallocate( (uint8 *)msg );
}
}
这里的事件句柄为:CMD_DEBUG_STR;
6、MT_ProcessDebugStr( (mtDebugStr_t *)msg );
void MT_ProcessDebugStr( mtDebugStr_t *dstr )
{
byte *msg_ptr;
// Get a message buffer to build the debug message
msg_ptr = osal_mem_alloc( (byte)(SPI_0DATA_MSG_LEN + dstr->sln) );
if ( msg_ptr )
{
#ifdef SPI_MGR_DEFAULT_PORT
MT_BuildSPIMsg( SPI_RESPONSE_BIT | SPI_SYS_STRING_MSG, msg_ptr, dstr->sln, dstr->pString );
HalUARTWrite ( SPI_MGR_DEFAULT_PORT, msg_ptr, SPI_0DATA_MSG_LEN + dstr->sln );
#endif
osal_mem_free( msg_ptr );
}
}
7、MT_BuildSPIMsg
void MT_BuildSPIMsg( UINT16 cmd, byte *msg, byte dataLen, byte *pData )
{
byte *msgPtr;
*msg++ = SOP_VALUE;
msgPtr = msg;
*msg++ = (byte)(HI_UINT16( cmd ));
*msg++ = (byte)(LO_UINT16( cmd ));
if ( pData )
{
*msg++ = dataLen;
msg = osal_memcpy( msg, pData, dataLen );
}
else
*msg++ = 0;
*msg = SPIMgr_CalcFCS( msgPtr, (byte)(3 + dataLen) );
}
这里可以看到MSG第一个字节为:SOP_VALUE
#define SOP_VALUE 0x02
第二、三个字节为:SPI_RESPONSE_BIT | SPI_SYS_STRING_MSG,
#define SPI_RESPONSE_BIT 0x1000
#define SPI_SYS_STRING_MSG 0x0015
最后结果为:0x1015
第四个字节为:*msg++ = dataLen;数据长度
最后一个字节为*msg = SPIMgr_CalcFCS( msgPtr, (byte)(3 + dataLen) );
校验!!!!!!
8、HalUARTWrite
发送数据到串口!!!
提问:
文章评论(0条评论)
登录后参与讨论