zigbee zstack 串口,按键,消息,定时器

来源:互联网 发布:解放战争 国民党 知乎 编辑:程序博客网 时间:2024/05/16 06:45

协议栈中的串口接收流程
串口在底层使用的是中断,轮询还是DMA呢??答案从下面这个文件定义的宏可以得知
在C:\Texas Instruments\ZStack-CC2530-2.3.0-1.4.0\Components\hal\target\CC2530EB\hal_board_cfg.h

[cpp] view plaincopy
  1. //默认开启DMA  
  2. #ifndef HAL_DMA  
  3.        #define HAL_DMA TRUE  
  4. #endif  
  5.   
  6. //只要定义了以下4个宏,就相当于需要使用串口  
  7. #ifndef HAL_UART  
  8.     #if (defined ZAPP_P1) || (defined ZAPP_P2) || (defined ZTOOL_P1) || (defined ZTOOL_P2)  
  9.         #define HAL_UART TRUE  
  10.     #else  
  11.         #define HAL_UART FALSE  
  12.     #endif  
  13. #endif  
  14.   
  15. // HAL_UART和HAL_DMA都已经定义过了,所以协议栈里的串口默认使用的是DMA,而不是中断  
  16. #if HAL_UART  
  17.     // Always prefer to use DMA over ISR.  
  18.     #if HAL_DMA  
  19.         #ifndef HAL_UART_DMA  
  20.             #if (defined ZAPP_P1) || (defined ZTOOL_P1)  
  21.                 #define HAL_UART_DMA  1  
  22.             #elif (defined ZAPP_P2) || (defined ZTOOL_P2)  
  23.                 #define HAL_UART_DMA  2  
  24.             #else  
  25.                 #define HAL_UART_DMA  1  
  26.             #endif  
  27.         #endif  
  28.         #define HAL_UART_ISR  0  
  29.     #else  
  30.         #ifndef HAL_UART_ISR  
  31.             #if (defined ZAPP_P1) || (defined ZTOOL_P1)  
  32.             #define HAL_UART_ISR  1  
  33.             #elif (defined ZAPP_P2) || (defined ZTOOL_P2)  
  34.             #define HAL_UART_ISR  2  
  35.             #else  
  36.             #define HAL_UART_ISR  1  
  37.             #endif  
  38.         #endif  
  39.         #define HAL_UART_DMA  0  
  40.     #endif  
  41.   
  42.     // Used to set P2 priority - USART0 over USART1 if both are defined.  
  43.     #if ((HAL_UART_DMA == 1) || (HAL_UART_ISR == 1))  
  44.         #define HAL_UART_PRIPO             0x00  
  45.         #else  
  46.         #define HAL_UART_PRIPO             0x40  
  47.     #endif  
  48.   
  49. #else//否则  
  50.     #define HAL_UART_DMA  0  
  51.     #define HAL_UART_ISR  0  
  52. #endif  

在某个应用的初始化函数中顺序执行下面两个函数,比如在SampleApp_Init函数中,
  MT_UartInit();
  MT_UartRegisterTaskID(task_id);
MT_UartRegisterTaskID//用于给SampleApp注册串口,这样当串口在MT_UartProcessZToolData(mt_uart.c)发数据到上层时,会发到SampleApp。如果多个app都执行了MT_UartRegisterTaskID,则最后一个注册的有效,因为前面的被覆盖掉了。
void MT_UartRegisterTaskID( byte taskID )
{
  App_TaskID = taskID;
}

比如,在osalInitTasks函数中
[cpp] view plaincopy
  1. void osalInitTasks( void )  
  2. {  
  3.   uint8 taskID = 0;  
  4.   
  5.   tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);  
  6.   osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));  
  7.   
  8.   macTaskInit( taskID++ );  
  9.   nwk_init( taskID++ );  
  10.   Hal_Init( taskID++ );  
  11. #if defined( MT_TASK )  
  12.   MT_TaskInit( taskID++ );//会执行MT_UartRegisterTaskID函数  
  13. #endif  
  14.   APS_Init( taskID++ );  
  15. #if defined ( ZIGBEE_FRAGMENTATION )  
  16.   APSF_Init( taskID++ );  
  17. #endif  
  18.   ZDApp_Init( taskID++ );  
  19. #if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )  
  20.   ZDNwkMgr_Init( taskID++ );  
  21. #endif  
  22.   SampleApp_Init( taskID );//会执行MT_UartRegisterTaskID函数,把MT_TaskInit函数注册的串口覆盖掉了。串口有数据发给上层时,SampleApp会收到消息。  
  23. }  

