STM32cubemx:version5.1
チップ:STM32F446RE
IDE:Keil5
Qは:シンプルな小さなプロジェクトの通信パケットに書かれた、230400ボーレートは、データ量が受信の大1600Byte / sの、DMA方式で、機械の長い部分のための大量生産の実行を見つけた受信のみを送信しないという問題点があります。
調査は見つけていません。断線検出の真ん中には、シリアルポートを再初期化しますが、解決することはできません。最後尾には、HALの鍋を見つけました。
コードの一部:
空 HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart) { もし(huart->インスタンス== UART4){ uint8_t RET = HAL_OK。 もし(frame_in_sync){ 場合(UART_Rx_Buffer.head == 0x55を && UART_Rx_Buffer.end == 0xAAを){ // TODO:チェックチェックサム UART_Rx_Data = UART_Rx_Buffer。 RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、はsizeof (UART_Rx_Buffer))。 uart_updata_time = HAL_GetTick()。 } 他 { // 同期フレームではない、端部(0xAAを)読み取るまで来るバイトをドロップ frame_in_sync = 0 。 RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、1 )。 } } 他{ 場合(*(uint8_t *)&UART_Rx_Buffer == 0xAAを){ frame_in_sync = 1 。 RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、はsizeof (UART_Rx_Buffer))。 } 他{ RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、1 )。 } } } }
上記のコードは正常にほとんどの時間を実行します。しかし、不可解な、問題が常に発生します下落しました。ダブルトラックをすることが難しいです。長い時間を検索、同様の問題を見て、HALライブラリは、ユーザプロセスに異常な動作を処理しません。
いくつかのケースでは、HAL_UART_Receive_IT戻り忙しいまたはERRO、正常に実行されなかったが、今回背面の全体のプロセスが中断しました。そして、シリアルポートは何とかロックされます。
空 HAL_UART_RxCpltCallback(UART_HandleTypeDef * huart) { もし(huart->インスタンス== UART4){ uint8_t RET = HAL_OK。 もし(frame_in_sync){ 場合(UART_Rx_Buffer.head == 0x55を && UART_Rx_Buffer.end == 0xAAを){ // TODO:チェックチェックサム UART_Rx_Data = UART_Rx_Buffer。 RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、はsizeof (UART_Rx_Buffer))。 uart_updata_time = HAL_GetTick()。 } 他 { // 同期フレームではない、端部(0xAAを)読み取るまで来るバイトをドロップ frame_in_sync = 0 。 RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、1 )。 } } 他{ 場合(*(uint8_t *)&UART_Rx_Buffer == 0xAAを){ frame_in_sync = 1 。 RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、はsizeof (UART_Rx_Buffer))。 } 他{ RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、1 )。 } } しばらく(!RET = HAL_OK){ / * 修正接続のバグしよう20191225 * / printfの(" UART4:RECEIVE_ITた:%d \ rを\ n個" 、RET)。//ログの huart - > RxState = HAL_UART_STATE_READY。 __HAL_UNLOCK(huart)。 RET = HAL_UART_Receive_IT(&huart4、(uint8_t *)&UART_Rx_Buffer、1 )。 } } } 空 HAL_UART_ErrorCallback(UART_HandleTypeDef * huart) { / * 防止、未使用の引数(s)は、コンパイルの警告* / 場合(huart->のErrorCode&HAL_UART_ERROR_ORE) { __HAL_UART_CLEAR_OREFLAG(huart)。 } / * 注:コールバックが必要な場合、この機能は、変更してはいけません、 HAL_UART_ErrorCallbackは、ユーザーのファイルに実装することができます。 * / }
修正強制ロック解除は、再び受信、忙しいかERRO表示されます。ログよると、約半分の時間は、一度表示されます。実行日、この問題は3件の定期的な更新が表示され、マシンの後に表示されません。ログに対応する修正処理を表示しています。