新闻  |   论坛  |   博客  |   在线研讨会
SimpleApp例子串口出现乱码的原因?
0750long | 2009-05-26 18:53:45    阅读:2319   发布文章

SimpleApp例子串口出现乱码的原因?

 

问题出现可以参看从零开始学习ZSTACK9文章

http://www.yyytech.cn/Tech/Read.aspx?id=264

提问:

“每次发射开始时候会发送乱码出来? 

我跟踪代码发现是DMA开始的时候发出来的?

难道是FIFO里面的随机数?

但是为什么每次都一样呢?

百思不得其解!!!!寻求帮忙~“

 解答:

下面我们来跟踪下串口发送程序:

1、首先看看SimpleApp.c文件的函数zb_ReceiveDataIndication()最后一句话为向串口发数据的。

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

发送数据到串口!!!

 

提问:

麻烦你看下截图:我仿真完 *msg++ = SOP_VALUE; msg[0]却=0x00
                         等仿真到如图却变成了1015   02怎么没了?
 
点击看大图
 
解答:
找到问题原因了。
因为*MSG=2之后呢,MSG++了,所以此时的MSG[0]已经是之前的*(MSG+1)了。建议用存储器观察!
 
点击看大图

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客