問題背景
最近開發(fā)低功耗產(chǎn)品,工作模式為喚醒情況下正常工作,沒什么特別的,沒有外部喚醒的時(shí)候,MCU進(jìn)入STOP模式,間隔RTC喚醒(2S一次),或者外部中斷喚醒,串口為其中的一種喚醒方式。
問題:
正常工作模式下,串口收發(fā)數(shù)據(jù)幀一直運(yùn)行幾個(gè)小時(shí)都沒問題,但是在低功耗進(jìn)入STOP模式之后,通訊喚醒,主機(jī)通訊,會出現(xiàn)無法通訊的情況,過了幾秒又恢復(fù)正常,一般5S以內(nèi),偶爾較長時(shí)間,為何?
目前只是解決了問題,但是出現(xiàn)問題的原因還沒有找到,有經(jīng)驗(yàn)的小伙伴可以一起探討交流下?。?!
問題分析
正常工作模式下既然長時(shí)間工作一直不出問題,應(yīng)用層的數(shù)據(jù)通訊解析邏輯肯定是沒問題的,可以放過了。
重點(diǎn)就放在了跟串口底層相關(guān)的部分,因?yàn)樵谶M(jìn)STOP模式之前會把所有的外設(shè)處理一下,串口、DMA都會關(guān)掉,喚醒之后重新使能,問題可能出在了這里,但是分析完之后也沒有發(fā)現(xiàn)有什么異常。
既然可能是串口底層出了問題,咱們重點(diǎn)來抓一下串口底層的一些現(xiàn)象,這里HAL庫做了很多的回調(diào)函數(shù),前面4個(gè)是正常的傳輸回調(diào)函數(shù),后面幾個(gè)是異常回調(diào),既然現(xiàn)在是出現(xiàn)了問題,不妨來監(jiān)測一下看看:
void?HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef?*huart); void?HAL_UART_TxCpltCallback(UART_HandleTypeDef?*huart); void?HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef?*huart); void?HAL_UART_RxCpltCallback(UART_HandleTypeDef?*huart); void?HAL_UART_ErrorCallback(UART_HandleTypeDef?*huart); void?HAL_UART_AbortCpltCallback(UART_HandleTypeDef?*huart); void?HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef?*huart); void?HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef?*huart);
使用這個(gè),別問為啥,想瞎貓碰死耗子~~~:
void?HAL_UART_ErrorCallback(UART_HandleTypeDef?*huart);
/** ??*?@brief??UART?error?callback. ??*?@param??huart?UART?handle. ??*?@retval?None ??*/ __weak?void?HAL_UART_ErrorCallback(UART_HandleTypeDef?*
這個(gè)在HAL庫中本身是個(gè)“弱函數(shù)”,什么是“弱函數(shù)”,大家動動小手自己百度下了哈,用戶可以自己實(shí)現(xiàn)一樣的名字的函數(shù),供系統(tǒng)回調(diào),打印個(gè)提示信息看看:
void?HAL_UART_ErrorCallback(UART_HandleTypeDef?*huart)
{ ??if(huart->Instance?==?USART3) ??{ ????LOG_E("comm?error!!!"); ??} }
測試下看看,會不會出錯,從打印的信息來看,瞎貓確實(shí)碰到死耗子了..果然有錯誤,既然有錯誤了,就繼續(xù)究根刨底下去:
調(diào)用這個(gè)回調(diào)函數(shù)的地方還挺多,那究竟跟哪一個(gè)???
翻一翻,加上我們是用DMA出現(xiàn)的問題,找找跟DMA相關(guān)的,DMA傳輸錯誤會調(diào)用這個(gè)回調(diào),這個(gè)DMA錯誤在串口中斷中有調(diào)用,這樣好像就都聯(lián)系起來了:
?
?
能夠進(jìn)來這個(gè)DMA錯誤回調(diào)的條件是下面這個(gè),發(fā)生以下通訊錯誤的時(shí)候,會進(jìn)一步處理:
/**?@defgroup?UART_Error_Definition???UART?Error?Definition
??*?@{ ??*/ #define??HAL_UART_ERROR_NONE?????????????(0x00000000U)????/*!接下來檢測下發(fā)生的錯誤,每一個(gè)錯誤都打印出來:
?
?
有時(shí)候也會出現(xiàn)噪聲錯誤
錯誤對應(yīng)的是,幀錯誤,噪聲錯誤:
#define??HAL_UART_ERROR_FE???????????????(0x00000004U)????/*!定位到問題了,接下來先打個(gè)補(bǔ)丁,能夠正常使用,在錯誤回調(diào)里面清除標(biāo)志,重新DMA接收:
void?HAL_UART_ErrorCallback(UART_HandleTypeDef?*huart) { ??if(huart->Instance?==?USART3) ??{ ??????LOG_E("comm?error!!!"); ??????__HAL_UART_CLEAR_FLAG(&m_sUartxHandle,UART_CLEAR_FEF);//清除幀錯誤標(biāo)志 ?????__HAL_UART_CLEAR_FLAG(&m_sUartxHandle,USART_ICR_NECF);//清除噪聲錯誤標(biāo)志 ??????Bsw_EUART_InitVariables(); ??????HAL_UART_Receive_DMA(&m_sUartxHandle,m_Uart_DMARX_Frame.rec_buffer,DMA_REC_DATA_LEN); ??????Bsw_Uart_ReceviceCfg(ENABLE);???????????????????????????//接收配置?? ??} }目前僅僅是問題得到了解決,但是為什么出現(xiàn)這個(gè)問題還在研究中,有知道的小伙伴嗎?可以交流下!!
編輯:黃飛
?
評論
查看更多