MT_UartInit将会指定串口有数据到来时,调用哪个callback函数来处理。如果在option的preprocessor中定义了ZTOOL_P1即串口0(cc2530有2个串口,ZTOOL_P2或ZAPP_P2代表串口1),则调用的是MT_UartProcessZToolData,见下面

[cpp] view plaincopy
  1. /*************************************************************************************************** 
  2.  * @fn      MT_UartInit 
  3.  * 
  4.  * @brief   Initialize MT with UART support 
  5.  * 
  6.  * @param   None 
  7.  * 
  8.  * @return  None 
  9. ***************************************************************************************************/  
  10. void MT_UartInit ()  
  11. {  
  12.   halUARTCfg_t uartConfig;  
  13.   
  14.   /* Initialize APP ID */  
  15.   App_TaskID = 0;  
  16.   
  17.   /* UART Configuration */  
  18.   uartConfig.configured           = TRUE;  
  19.   uartConfig.baudRate             = MT_UART_DEFAULT_BAUDRATE;  
  20.   uartConfig.flowControl          = MT_UART_DEFAULT_OVERFLOW;  
  21.   uartConfig.flowControlThreshold = MT_UART_DEFAULT_THRESHOLD;  
  22.   uartConfig.rx.maxBufSize        = MT_UART_DEFAULT_MAX_RX_BUFF;  
  23.   uartConfig.tx.maxBufSize        = MT_UART_DEFAULT_MAX_TX_BUFF;  
  24.   uartConfig.idleTimeout          = MT_UART_DEFAULT_IDLE_TIMEOUT;  
  25.   uartConfig.intEnable            = TRUE;  
  26. #if defined (ZTOOL_P1) || defined (ZTOOL_P2)  
  27.   uartConfig.callBackFunc         = MT_UartProcessZToolData;  
  28. #elif defined (ZAPP_P1) || defined (ZAPP_P2)  
  29.   uartConfig.callBackFunc         = MT_UartProcessZAppData;  
  30. #else  
  31.   uartConfig.callBackFunc         = NULL;  
  32. #endif  
  33.   
  34.   /* Start UART */  
  35. #if defined (MT_UART_DEFAULT_PORT)//默认串口,如果定义了ZTOOL_P1则是串口0,ZTOOL_P2则是串口1  
  36.   HalUARTOpen (MT_UART_DEFAULT_PORT, &uartConfig);  
  37. #else  
  38.   /* Silence IAR compiler warning */  
  39.   (void)uartConfig;  
  40. #endif  
  41.   
  42.   /* Initialize for ZApp */  
  43. #if defined (ZAPP_P1) || defined (ZAPP_P2)  
  44.   /* Default max bytes that ZAPP can take */  
  45.   MT_UartMaxZAppBufLen  = 1;  
  46.   MT_UartZAppRxStatus   = MT_UART_ZAPP_RX_READY;  
  47. #endif  
  48.   
  49. }  

MT_UartProcessZToolData用于处理串口接收缓冲区的数据,pMsg->msg的结构体的数据如下

