STM32F4 HAL庫串口死鎖問題調試記錄

文章目錄

  • STM32F4 HAL庫串口死鎖問題調試記錄
      • 調試方法
      • 結果
      • 分析
      • 解決
        • 方法一:
        • 方法二:

STM32F4 HAL庫串口死鎖問題調試記錄

使用方法:通過串口DMA固定周期向外發送數據,同時開啟串口DMA接收用于接收其它板卡發來的數據。
問題:在程序運行一段時間后會出現程序不再接收數據的情況,但向外發送數據正常。
分析:一開始認為是觸發了串口ORE錯誤導致的這個問題呢,但奇怪的是并沒有觸發串口錯誤中斷的回調函數,通過進一步分析排查發現是由__HAL_LOCK()引起的,而串口ORE錯誤是在觸發這個問題之后出現的。

調試方法

  1. 通過如下函數開啟串口DMA接收
HAL_UARTEx_ReceiveToIdle_DMA(&JOYSTICK_HUART, joystick_uart_buffer, JOYSTICK_UART_BUFFER_SIZE);
  1. 通過如下函數以10ms周期定時向外發送數據
HAL_UART_Transmit_DMA(&JOYSTICK_HUART,(uint8_t*)&joystick_display_frame,sizeof(JoystickDisplayFrame_t));
  1. 實現串口DMA+IDLE中斷接收回調函數
