如何解决因CC2530重复触发串口回调函数导致程序卡死的问题
https://blog.youkuaiyun.com/zzz_xxj/article/details/80389531
原因:当使用CC2530的串口时,协议栈会生成一个串口发送事件,在执行该事件的时候也会触发相应的串口回调函数,导致回调函数被重复调用。
解决方法:在_hal_uart_dma.c文件中找到static void HalUARTPollDMA(void)函数,然后找到if (dmaCfg.txMT)语句,将这个判断语句注释掉,即可解决回调函数重复调用问题。
详细代码如下:
-
/****************************************************************************** -
* @fn HalUARTPollDMA -
* -
* @brief Poll a USART module implemented by DMA. -
* -
* @param none -
* -
* @return none -
*****************************************************************************/ -
static void HalUARTPollDMA(void) -
{ -
uint16 cnt = 0; -
uint8 evt = 0; -
if (HAL_UART_DMA_NEW_RX_BYTE(dmaCfg.rxHead)) -
{ -
uint16 tail = findTail(); -
// If the DMA has transferred in more Rx bytes, reset the Rx idle timer. -
if (dmaCfg.rxTail != tail) -
{ -
dmaCfg.rxTail = tail; -
// Re-sync the shadow on any 1st byte(s) received. -
if (dmaCfg.rxTick == 0) -
{ -
dmaCfg.rxShdw = ST0; -
} -
dmaCfg.rxTick = HAL_UART_DMA_IDLE; -
} -
else if (dmaCfg.rxTick) -
{ -
// Use the LSB of the sleep timer (ST0 must be read first anyway). -
uint8 decr = ST0 - dmaCfg.rxShdw; -
if (dmaCfg.rxTick > decr) -
{ -
dmaCfg.rxTick -= decr; -
dmaCfg.rxShdw = ST0; -
} -
else -
{ -
dmaCfg.rxTick = 0; -
} -
} -
cnt = HalUARTRxAvailDMA(); -
} -
else -
{ -
dmaCfg.rxTick = 0; -
} -
if (cnt >= HAL_UART_DMA_FULL) -
{ -
evt = HAL_UART_RX_FULL; -
} -
else if (cnt >= HAL_UART_DMA_HIGH) -
{ -
evt = HAL_UART_RX_ABOUT_FULL; -
PxOUT |= HAL_UART_Px_RTS; -
} -
else if (cnt && !dmaCfg.rxTick) -
{ -
evt = HAL_UART_RX_TIMEOUT; -
} -
/****************以下代码会重复触发串口回调函数,所以注释掉*************************/ -
// if (dmaCfg.txMT) -
// { -
// dmaCfg.txMT = FALSE; -
// evt |= HAL_UART_TX_EMPTY; -
// } -
/*********************************************************************************/ -
if (dmaCfg.txShdwValid) -
{ -
uint8 decr = ST0; -
decr -= dmaCfg.txShdw; -
if (decr > dmaCfg.txTick) -
{ -
// No protection for txShdwValid is required -
// because while the shadow was valid, DMA ISR cannot be triggered -
// to cause concurrent access to this variable. -
dmaCfg.txShdwValid = FALSE; -
} -
} -
if (dmaCfg.txDMAPending && !dmaCfg.txShdwValid) -
{ -
// UART TX DMA is expected to be fired and enough time has lapsed since last DMA ISR -
// to know that DBUF can be overwritten -
halDMADesc_t *ch = HAL_DMA_GET_DESC1234(HAL_DMA_CH_TX); -
halIntState_t intState; -
// Clear the DMA pending flag -
dmaCfg.txDMAPending = FALSE; -
HAL_DMA_SET_SOURCE(ch, dmaCfg.txBuf[dmaCfg.txSel]); -
HAL_DMA_SET_LEN(ch, dmaCfg.txIdx[dmaCfg.txSel]); -
dmaCfg.txSel ^= 1; -
HAL_ENTER_CRITICAL_SECTION(intState); -
HAL_DMA_ARM_CH(HAL_DMA_CH_TX); -
do -
{ -
asm("NOP"); -
} while (!HAL_DMA_CH_ARMED(HAL_DMA_CH_TX)); -
HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_TX); -
HAL_DMA_MAN_TRIGGER(HAL_DMA_CH_TX); -
HAL_EXIT_CRITICAL_SECTION(intState); -
} -
else -
{ -
halIntState_t his; -
HAL_ENTER_CRITICAL_SECTION(his); -
if ((dmaCfg.txIdx[dmaCfg.txSel] != 0) && !HAL_DMA_CH_ARMED(HAL_DMA_CH_TX) -
&& !HAL_DMA_CHECK_IRQ(HAL_DMA_CH_TX)) -
{ -
HAL_EXIT_CRITICAL_SECTION(his); -
HalUARTIsrDMA(); -
} -
else -
{ -
HAL_EXIT_CRITICAL_SECTION(his); -
} -
} -
if (evt && (dmaCfg.uartCB != NULL)) -
{ -
dmaCfg.uartCB(HAL_UART_DMA-1, evt); -
} -
}
本文解决CC2530串口使用中,因重复触发串口回调函数导致程序卡死的问题。通过修改_hal_uart_dma.c文件中的HalUARTPollDMA函数,注释掉特定代码段,防止回调函数重复调用。
3759

被折叠的 条评论
为什么被折叠?