[cpp] view plaincopy
  1. /*************************************************************************************************** 
  2.  * @fn      MT_UartProcessZToolData 
  3.  * 
  4.  * @brief   | SOP | Data Length  |   CMD   |   Data   |  FCS  | 
  5.  *          |  1  |         1    |      2  |  0-Len   |   1   | 
  6.  * 
  7.  *          Parses the data and determine either is SPI or just simply serial data 
  8.  *          then send the data to correct place (MT or APP) 
  9.  * 
  10.  * @param   port     - UART port 
  11.  *          event    - Event that causes the callback 
  12.  * 
  13.  * 
  14.  * @return  None 
  15.  ***************************************************************************************************/  
  16. void MT_UartProcessZToolData ( uint8 port, uint8 event )  
  17. {  
  18.   uint8  ch;  
  19.   uint8  bytesInRxBuffer;  
  20.     
  21.   (void)event;  // Intentionally unreferenced parameter  
  22.   
  23.   while (Hal_UART_RxBufLen(port))  
  24.   {  
  25.     HalUARTRead (port, &ch, 1);//每次读一个字节  
  26.   
  27.     switch (state)  
  28.     {  
  29.       case SOP_STATE://0  
  30.         if (ch == MT_UART_SOF)// 如果读到的字符时Start-of-frame即0xFE,则进入LEN_STAT状态,进行读LEN  
  31.           state = LEN_STATE;  
  32.         break;  
  33.   
  34.       case LEN_STATE://1  
  35.         LEN_Token = ch;//消息的长度  
  36.   
  37.         tempDataLen = 0;  
  38.   
  39.         /* Allocate memory for the data */  
  40.         pMsg = (mtOSALSerialData_t *)osal_msg_allocate( sizeof ( mtOSALSerialData_t ) +  
  41.                                                         MT_RPC_FRAME_HDR_SZ + LEN_Token );  
  42.   
  43.         if (pMsg)  
  44.         {  
  45.           /* Fill up what we can */  
  46.           pMsg->hdr.event = CMD_SERIAL_MSG;  
  47.           pMsg->msg = (uint8*)(pMsg+1);  
  48.           pMsg->msg[MT_RPC_POS_LEN] = LEN_Token;//pMsg->msg[0]=len  
  49.           state = CMD_STATE1;//读完长度,就进入CMD_STATE1状态,进行读命令  
  50.         }  
  51.         else  
  52.         {  
  53.           state = SOP_STATE;  
  54.           return;  
  55.         }  
  56.         break;  
  57.   
  58.       case CMD_STATE1:  
  59.         pMsg->msg[MT_RPC_POS_CMD0] = ch;//pMsg->msg[1]=命令低字节  
  60.         state = CMD_STATE2;  
  61.         break;  
  62.   
  63.       case CMD_STATE2:  
  64.         pMsg->msg[MT_RPC_POS_CMD1] = ch;//pMsg->msg[2]=命令高字节  
  65.         /* If there is no data, skip to FCS state */  
  66.         if (LEN_Token)  
  67.         {  
  68.           state = DATA_STATE;//读完命令,如果数据长度不为0,就进入DATA_STATE状态,进行读数据  
  69.         }  
  70.         else  
  71.         {  
  72.           state = FCS_STATE;//否则进入FCS_STATE状态,进行校验  
  73.         }  
  74.         break;  
  75.   
  76.       case DATA_STATE:  
  77.   
  78.         /* Fill in the buffer the first byte of the data */  
  79.         pMsg->msg[MT_RPC_FRAME_HDR_SZ + tempDataLen++] = ch;  
  80.   
  81.         /* Check number of bytes left in the Rx buffer */  
  82.         bytesInRxBuffer = Hal_UART_RxBufLen(port);  
  83.   
  84.         /* If the remain of the data is there, read them all, otherwise, just read enough,读数量较小的数据 */  
  85.         if (bytesInRxBuffer <= LEN_Token - tempDataLen)//如果剩余数据<=len-已读长度,全部读出  
  86.         {  
  87.           HalUARTRead (port, &pMsg->msg[MT_RPC_FRAME_HDR_SZ + tempDataLen], bytesInRxBuffer);  
  88.           tempDataLen += bytesInRxBuffer;  
  89.         }  
  90.         else//否则只读出(len-已读长度)的数据  
  91.         {  
  92.           HalUARTRead (port, &pMsg->msg[MT_RPC_FRAME_HDR_SZ + tempDataLen], LEN_Token - tempDataLen);  
  93.           tempDataLen += (LEN_Token - tempDataLen);  
  94.         }  
  95.   
  96.         /* If number of bytes read is equal to data length, time to move on to FCS */  
  97.         if ( tempDataLen == LEN_Token )  
  98.             state = FCS_STATE;  
  99.   
  100.         break;  
  101.   
  102.       case FCS_STATE:  
  103.   
  104.         FSC_Token = ch;  
  105.   
  106.         /* Make sure it's correct */  
  107.         if ((MT_UartCalcFCS ((uint8*)&pMsg->msg[0], MT_RPC_FRAME_HDR_SZ + LEN_Token) == FSC_Token))//计算fcs  
  108.         {  
  109.           osal_msg_send( App_TaskID, (byte *)pMsg );  
  110.         }  
  111.         else  
  112.         {  
  113.           /* deallocate the msg */  
  114.           osal_msg_deallocate ( (uint8 *)pMsg );  
  115.         }  
  116.   
  117.         /* Reset the state, send or discard the buffers at this point */  
  118.         state = SOP_STATE;  
  119.   
  120.         break;  
  121.   
  122.       default:  
  123.        break;  
  124.     }  
  125.   }  
  126. }  

所以如果PC发数据给zigbee串口,需要先发送FE...或者修改这个MT_UartProcessZToolData函数以适应自己的应用

协议栈中的串口发送流程

