1. gzyueqian
      13352868059

      嵌入式開發(fā):編寫中斷服務(wù)例程的5個最佳實踐

      更新時間: 2024-06-08 09:18:58來源: 粵嵌教育瀏覽量:1036


      幾乎每個嵌入式系統(tǒng)都使用中斷服務(wù)程序。如果需要跟蹤時間,可能會有一個產(chǎn)生系統(tǒng)滴答的定時器中斷。如果你有一個USART,你可能正在使用中斷。使用DMA進行更高效的數(shù)據(jù)傳輸?你可能正在使用中斷。

      中斷是嵌入式系統(tǒng)不可或缺的一部分。不幸的是,寫得不好的ISR會導(dǎo)致系統(tǒng)出現(xiàn)爭用情況、響應(yīng)能力差,甚至CPU使用過度。

      在本帖中,我們將探討撰寫高效ISR的幾種最佳實踐。

       

      1.保持簡短快速

      中斷超級酷!當(dāng)的代碼正在執(zhí)行并且發(fā)生重要事件時,程序會被中斷以跳轉(zhuǎn)到中斷服務(wù)例程。發(fā)生跳轉(zhuǎn)時,寄存器的當(dāng)前狀態(tài)需要存儲在中斷幀中。

      中斷幀被推送到堆棧上,并進入ISR。中斷運行,然后中斷幀恢復(fù),應(yīng)用程序恢復(fù)。可以想象,每次運行中斷服務(wù)程序時,這個過程都會消耗CPU周期并產(chǎn)生開銷。周期數(shù)因處理器和架構(gòu)而異,但中斷兩端的周期數(shù)可能在12到數(shù)百個之間。

       

      雖然我們對中斷開銷無能為力,但我們可以控制中斷中使用的周期數(shù)。可以想象,ISR執(zhí)行所花費的CPU周期越多,對我們的應(yīng)用程序代碼的影響就越大。長而慢的中斷會導(dǎo)致程序不同部分的抖動和其他時序問題。它們甚至?xí)?dǎo)致其他中斷丟失或延遲!

      經(jīng)驗法則是讓你的中斷短而快!

       

      2.不要調(diào)用函數(shù)

      如果你希望你的ISR短而快,你應(yīng)該避免在ISR內(nèi)部進行函數(shù)調(diào)用。函數(shù)(尤其是那些開銷巨大或執(zhí)行復(fù)雜任務(wù)的函數(shù))會大大增加ISR的執(zhí)行時間。增加的執(zhí)行時間會導(dǎo)致中斷丟失或其他關(guān)鍵任務(wù)的延遲處理,從而可能導(dǎo)致系統(tǒng)不穩(wěn)定。

      當(dāng)在ISR中調(diào)用一個函數(shù)時,它涉及到額外的步驟,如將當(dāng)前上下文推送到堆棧上、跳轉(zhuǎn)到函數(shù)代碼并返回到ISR。這些額外的步驟消耗了寶貴的CPU周期。如果函數(shù)包含阻塞調(diào)用、等待I/O操作或依賴中斷期間可能處于不一致狀態(tài)的資源,則可能會嚴重影響系統(tǒng)的響應(yīng)能力和可預(yù)測性。

      現(xiàn)在,可能認為編寫ISR會違反軟件開發(fā)最佳實踐。畢竟,我們不應(yīng)該模塊化我們的代碼嗎?沒有職能,我們的ISR不會變得混亂嗎?

      使用一些技巧來規(guī)避不調(diào)用函數(shù)的最佳實踐

      1)使用靜態(tài)編譯或預(yù)處理程序。

      根據(jù)的語言,復(fù)雜的計算或至少部分計算可能會在編譯時執(zhí)行。通過在編譯時執(zhí)行這些計算,ISR在運行時需要執(zhí)行的工作將會減少。

      2)內(nèi)嵌函數(shù)

      仍然可以將ISR代碼放入函數(shù)中,但是不要將它們作為常規(guī)函數(shù),而是使用inline關(guān)鍵字。inline關(guān)鍵字會建議編譯器不要調(diào)用該函數(shù),而是應(yīng)該將該函數(shù)的內(nèi)容復(fù)制并粘貼到調(diào)用者中。

      內(nèi)聯(lián)函數(shù)將消除與函數(shù)調(diào)用相關(guān)的開銷。被警告!只是給編譯器的一個建議!必須在程序集中驗證該函數(shù)實際上是內(nèi)聯(lián)的。

      注意今天大多數(shù)編譯器會采納我們的建議,但你不能毫無疑問地相信它!

      通過避免ISR中的函數(shù)調(diào)用,可以保持中斷處理的效率和可靠性,確保的系統(tǒng)在各種條件下保持響應(yīng)和穩(wěn)定。

       

      3.將進程卸載到其他線程

      中斷并不是用來做很多繁重的工作的。我們希望中斷短而快,這意味著它應(yīng)該做最少需要做的事情。例如,如果正在通過USART接收作為數(shù)據(jù)包一部分的字節(jié),則不會在中斷中處理該數(shù)據(jù)包。處理該字節(jié),然后設(shè)置一個標志來指示程序的另一部分應(yīng)該處理該數(shù)據(jù)。

      通過將密集的進程卸載到其他線程,可以確保ISR保持高效和快速響應(yīng)。這種方法可以在裸機或多線程環(huán)境中使用。以下是如何有效地將處理任務(wù)轉(zhuǎn)移到ISR之外的方法

      1)設(shè)置標志

      使用簡單的標志來指示事件已經(jīng)發(fā)生。主程序或另一個線程可以監(jiān)視這些標志,并在安全的情況下進行必要的處理。

      使用隊列

      實現(xiàn)隊列將數(shù)據(jù)從ISR傳遞到其他線程。這樣,ISR可以快速將數(shù)據(jù)排隊并返回處理中斷,同時主程序或?qū)S霉ぷ骶€程可以處理排隊的數(shù)據(jù)。

      3)線程同步

      確保ISR和其他線程之間的正確同步,以避免競爭情況和數(shù)據(jù)損壞。根據(jù)需要使用互斥、信號量或其他同步機制。

       

      通過遵循這些實踐,可以在嵌入式系統(tǒng)中保持高水平的性能和可靠性。這將確保ISR保持快速和高效,同時安全地處理和控制更復(fù)雜的處理。

       

      4.對共享變量使用volatile

      當(dāng)ISR和主程序共享變量時,將它們聲明為volatile是至關(guān)重要的。volatile關(guān)鍵字告訴編譯器,變量值可能會在程序流的控制之外隨時更改,從而防止編譯器應(yīng)用假定值不會意外更改的特定優(yōu)化。

      如果沒有volatile關(guān)鍵字,編譯器可能會優(yōu)化掉必要的讀取或?qū)懭耄瑥亩鴮?dǎo)致不可預(yù)測的行為和難以診斷的錯誤。Volatile將為做三件事

      1)阻止優(yōu)化

      編譯器假定非易失性變量不會改變,除非程序顯式修改它。對于共享變量,這種假設(shè)是錯誤的,因為ISR可以隨時更改變量。將變量聲明為volatile會阻止編譯器優(yōu)化必要的讀取或?qū)懭搿?/span>

      2)確保數(shù)據(jù)是新鮮的

      使用volatile時,編譯器總是從內(nèi)存中讀取值,而不是使用寄存器中的緩存值。這確保了主程序看到ISR寫入的最新值,反之亦然。

       

      結(jié)論

      中斷服務(wù)例程對于每個嵌入式系統(tǒng)都至關(guān)重要。如果你想讓你的系統(tǒng)反應(yīng)靈敏和高效,你必須正確地實現(xiàn)你的中斷。我無法告訴你我遇到性能差的系統(tǒng)的頻率,根本原因是ISR寫得不好。

      如果你遵循本文中的最佳實踐,你的中斷會表現(xiàn)得更好,引起的問題也會更少。


      免費預(yù)約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 五月天亚洲视频福利 | 在线观看免费午夜A级毛∧ 日韩欧美亚洲国产精品影视在线 | 亚洲无线国产观看 | 中文字幕免费伦费影视在线观看 | 午夜性爱视频久久 | 亚洲欧洲中文日韩A乱码 |