請問小哥,飛控如果需要通過三四個串口同時採集多個傳感器數據,應該如何設計中斷優先級,會不會出現當某一傳感器發送頻率過快時,一直佔用改串口中斷函數而進不了其他串口中斷呢?這種該如何解決?謝謝小哥

首先這裏需要明白一點,串口通訊波特率與數據傳輸時間的關係,以無名飛控GPS解析為例,正常工作時,GPS工作以波特率921600,8個數據位,一個起始位,一個停止位。921600bps/(8+1+1)bit=傳輸92160字節/s,故串口傳輸一個字節用時1000000us/92160≈10.85us,這裏可以簡單計算一下,飛控接受pvt語句開銷92數據位+2檢驗位=94,94*10.85約等於1.02ms,與飛控實際測試時間基本一致,實際也可以測試115200、38400通訊時開銷分別為8.53ms、25.6ms,接受單個字節耗時分別為86.8us、264.4us。 以GPS解析為説明串口傳輸時間後,再來考慮中斷問題,首先為保障數據不丟幀,當只存在一個串口中斷時,該串口中斷內部函數執行時間,務必要小於該串口的傳輸一個直接所需的時間,以波特率115200的串口1為例,串口1的中斷函數執行時間務必小於86.8us,即串口1的下一個字節傳輸來之前,上一個字節的串口中斷處理函數務必運行完成,否則數據就會丟幀。 所以一般來講,串口中斷函數裏面都不會去執行大段時間開銷的任務,目的就是確保不丟幀,常用的辦法是在串口中斷裏面採用環形隊列緩衝區存儲數據,數據解析用低優先級的任務去處理。 環形隊列緩衝區存儲函數的執行時間在STM32F1裏面大概2us不到,在STM32F4裏面不足1us,所以當串口中斷函數裏面只運行環形對接緩衝區存儲函數時,即使以波特圖921600(傳輸一個字節10.85us)通訊,數據也不會丟幀。 當存在多個串口接受函數時,此時以STM32F1為例,假設環形隊列緩衝區存儲函數的執行時間在STM32F1裏面為2us,此時存在6個串口中斷以波特率921600同時運行,各中斷彼此之間不能打斷,但是存在子優先順序,同一時刻6箇中斷全部掛起,這個時候系統首先響應子優先級第一的串口中斷接受函數耗時2us,接着依次響應子優先級23456,當第6個串口中斷函數剛開始執行時是第10us,在10—12us時系統正在執行第6個串口中斷函數,在10.85us時刻,下一次串口中斷又來了,此時便發生了數據丟幀。可以可以想一下,此時在不丟幀情況下,系統能設計的最大串口中斷數為5個。 上面是以很極端的例子説明了丟幀在實際系統中是怎麼發生的,一般串口通訊波特率不會到921600這麼大,並且不是每個串口都必須工作在同一波特率,當工作波特率為115200時,串口接收單個字節為86.8us,此情況下系統能夠執行足夠多的串口中斷函數,仍然能確保不丟幀。所以當系統所需串口中斷很多時,可以通訊把波特率降下來,來確保不數據丟幀。 以上只考慮了串口中斷彼此之間開銷,當系統存在比串口中斷接收優先級更好的中斷任務時,比如利用外部中斷的ppm接收、超聲波測距等,為了確保串口不丟幀,需要優先級高於串口中斷的任務最大執行時間+串口中斷函數執行時間,務必小於串口接收單個字節所需的時間,才能確保不丟幀。 

總結: 

1、多個串口通訊時,串口通訊波特率可以降低一點。 

2、合計設計優先級,當存在不同波特率通訊時,通訊波特率高的串口中斷優先級要高於波特率低的。 

3、存在優先級高於串口中斷的其它中斷任務時,其它中斷任務的總的最大時間開銷也要考慮。

祝好 

無名小哥:餘義

作者:無名創新

飛牛系統裏的docker鏡像zabbix怎麼使用_優先級