在某个app_init()中初始化和注册串口(如果此app不需要接收数据,可以不用注册)
直接使用如下代码发送数据即可
 HalUARTWrite(0,"Hello World\n",12);
如果在opention中定义了MT_TASK,则在发送实际的数据之前会发送一个11字节的数据头(下行红色数据),在PC接收到如下形式的数据:
FE 06 41 80 01 02 00 02 03 00 C5 48 65 6C 6C 6F 20 57 6F 72 6C 64 0A 
后面黑色字体的12个字节才是真正的数据

MT_TASK取消定义则直接发送真实的数据


关于串口buffer的和应用层的串口帧大小的关系:
cc2530的串口buffer是1字节,可以看出串口帧的大小与串口buffer没啥关系,因为帧大小一般总是大于1字节的。
U0DBUF (0xC1) – USART 0 Receive/Transmit Data Buffer
这也说明串口在最低层发送的时候,是把上层给的数据一个字节一个字节的塞进buffer里面发出去的)
但是在协议栈中只要发送的串口帧大于128字节,就发不出去,这是因为单片机内存分给帧最大长度是128字节造成的。位于OnBoard.h。可修改之。

#define MT_UART_TX_BUFF_MAX  128
#define MT_UART_RX_BUFF_MAX  128

如果你想要发送大于128字节的帧而不愿意修改上面的宏,可以在while里面用HalUARTWrite一个字节一个字节的发,每发出一个字节执行一次HalUARTPoll。(相当于flush)。



协议栈中的按键流程
以其为例C:\Texas Instruments\ZStack-CC2530-2.3.0-1.4.0\Projects\zstack\Samples\SampleApp
1.在main函数中会执行InitBoard(),用于初始化led和按键
OnBoard.c
[cpp] view plaincopy
  1. void InitBoard( uint8 level )  
  2. {  
  3.   if ( level == OB_COLD )  
  4.   {  
  5.     // Interrupts off  
  6.     osal_int_disable( INTS_ALL );  
  7.     // Turn all LEDs off  
  8.     HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF );  
  9.     // Check for Brown-Out reset  
  10.     ChkReset();  
  11.   }  
  12.   else  // !OB_COLD  
  13.   {  
  14.     /* Initialize Key stuff */  
  15.     OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;//此处需要使能按键中断  
  16.     HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);//配置按键终端产生之后,触发OnBoard_KeyCallback函数  
  17.   }  
  18. }  

配置函数HalKeyConfig,用于配置哪个按键(哪个端口)
回调函数OnBoard_KeyCallback,此函数执行OnBoard_SendKeys,将按键事件发给上层注册按键的应用

2.在SampleApp_Init()函数中注册按键,这样以后有按键事件发生时,才会将消息发送到SampleApp应用
RegisterForKeys( SampleApp_TaskID );
如果按键已被注册,则后来注册的就会失败。
uint8 RegisterForKeys( uint8 task_id )
{
  // Allow only the first task
  if ( registeredKeysTaskID == NO_TASK_ID )
  {
    registeredKeysTaskID = task_id;
    return ( true );
  }
  else
    return ( false );
}
类似于注册串口,但串口刚好相反。


不管有没有使用中断,对于button1和joystick的按键,都会响应
如果按键没有启用中断,则会每隔100ms轮询一次按键状态,见下
如果注册了中断,则在按键中断发生时,会触发hal_key.c中的中断处理函数,注意kal_key.c中只注册了p2和p0口的中断处理函数,见下
 **************************************************************************************************/
HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR )
{
  if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT)
  {
    halProcessKeyInterrupt();
  }
  /*
    Clear the CPU interrupt flag for Port_2
    PxIFG has to be cleared before PxIF
    Notes: P2_1 and P2_2 are debug lines.
  */
  HAL_KEY_JOY_MOVE_PXIFG = 0;
  HAL_KEY_CPU_PORT_2_IF = 0;
}

HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
{
  if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)
  {
    halProcessKeyInterrupt();
  }
  /*
    Clear the CPU interrupt flag for Port_0
    PxIFG has to be cleared before PxIF
  */

  HAL_KEY_SW_6_PXIFG = 0;
  HAL_KEY_CPU_PORT_0_IF = 0;
}


