zigbee官方协议栈实验无线透明传输SerialApp.c解析

本文详细解析了串口传输实验中启动串口传输的过程,重点介绍了DMA配置及回调函数的实现机制,并通过源码分析揭示了串口数据收发的具体流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

绑定建立起来之后什么时候就启动串口传输了呢?

从osal_start_system这个函数开始->>Hal_ProcessPoll()

里面有如下的编译判断语句

#if (defined HAL_UART) && (HAL_UART == TRUE)
  HalUARTPoll();

由于本实验是串口传输实验判断条件成立

 HalUARTPoll();

然后-》HalUARTPollDMA()

这个函数的最后有这样一句话:

if (evt && (dmaCfg.uartCB != NULL))
  {
    dmaCfg.uartCB(HAL_UART_DMA-1, evt);
  }

进一步分析:

static uartDMACfg_t dmaCfg;

typedef struct {  

uint16 rxBuf[HAL_UART_DMA_RX_MAX];

#if HAL_UART_DMA_RX_MAX < 256   uint8 rxHead;

  uint8 rxTail; #else   uint16 rxHead;  

uint16 rxTail;

#endif  

uint8 rxTick;  

uint8 rxShdw;

  uint8 txBuf[2][HAL_UART_DMA_TX_MAX];

#if HAL_UART_DMA_TX_MAX < 256   uint8 txIdx[2];

#else   uint16 txIdx[2];

#endif  

volatile uint8 txSel;  

uint8 txMT;  

uint8 txTick;           // 1-character time in 32kHz ticks according to baud rate,                           // to be used in calculating time lapse since DMA ISR                           // to allow delay margin before start firing DMA, so that                           // DMA does not overwrite UART DBUF of previous packet     volatile uint8 txShdw;  // Sleep Timer LSB shadow.  

volatile uint8 txShdwValid; // TX shadow value is valid  

uint8 txDMAPending;     // UART TX DMA is pending

halUARTCBack_t uartCB;

} uartDMACfg_t;

那halUARTCBack_t又是什么呢?

typedef void (*halUARTCBack_t) (uint8 port, uint8 event);

他是个指针函数,也就是说dmaCfg.uartCB是个halUARTCBack_t的回调函数,那他又是在哪儿赋值的呢?

既然是回调函数,那么在要用的时候才会被赋值,我们回到void SerialApp_Init( uint8 task_id )这个函数分析,发现如下两句话:

 uartConfig.callBackFunc         = SerialApp_CallBack;
  HalUARTOpen (SERIAL_APP_PORT, &uartConfig);

先分析第一句:halUARTCfg_t   uartConfig;

typedef struct
{
  bool                configured;
  uint8               baudRate;
  bool                flowControl;
  uint16              flowControlThreshold;
  uint8               idleTimeout;
  halUARTBufControl_t rx;
  halUARTBufControl_t tx;
  bool                intEnable;
  uint32              rxChRvdTime;
  halUARTCBack_t      callBackFunc;
}halUARTCfg_t;

也就是说uartConfig.callBackFunc也是typedef void (*halUARTCBack_t) (uint8 port, uint8 event);类型的函数指针。

并且SerialApp_CallBack赋值给他uartConfig.callBackFunc,那我们会想到uartConfig.callBackFunc应该会继续把值赋值给dmaCfg.uartCB的

继续分析:

进入HalUARTOpen(uint8 port, halUARTCfg_t *config)--》》HalUARTOpenDMA(config)

发现第一句话:static void HalUARTOpenDMA(halUARTCfg_t *config)
{
  dmaCfg.uartCB = config->callBackFunc;
  // Only supporting subset of baudrate for code size - other is possible.

这下该清楚了吧,也就是说dmaCfg.uartCB最终调用的是这个函数:

static void SerialApp_CallBack(uint8 port, uint8 event)

{  

  (void)port;

  if ((event & (HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT)) &&

#if SERIAL_APP_LOOPBACK       (SerialApp_TxLen < SERIAL_APP_TX_MAX))

#else       !SerialApp_TxLen)

#endif

  {    

SerialApp_Send();  

   }

}

 然后就进入了SerialApp_Send(); 这个函数,首先读DMA,若有数据时进行发送,否则 设置事件

osal_set_event(SerialApp_TaskID, SERIALAPP_SEND_EVT);

继续查询。。。

转载于:https://www.cnblogs.com/ltfbk/archive/2013/03/29/2989005.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值