uint32_t huart2_err_cnt = 0;
uint32_t aaa[10] = {0};
HAL_StatusTypeDef huart2_status1;
HAL_StatusTypeDef huart2_status2;uint32_t tx_lock_cnt = 0;
uint32_t tx_unlock_cnt = 0;
uint8_t rx_irq_flag = 0;void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {uart_rx_event_cnt++;huart2_status1 = HAL_UARTEx_ReceiveToIdle_DMA(&JOYSTICK_HUART, joystick_uart_buffer, JOYSTICK_UART_BUFFER_SIZE);if(huart2_status1 != HAL_OK) {huart2_err_cnt++;rx_irq_flag = 1;/* 根據相應的錯誤類型清除相應的錯誤標志 */if(__HAL_UART_GET_FLAG(&JOYSTICK_HUART, UART_FLAG_ORE) != RESET) {__HAL_UART_CLEAR_OREFLAG(&JOYSTICK_HUART); //清除ORE溢出錯誤標志,(讀SR然后讀DR,這里用于清除串口錯誤標志)aaa[0]++;} else if(__HAL_UART_GET_FLAG(&JOYSTICK_HUART, UART_FLAG_FE) != RESET) {__HAL_UART_CLEAR_FEFLAG(&JOYSTICK_HUART); //清除FE幀錯誤標志aaa[1]++;} else if(__HAL_UART_GET_FLAG(&JOYSTICK_HUART, UART_FLAG_PE) != RESET) {__HAL_UART_CLEAR_PEFLAG(&JOYSTICK_HUART); //清除PE奇偶校驗錯誤標志aaa[2]++;} else if(__HAL_UART_GET_FLAG(&JOYSTICK_HUART, UART_FLAG_NE) != RESET) {__HAL_UART_CLEAR_NEFLAG(&JOYSTICK_HUART); //清除NE噪聲錯誤標志aaa[3]++;}huart2_status2 = HAL_UARTEx_ReceiveToIdle_DMA(&JOYSTICK_HUART, joystick_uart_buffer, JOYSTICK_UART_BUFFER_SIZE);}
}
  1. 實現串口錯誤中斷回調函數
uint32_t uart_error_cnt = 0; //記錄是否進入串口錯誤中斷
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart) {uart_error_cnt++;// 其它處理
}
  1. 改造HAL庫串口DMA發送函數來驗證問題
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{uint32_t *tmp;/* Check that a Tx process is not already ongoing */if (huart->gState == HAL_UART_STATE_READY){if ((pData == NULL) || (Size == 0U)){return HAL_ERROR;}/* Process Locked */__HAL_LOCK(huart);if(rx_irq_flag == 0) {tx_lock_cnt++;}// 省略中間的處理/* Process Unlocked */__HAL_UNLOCK(huart);if(rx_irq_flag == 0) {tx_unlock_cnt++;}/* Enable the DMA transfer for transmit request by setting the DMAT bitin the UART CR3 register */ATOMIC_SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);return HAL_OK;}else{return HAL_BUSY;}
}

結果

下圖為出錯時對應的變量值
第一次測試結果:
在這里插入圖片描述
第二次測試結果:
在這里插入圖片描述

分析

  1. 根據上面的結果可以看出:程序在執行發送函數中的__HAL_LOCK(huart)串口加鎖函數后,__HAL_UNLOCK(huart)串口解鎖函數前觸發了串口IDLE中斷,此時由于串口處于鎖定狀態,執行HAL_UARTEx_ReceiveToIdle_DMA()函數會直接返回HAL_BUSY(即2)的狀態,導致出現了錯誤。
  2. 根據aaa[0]的值可以判定此時尚未出現串口ORE的報錯,而usart2_sr串口狀態寄存器的值顯示當前出現了串口ORE錯誤,這個錯誤是由于后續又繼續收到數據導致的。
  3. 根據usart2_cr串口控制寄存器1的值可以看出IDLEIE中斷使能標志位現在為0,因而不會繼續觸發串口IDLE接收中斷了,自然就不會繼續執行回調函數的內容了

解決

STM32串口是支持全雙工工作的,按理說收發可以做到完全互不干擾,但是串口鎖定處理的這段時間確實會影響全雙工的性能。程序同時高頻接收和高頻發送時可能會有比較高的概率出現該問題。

方法一:

屏蔽掉HAL庫中關于串口鎖的函數(不推薦)

方法二:

觸發這種情況時添加串口解鎖處理

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) {uart_rx_event_cnt++;huart2_status1 = HAL_UARTEx_ReceiveToIdle_DMA(&JOYSTICK_HUART, joystick_uart_buffer, JOYSTICK_UART_BUFFER_SIZE);if(huart2_status1 != HAL_OK) {huart2_err_cnt++;JOYSTICK_HUART.RxState = HAL_UART_STATE_READY;JOYSTICK_HUART.Lock = HAL_UNLOCKED; //或者調用 __HAL_UNLOCK(&JOYSTICK_HUART);huart2_status2 = HAL_UARTEx_ReceiveToIdle_DMA(&JOYSTICK_HUART, joystick_uart_buffer, JOYSTICK_UART_BUFFER_SIZE);}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716046.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716046.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716046.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2024年,智慧文旅領航新時代,重塑旅行體驗的未來篇章!

隨著科技的飛速發展,智慧文旅正成為旅游行業的新寵,以其獨特的魅力和無限可能,引領著旅行體驗的全面升級。 2024年,智慧文旅火爆出圈,成為各界關注的焦點,為游客帶來了前所未有的震撼與享受。 智慧文旅&a…

290.【華為OD機試】連續出牌數量(深度優先搜索DFS—JavaPythonC++JS實現)

??點擊這里可直接跳轉到本專欄,可查閱頂置最新的華為OD機試寶典~ 本專欄所有題目均包含優質解題思路,高質量解題代碼(Java&Python&C++&JS分別實現),詳細代碼講解,助你深入學習,深度掌握! 文章目錄 一. 題目二.解題思路三.題解代碼Python題解代碼JAVA題解…

《猛獸派對》好玩嗎值得買嗎?蘋果電腦也能裝《猛獸派對》嗎?猛獸派對好友通行證 動物派對 猛獸對戰游戲

目錄 一、《猛獸派對》好玩嗎? 游戲玩法: 物理引擎: 關卡設計: 游戲特色: 評價: 榮譽: 二、蘋果電腦也能裝《猛獸派對》嗎? 第1步:下載并安裝CrossOver這款軟件…

C語言---文件操作(1)

1.文件的打開和關閉 fopen有2個參數,第一個是文件的名字,第二個是打開的模式(例如是讀文件還是寫文件) (1)該文件夾下面沒有data.txt文件,但是我執行了read操作,所以會顯示這樣的錯誤 (2&#…

『NLP學習筆記』圖解GPT3(How GPT3 Works-Visualizations and Animations)

圖解GPT3(How GPT3 Works-Visualizations and Animations) 文章目錄 一. GPT-1 vs GPT-2 vs GPT-3 vs GPT-3.5 vs GPT-4二. GPT32.1. 訓練動圖2.2. 預測動圖2.3. 代碼生成示例三. 參考文章原作者主頁:Jay Alammar原英文鏈接:How GPT3 Works - Visualizations and Animations …

ApplicationContext容器

ApplicationContext容器 1.概述 ApplicationContext接口代表了一個Spring容器,它主要負責實例化、配置和組裝bean。ApplicationContext接口間接繼承了BeanFactory接口,相較于BeanFactory一些基本的容器功能,ApplicationContext接口是在BeanFactory接口基礎上進行了擴展,增…

SQL 術語:Join 中的 Build 和 Probe 是什么意思?

博主歷時三年精心創作的《大數據平臺架構與原型實現:數據中臺建設實戰》一書現已由知名IT圖書品牌電子工業出版社博文視點出版發行,點擊《重磅推薦:建大數據平臺太難了!給我發個工程原型吧!》了解圖書詳情,…

如何在Vue中實現事件處理?

Vue是一種流行的JavaScript框架,廣泛應用于前端開發。在Vue中,事件處理是一個非常關鍵的概念,可以幫助我們實現用戶與頁面的交互,今天我們就來探討一下如何在Vue中實現事件處理。 首先,讓我們先了解一下在Vue中如何綁…

[pdf]《軟件方法》強化自測題業務建模需求分析共191頁,230題

潘加宇《軟件方法》強化自測題業務建模需求分析共191頁,230題,已上傳CSDN資源。 在完成書中自測題基礎上,進一步強化。 也可到以下地址下載: 資料http://www.umlchina.com/url/quizad.html 如果需要網盤提取碼:uml…

【Python】1. 背景知識

認識 Python 計算機基礎概念 什么是計算機? 很多老一輩的人, 管下面這個叫做計算機. 然鵝, 它只是 “計算器”, 和計算機是有很大區別的. 現在我們所說的計算機, 不光能進行算術運算, 還能進行邏輯判斷, 數據存儲, 網絡通信等等功能,。 以至于可以自動的完成非常復雜的工作…

代碼隨想錄day10(2)字符串:反轉字符串Ⅱ (leetcode541)

題目要求:給定一個字符串 s 和一個整數 k,從字符串開頭算起, 每計數至 2k 個字符,就反轉這 2k 個字符中的前 k 個字符。如果剩余字符少于 k 個,則將剩余字符全部反轉。如果剩余字符小于 2k 但大于或等于 k 個,則反轉前…

Spring與Spring Boot:簡化Java開發的革命性框架

Spring與Spring Boot:簡化Java開發的革命性框架 摘要:本文將深入探討Spring與Spring Boot兩個在Java開發領域具有重要地位的框架。我們將了解它們的核心概念、區別、聯系以及在實際項目中的應用。通過本文,您將更好地理解如何使用這兩個框架…

Zookeeper4:Java客戶端、應用場景以及實現、第三方客戶端curator工具包

文章目錄 Java連接Zookeeper服務端依賴代碼使用 應用場景統一命名服務統一配置管理統一集群管理服務器節點動態上下線理解實現模擬服務提供者【客戶端代碼】-注冊服務模擬服務消費者【客戶端代碼】-獲取服務信息進行請求消費 軟負載均衡分布式鎖理解實現 生產集群安裝N臺機器合…

Java中的Collection

Collection Collection 集合概述和使用 Collection集合概述 是單例集合的頂層接口,它表示一組對象,這些對象也稱為Collection的元素 JDK 不提供此接口的任何直接實現.它提供更具體的子接口(如Set和List)實現 創建Collection集合的對象 多態的方式 具體的實現類ArrayList C…

leetcode - 71. Simplify Path

Description Given a string path, which is an absolute path (starting with a slash ‘/’) to a file or directory in a Unix-style file system, convert it to the simplified canonical path. In a Unix-style file system, a period ‘.’ refers to the current di…

MATLAB環境下基于熵的聲納圖像分割算法

聲納圖像作為準確獲取水下信息的重要途徑之一,在國防、軍事、工程等方面發揮著巨大作用。然而,由于水聲信道的復雜多變和聲波本身的傳播損失,聲納圖像往往呈現出分辨率和對比度不高、噪聲干擾嚴重、目標輪廓模糊等特點。 聲納圖像的分割指的…

FCIS 2023網絡安全創新大會:洞察前沿技術,探索安全新境界(附大會核心PPT下載)

隨著信息技術的飛速發展,網絡安全問題日益凸顯,成為全球關注的焦點。作為網絡安全領域的重要盛會,FCIS 2023網絡安全創新大會如期而至,匯聚了全球網絡安全領域的頂尖專家、學者、企業家和政策制定者,共同探討網絡安全的…

備戰藍橋杯————差分數組1

引言 一、差分數組 什么是差分數組 差分數組的作用 Java代碼實現差分數組 二、 區間加法 題目描述 代碼與解題思路 總結 引言 在數字世界的海洋中,數據是構建和優化算法的基石。然而,當我們面對需要頻繁進行區間操作的數組時,傳統的逐元素…

ABAP - SALV教程10 添加可編輯checkbox列

幾乎所有的功能報表都會有那么一個選擇列,問了業務顧問,業務顧問說是用戶不習慣使用報表原生的選擇模式。效果圖SALV的選擇列是通過將列設置成checkbox_hotspot樣式,注冊單擊事件完成勾選功能的。完成步驟 將SEL列設置成checkbox_hotspot樣式…

【筆記】OpenHarmony和HarmonyOS區別及應用開發簡介

一、概念 OpenHarmony(OH) : OpenAtom OpenHarmonyHarmonyOS(HO):開發 | 華為開發者聯盟 (huawei.com) HO當前最高是3.1,在華為mate 60上面也是。關于4.0、5.0和next這類版本說法都是面向用戶的,不是開發人員。對于程序員&#…