halProcessKeyInterrupt 只是中断标志。没有对中断做具体处理,同时延时25ms设置一个HAL_KEY_EVENT事件,让Hal_TaskID去处理。延时的目的是去抖动。
void halProcessKeyInterrupt (void)
{
  bool valid=FALSE;
  if (HAL_KEY_SW_6_PXIFG & HAL_KEY_SW_6_BIT)  /* Interrupt Flag has been set */
  {
    HAL_KEY_SW_6_PXIFG = ~(HAL_KEY_SW_6_BIT); /* Clear Interrupt Flag */
    valid = TRUE;
  }
  if (HAL_KEY_JOY_MOVE_PXIFG & HAL_KEY_JOY_MOVE_BIT)  /* Interrupt Flag has been set */
  {
    HAL_KEY_JOY_MOVE_PXIFG = ~(HAL_KEY_JOY_MOVE_BIT); /* Clear Interrupt Flag */
    valid = TRUE;
  }
  if (valid)
  {
    osal_start_timerEx (Hal_TaskID, HAL_KEY_EVENT, HAL_KEY_DEBOUNCE_VALUE);//
  }
}

在循环任务中有一个Hal_ProcessEvent (hal_driver.c) ,

  if (events & HAL_KEY_EVENT)
  {
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
    /* Check for keys */
    HalKeyPoll();//读取时按个按键
    /* if interrupt disabled, do next polling */
    if (!Hal_KeyIntEnable)//如果没有使用中断,就重新延时100ms设置事件HAL_KEY_EVENT。从此处可以看出,如果按键没有启用中断,则会每隔100ms轮询一次按键状态
    {
      osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);
    }
#endif // HAL_KEY
    return events ^ HAL_KEY_EVENT;
  }



其调用了HalKeyPoll(hal_key.c),在这个函数中
 **************************************************************************************************/
void HalKeyPoll (void)
{
  uint8 keys = 0;
//读取joystick的状态
  if ((HAL_KEY_JOY_MOVE_PORT & HAL_KEY_JOY_MOVE_BIT))  /* Key is active HIGH */
  {
    keys = halGetJoyKeyInput();//返回joystick的哪个按键按下
  }
  /* If interrupts are not enabled, previous key status and current key status
   * are compared to find out if a key has changed status.
   */
  if (!Hal_KeyIntEnable)//如果没有启动中断
  {
    if (keys == halKeySavedKeys)
    {
      /* Exit - since no keys have changed */
      return;
    }
    /* Store the current keys for comparation next time */
    halKeySavedKeys = keys;
  }
  else
  {
    /* Key interrupt handled here */
  }

//读取button1状态,
  if (HAL_PUSH_BUTTON1())//返回button1是否按下
  {
    keys |= HAL_KEY_SW_6;
  }

//如果按键按下设置了回调函数,就调用回调函数,如下
  /* Invoke Callback if new keys were depressed */
  if (keys && (pHalKeyProcessFunction))
  {
    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
  }
}

onboard.c中定义了回调函数
 *********************************************************************/
void OnBoard_KeyCallback ( uint8 keys, uint8 state )
{
  uint8 shift;
  (void)state;

  /* Get shift key status */
  shift = ((keys & HAL_KEY_SW_6) ? true : false);

  if ( OnBoard_SendKeys( keys, shift ) != ZSuccess )//如果上传消息失败(即应用层没有注册按键事件),就就地处理。
  {
    // Process SW1 here
    if ( keys & HAL_KEY_SW_1 )  // Switch 1
    {
    }
    // Process SW2 here
    if ( keys & HAL_KEY_SW_2 )  // Switch 2
    {
    }
    // Process SW3 here
    if ( keys & HAL_KEY_SW_3 )  // Switch 3
    {
    }
    // Process SW4 here
    if ( keys & HAL_KEY_SW_4 )  // Switch 4
    {
    }
    // Process SW5 here
    if ( keys & HAL_KEY_SW_5 )  // Switch 5
    {
    }
    // Process SW6 here
    if ( keys & HAL_KEY_SW_6 )  // Switch 6
    {
    }
  }
}


由上可知,
/* Switches (keys) */
#define HAL_KEY_SW_1 0x01  // Joystick up
#define HAL_KEY_SW_2 0x02  // Joystick right
#define HAL_KEY_SW_5 0x04  // Joystick center
#define HAL_KEY_SW_4 0x08  // Joystick left
#define HAL_KEY_SW_3 0x10  // Joystick down
#define HAL_KEY_SW_6 0x20  // Button S1 if available
协议栈中只对这6个按键由响应。而HalKeyConfig (hal_key.c) 函数中也只是对这6个按键进行了配置。
协议栈中的消息流程

3个不得不知道的结构体
[cpp] view plaincopy
  1. typedef struct  
  2. {  
  3.   void   *next;  
  4.   uint16 len;  
  5.   uint8  dest_id;  
  6. } osal_msg_hdr_t;  
  7.   
  8. typedef struct  
  9. {  
  10.   uint8  event;  
  11.   uint8  status;  
  12. } osal_event_hdr_t;  
  13.   
  14. typedef void * osal_msg_q_t;  

[cpp] view plaincopy
  1. //无线收到数据向上层发送的消息  
  2. typedef struct  
  3. {  
  4.   osal_event_hdr_t hdr;     /* OSAL Message header */  
  5.   uint16 groupId;           /* Message's group ID - 0 if not set */  
  6.   uint16 clusterId;         /* Message's cluster ID */  
  7.   afAddrType_t srcAddr;     /* Source Address, if endpoint is STUBAPS_INTER_PAN_EP, 
  8.                                it's an InterPAN message */  
  9.   uint16 macDestAddr;       /* MAC header destination short address */  
  10.   uint8 endPoint;           /* destination endpoint */  
  11.   uint8 wasBroadcast;       /* TRUE if network destination was a broadcast address */  
  12.   uint8 LinkQuality;        /* The link quality of the received data frame */  
  13.   uint8 correlation;        /* The raw correlation value of the received data frame */  
  14.   int8  rssi;               /* The received RF power in units dBm */  
  15.   uint8 SecurityUse;        /* deprecated */  
  16.   uint32 timestamp;         /* receipt timestamp from MAC */  
  17.   afMSGCommandFormat_t cmd; /* Application Data */  
  18. } afIncomingMSGPacket_t;  
  19.   
  20. //按键按下时向上层发送的消息格式  
  21. typedef struct  
  22. {  
  23.   osal_event_hdr_t hdr;  
  24.   uint8             state; // shift  
  25.   uint8             keys;  // keys  
  26. } keyChange_t;  
  27.   
  28. //串口接到数据向上层发送的消息  
  29. typedef struct  
  30. {  
  31.   osal_event_hdr_t  hdr;  
  32.   uint8             *msg;  
  33. } mtOSALSerialData_t;  


定时器
cc2530-ZStack-CC2530-2.3.0-1.4.0

Hal_timer.c
 NOTE: The following mapping is done between the logical timer
       names defined in HAL_TIMER.H and the physical HW timer.


       HAL_TIMER_0 --> HW Timer 3  (8-bits)
       HAL_TIMER_2 --> HW Timer 4  (8-bits)
       HAL_TIMER_3 --> HW Timer 1  (16-bits)


 NOTE: The timer code assumes only one channel, CHANNEL 0, is used
       for each timer.  There is currently no support for other
       channels.


HAL_ISR_FUNCTION( halTimer1Isr, T1_VECTOR )
{
  halProcessTimer1 ();//是真实的硬件定时器1处理函数,默认没有开启
}

HAL_ISR_FUNCTION( halTimer3Isr, T3_VECTOR )
{
  halProcessTimer3 ();//是真实的硬件定时器3处理函数,默认没有开启
}

HAL_ISR_FUNCTION( halTimer4Isr, T4_VECTOR )
{
  halProcessTimer4 ();//是真实的硬件定时器4处理函数,默认没有开启
}


还有一个硬件定时器2,也是mac timer,已被协议栈占用
mac_mcu.c
/**************************************************************************************************
 * @fn          macMcuTimer2Isr
 *
 * @brief       Interrupt service routine for timer2, the MAC timer.
 *
 * @param       none
 *
 * @return      none
 **************************************************************************************************
 */
HAL_ISR_FUNCTION( macMcuTimer2Isr, T2_VECTOR )


osal_start_timerEx使用的是
mac timer
但是osal_start_timerEx最快可以实现1ms的定时,而我测在mac timer的中断处理函数中使用P1_1=!P1_1测得的中断周期却大于100ms.?????
是使用的mac tiemr吗???
如下是说是使用的MAC backoff timer,这个timer又是啥玩意?
/*********************************************************************
 * @fn      osalTimeUpdate
 *
 * @brief   Uses the free running rollover count of the MAC backoff timer;
 *          this timer runs freely with a constant 320 usec interval.  The
 *          count of 320-usec ticks is converted to msecs and used to update
 *          the OSAL clock and Timers by invoking osalClockUpdate() and
 *          osalTimerUpdate().  This function is intended to be invoked 
 *          from the background, not interrupt level.
 *
 * @param   None.
 *
 * @return  None.
 */
void osalTimeUpdate( void )
原创粉丝点击