主頁 > 作業系統 > 微控制器實時作業系統實踐2了解RTOS任務

微控制器實時作業系統實踐2了解RTOS任務

2023-06-07 08:22:25 作業系統

2了解RTOS任務

超級回圈編程范式通常是嵌入式系統工程師最先接觸到的編程方法之一,用超級回圈實作的程式有一個單一的頂層回圈,在系統需要執行的各種功能之間回圈,這些簡單的while回圈很容易創建和理解(當它們很小的時候),在FreeRTOS中,任務與超級回圈非常相似--主要區別在于,系統可以有一個以上的任務,但只有一個超級回圈,

在本章中,我們將仔細研究超級回圈和用它們實作一定程度的并行性的不同方法,之后,將對超級回圈和任務進行比較,并從理論上介紹任務執行的思維方式,最后,我們將看看任務是如何通過RTOS內核實際執行的,并比較兩種基本的調度演算法,

超級回圈編程介紹

所有的嵌入式系統都有一個共同的特性--它們沒有退出點,由于其性質,嵌入式代碼通常被期望總是可用的--靜靜地在后臺運行,處理內務作業,并隨時準備接受用戶的輸入,與旨在啟動和停止程式的桌面環境不同,如果微控制器退出main()函式,它就沒有任何事情可做,如果發生這種情況,很可能是整個設備已經停止運作,由于這個原因,嵌入式系統中的main()函式從不回傳,與應用程式不同的是,應用程式是由其主機作業系統啟動和停止的,大多數基于嵌入式MCU的應用程式在上電時開始,在系統斷電時突然結束,由于這種突然的關閉,嵌入式應用程式通常沒有任何通常與應用程式相關的關閉任務,如釋放記憶體和資源,

下面的代碼代表了超級回圈的基本思想:

void main ( void )
{
    while(1)
    {
        func1();
        func2();
        func3();
        //do useful stuff, but don't return
        //(otherwise, where would we go. . what would we do. . .?!)
    }
}

雖然非常簡單,但前面的代碼有許多值得指出的特點,while回圈從不回傳--它一直在執行同樣的三個函式(這是故意的),這三個看似無害的函式呼叫可以在實時系統中隱藏一些令人討厭的驚喜,

基本的超級回圈

這個從不回傳的主回圈一般被稱為超級回圈,超級回圈總是很有趣,因為它可以控制系統中的大多數事情--除非超級回圈使之發生,否則下圖中的任何事情都無法完成,這種型別的設定非常適合于非常簡單的系統,只需要執行一些不需要花費大量時間的任務,基本的超級回圈結構非常容易撰寫和理解;如果你想解決的問題可以用一個簡單的超級回圈來完成,那么就使用一個簡單的超級回圈,下面是前面介紹的代碼的執行流程--每個函式都是按順序呼叫的,而且回圈永不退出:

實時系統中的超級環路

當簡單的超級回圈快速運行時(通常是因為它們的功能/責任有限),它們的回應速度相當快,然而,超級回圈的簡單性可能是一種祝福,也是一種詛咒,由于每個函式總是跟在前面的函式后面,它們總是以相同的順序被呼叫,并且完全相互依賴,一個函式引入的任何延遲都會傳播到下一個函式,從而導致執行該回圈迭代的總時間增加(如下圖所示),如果func1在回圈中執行一次需要10毫秒,而下一次需要100毫秒,那么func2在回圈中第二次被呼叫的時間就不會像第一次那樣快:

讓我們更深入地看一下這個問題,在上圖中,func3負責檢查一個代表外部事件的標志的狀態(這個事件是一個信號的上升沿),func3檢查標志的頻率取決于func1和func2執行的時間,一個設計良好、反應靈敏的超級回圈通常會執行得非常快,檢查事件的頻率要比事件發生的頻率高(呼出B),當外部事件確實發生時,該回圈直到func3的下一次執行才檢測到該事件(呼出A、C和D),注意,在事件產生和func3檢測到它之間有一個延遲,還要注意的是,這個延遲并不總是一致的:這種時間上的差異被稱為抖動,

在許多基于超級回圈的系統中,與被輪詢的緩慢發生的事件相比,超級回圈的執行速度非常高,我們在頁面上沒有足夠的空間來顯示回圈在檢測到事件之間執行數百次(或數千次)的迭代!這就是所謂的抖動!

如果系統在回應事件時有一個已知的最大抖動量,它被認為是確定性的,也就是說,它將在事件發生后的指定時間內對事件作出可靠的反應,高水平的確定性對于實時系統中的時間關鍵型組件是至關重要的,因為如果沒有它,系統可能無法及時回應重要的事件,

考慮到回圈反復檢查硬體標志的事件(這被稱為輪詢),回圈越緊密,標志被檢查的速度就越快--當標志經常被檢查時,代碼將對感興趣的事件做出更多的反應,如果我們有需要及時采取行動的事件,我們可以只寫非常緊密的回圈,等待重要事件的發生,這種方法是有效的--但前提是該事件是系統唯一感興趣的事情,如果整個系統唯一的責任就是觀察該事件(沒有后臺I/O、通信等),那么這是一個有效的方法,這種型別的情況在今天復雜的現實世界的系統中很少發生,回應性差是單純基于輪詢的系統的局限性,接下來,我們將看看如何在我們的超級回圈中獲得更多的并行性,

用超級回圈實作并行操作

盡管基本的超級回圈只能按順序通過函式,但仍有辦法實作并行化,單片機有一些不同型別的專用硬體,它們被設計用來減輕CPU的一些負擔,同時還能實作高度回應的系統,本節將介紹這些系統以及如何在超級回圈風格的程式中使用它們,

中斷

對單一事件進行輪詢不僅在CPU周期和功率方面是浪費的--它還會導致系統對其他事物沒有反應,這通常是應該避免的,那么,我們怎樣才能讓單核處理器并行地做事情呢?嗯,我們不能--畢竟只有一個處理器,...但由于我們的處理器很可能每秒運行數百萬條指令,所以有可能讓它執行足夠接近于并行的事情,MCU還包括用于生成中斷的專用硬體,中斷向MCU提供信號,使其在事件發生時直接跳到中斷服務程式(ISR interrupt service routine ),這是一個非常關鍵的功能,ARM Cortex-M內核為其提供了一個標準化的外設,稱為嵌套向量中斷控制器(NVIC nested vector interrupt controller,NVIC提供了一種處理中斷的通用方法,這個術語的嵌套部分標志著即使是中斷也可以被其他具有更高優先級的中斷打斷,這相當方便,因為它允許我們將系統中時間最關鍵的部分的延遲和抖動量降到最低,

那么,中斷如何融入超級回圈,以更好地實作并行活動的假象?ISR內部的代碼通常被保持得盡可能短,以盡量減少在中斷中花費的時間,這一點很重要,有幾個原因,如果中斷發生得很頻繁,而且ISR包含很多指令,那么ISR就有可能在被再次呼叫之前不回傳,對于UART(universal asynchronous receiver / transmitter)或SPI(serial peripheral interface)等通信外設來說,這將意味著資料丟失(這顯然是不可取的),保持代碼簡短的另一原因是其他中斷也需要得到服務,這就是為什么把任何責任推給不在ISR背景關系中運行的代碼是個好主意,

為了快速了解ISR是如何導致抖動的,讓我們看看簡單的例子:外部模數轉換器(ADC analog to digital converter )向MCU發出信號,表示已經采集了讀數,轉換結果準備傳送給MCU(參考這里的硬體圖):

在ADC硬體中,有一個引腳專門用來指示模擬值的讀數已被轉換為數字表示,并準備傳輸給MCU,然后,MCU將通過通信介質(圖中的COM)啟動傳輸,

接下來,讓我們看看相對于轉換準備線的上升沿,ISR呼叫如何隨著時間的推移而相互疊加,下圖顯示了六個不同的ISR被呼叫以回應信號的上升沿的情況,硬體中的上升沿與韌體中的ISR被呼叫之間的少量時間是最小延遲,ISR回應中的抖動是許多不同周期中延遲的差異:

有不同的方法來最小化關鍵ISR的延時和抖動,在基于ARM Cortex-M的MCU中,中斷優先級是靈活的--在運行時可以為單個中斷源分配不同的優先級,重新確定中斷優先級的能力是確保系統中最重要的部分在需要時獲得CPU的一種方式,
如前所述,保持在中斷中執行的代碼量盡可能短是很重要的,因為在ISR中的代碼將優先于任何不在ISR中的代碼(例如main()),此外,較低優先級的ISR不會被執行,直到較高優先級的ISR中的所有代碼都被執行,并且ISR退出--這就是為什么保持ISR的簡短是重要的,嘗試限制ISR的責任(以及因此而產生的代碼)總是好主意,
當多個中斷被嵌套時,它們不會完全回傳--實際上ARM Cortex M處理器有非常有用的功能,叫做中斷-尾部鏈,如果處理器檢測到一個中斷即將退出,但另一個中斷正在等待,那么下一個ISR將被執行,而處理器不會完全恢復中斷前的狀態,這進一步減少了延遲,

中斷和超級回圈

在ISR中實作最小指令和責任的一種方法是在ISR中做盡可能少的作業,然后設定標志,由超級回圈中運行的代碼來檢查,這樣一來,中斷就可以盡快得到服務,而不需要整個系統都致力于等待該事件,在下圖中,注意到在最后由func3處理之前,中斷是如何被多次產生的,

根據該中斷試圖實作的具體目標,它通常會從相關的外設中獲取一個值并將其推入陣列(或從陣列中獲取值并將其送入外設暫存器),在我們的外部ADC的情況下,ISR(每次ADC執行轉換時觸發)將出去到ADC,傳輸數字化的讀數,并將其存盤在RAM中,設定標志,表明一個或多個值已經準備好進行處理,這使得中斷可以被多次服務,而不涉及高層代碼:

在通信外設傳輸大塊資料的情況下,可以用陣列作為佇列來存盤要傳輸的專案,在整個傳輸結束時,可以設定標志來通知主回圈的完成,有很多例子可以說明佇列值是合適的情況,例如,如果需要對資料塊進行一些處理,首先收集資料,然后在中斷之外一起處理整個資料塊,這往往是有利的,中斷驅動的方法并不是實作這種阻斷資料的唯一方法,

DMA

還記得處理器不可能真正做到并行的說法嗎?這仍然是事實,然而......現代的MCU不僅僅包含一個處理核心,當我們的處理核心在處理指令時,還有許多其他硬體子系統在MCU內努力作業,這些努力作業的子系統之一被稱為直接記憶體訪問控制器(DMA Direct Memory Access Controller):

前面的圖是非常簡化的硬體框圖,顯示了從RAM到UART外設的兩個不同的資料路徑的視圖,
在沒有DMA的情況下,從UART接收位元組流,來自UART的資訊將進入UART暫存器,被CPU讀取,然后推送到RAM進行存盤:

  • CPU必須檢測到何時收到單獨的位元組(或字),要么通過輪詢UART暫存器標志,要么通過設定中斷服務例程,當一個位元組準備好時就啟動,
  • 位元組從UART傳輸后,CPU可以將其放入RAM進行進一步處理,
  • 步驟1和2重復進行,直到收到整個資訊,

當DMA被用在同樣的場景中時,會發生以下情況:

  • CPU為傳輸配置DMA控制器和外圍設備,
  • DMA控制器負責UART外設和RAM之間的所有傳輸,這不需要CPU的干預,
  • 當整個傳輸完成時,CPU會得到通知,它可以直接處理整個位元組流,

大多數程式員發現DMA幾乎是神奇的,如果他們習慣于處理超級回圈和ISR,控制器被配置為在外設需要時向外設傳輸記憶體塊,然后在傳輸完成時提供通知(通常是通過一個中斷)--就是這樣!這就是DMA!

當然,這種便利也是有代價的,最初設定DMA傳輸確實需要一些時間,所以對于小的傳輸,實際上可能比使用中斷或輪詢的方法要花費更多的CPU時間來設定傳輸,
還有一些需要注意的地方:每個MCU都有特定的限制,所以在指望DMA對系統的關鍵設計組件的可用性之前,一定要閱讀資料手冊、參考手冊和勘誤表的細節:
MCU內部總線的帶寬限制了可以可靠地放在單一總線上的對帶寬要求高的外設的數量,
偶爾,映射到外設的DMA通道的有限可用性也使設計程序復雜化,
這些型別的原因就是為什么要讓所有的團隊成員參與到嵌入式系統的早期設計中來,而不是直接把它扔到墻上,
DMA對于有效地訪問大量的外設是很好的,使我們有能力為系統添加越來越多的功能,然而,當我們開始向超級回圈添加越來越多的代碼模塊時,子系統之間的相互依賴關系也變得更加復雜,在下一節中,我們將討論為復雜系統擴展超級回圈的挑戰,

擴展超級回圈

現在已經有了能夠可靠地處理中斷的回應系統,也許我們已經配置了DMA控制器來處理通信外圍設備的繁重作業,為什么我們需要實時作業系統?嗯,你完全有可能不需要! 如果系統只處理有限的任務,而且沒有特別復雜或耗時的,那么可能就不需要比超級回圈更復雜的東西,

但是,如果系統還要負責生成用戶界面(UI),運行復雜的耗時的演算法,或者處理復雜的通信堆疊,那么這些任務很可能要花費非同小可的時間,如果帶有大量影片的華麗奪目的用戶界面因為MCU正在處理從關鍵的傳感器收集資料而開始有點結巴,那也沒什么大不了的,要么影片可以回呼,要么取消,而實時系統的重要部分則保持原樣,但是,如果那個影片看起來仍然非常好,即使有一些來自傳感器的資料被遺漏,又會發生什么呢?

在我們的行業中,這個問題每天都有各種不同的方式,有時,如果系統設計得足夠好,丟失的資料會被檢測到并被標記出來(但它不能被恢復:它永遠消失了),如果設計團隊真的很幸運,它甚至可能在內部測驗中以這種方式失敗,然而,在許多情況下,遺漏的傳感器資料將完全沒有被注意到,直到有人注意到其中一個讀數似乎有點偏離......有時,如果每個人都很幸運,關于粗略讀數的錯誤報告可能包括一個提示,即它似乎只在有人在前面板上(玩那些花哨的影片)時發生,這至少會給被指派去除錯這個問題的可憐的韌體工程師一個提示--但我們往往甚至沒有那么幸運,
這些是需要實時作業系統的系統型別,保證時間最緊迫的任務在必要時總是在運行,并在有空閑時間時將低優先級的任務調度到運行,這是搶占式調度器的一個強項,在這種型別的設定中,關鍵的傳感器讀數可以被推到他們自己的任務中,并分配一個高優先級--當需要處理傳感器的時候,有效地中斷了系統中的任何其他任務(除了ISR),那個復雜的通信堆疊可以被分配一個比關鍵傳感器更低的優先級,最后,具有花哨影片的華麗用戶界面得到了剩余的處理器周期,它可以自由地執行任意多的滑動阿爾法混合影片,但只有在處理器沒有其他更好的事情可做的時候,

RTOS任務與超級回圈相比較

到目前為止,我們只是非常隨意地提到了任務,但任務到底是什么?思考任務的簡單方法是,它只是另一個主回圈,在一搶占式RTOS中,任務和超級回圈之間有兩個主要區別:

  • 每個任務都收到它自己的私有堆疊,與共享系統堆疊的main中的超級回圈不同,任務收到自己的堆疊,系統中的其他任務不會使用,這允許每個任務擁有自己的呼叫堆疊,而不干擾其他任務,
  • 每個任務都有分配給它的優先級,這個優先級允許調度員決定哪個任務應該運行(目標是確保系統中最高優先級的任務總是在做有用的作業),
    考慮到這兩個特點,每個任務都可以被編程,好像它是處理器唯一要做的事情,你有一個你想看的單一標志和一些計算的華美的影片要攪和嗎?沒問題:只需對任務進行編程,并給它分配合理的優先級,相對于系統的其他功能而言,搶占式調度器將始終確保最重要的任務在有作業要做時被執行,當一個較高優先級的任務不再有有用的作業要做,并且它正在等待系統中的其他東西時,較低優先級的任務將被切換到背景關系并允許運行,

用RTOS任務實作并行操作

早些時候,我們看了在三個函式中回圈的超級回圈,現在讓我們把這三個函式中的每一個移到自己的任務中,我們將用這三個簡單的任務來研究以下內容:

  • 理論上的任務編程模型: 如何在理論上描述這三個任務
  • 實際的輪流調度: 任務在使用輪回呼度演算法執行時是什么樣子的
  • 實際的搶占式調度: 使用搶占式調度執行的任務是什么樣子的?
    在現實世界的程式中,每個任務幾乎都沒有單一的函式;我們只是把它作為類似于前面的過于簡單的超級回圈的例子,

理論上的任務編程模型

下面是使用超級回圈來執行三個函式的偽代碼,同樣的三個函式也包含在基于任務的系統中--每個RTOS任務(在右邊)包含與左邊的超級回圈的函式相同的功能,當我們討論使用超級回圈與使用調度器的任務驅動方法時,代碼執行方式的差異時,這點將被繼續使用:

你可能會注意到超級回圈實作和RTOS實作之間的直接區別是無限的while回圈的數量,在超級回圈的實作中,只有一個無限的while回圈(在main()中),但是每個任務都有自己的無限的while回圈,
在超級回圈中,在呼叫下一個函式之前,被超級回圈執行的三個函式分別運行到完成,然后回圈繼續到下一個迭代(如下圖所示):

在RTOS的實作中,每個任務本質上是它自己的小的無限的while回圈,超級回圈中的函式總是一個接一個地被呼叫(由超級回圈中的邏輯協調),而任務可以簡單地被認為是在調度器啟動后的所有并行執行,下面是一個執行三個任務的實時作業系統的圖示:

在圖中,你會注意到每個while回圈的大小是不一樣的,這是使用并行執行任務的調度器相對于超級回圈的許多好處之一--程式員不需要立即關注最長的執行回圈的長度會拖累其他更緊密的回圈,圖中描述了任務2的回圈比任務1長很多,在超級回圈系統中,這將導致func1的功能執行頻率降低(因為超級回圈需要先執行func1,然后是func2,最后是func3),在基于任務的編程模型中,情況并非如此--每個任務的回圈可以被認為是與系統中的其他任務隔離的--而且它們都是并行運行的,

這種隔離和感知的并行執行是使用實時作業系統的一些好處;它為程式員減輕了一些復雜性,所以,這是概念化任務的最簡單的方法--它們只是獨立的無限的while回圈,都是平行執行的......在理論上,在現實中,事情并沒有這么簡單,在接下來的兩節中,我們將瞥見幕后發生的事情,使其看起來像是任務在并行執行,

回圈排程

概念化實際任務執行的最簡單方法之一是輪流調度,在輪流調度中,每個任務得到一小塊時間來使用處理器,這是由調度器控制的,只要任務有作業要執行,它就會執行,就該任務而言,它完全擁有自己的處理器,調度器負責處理為下一個任務切換適當背景關系的所有復雜問題:

這和之前展示的三個任務是一樣的,只不過不是理論上的概念化,而是通過任務的回圈的每一次迭代都是隨著時間的推移而列舉的,因為回圈調度器給每個任務分配了相等的時間片,最短的任務(任務1)已經執行了將近六次回圈,而最慢的回圈任務(任務2)只完成了第一次回圈,任務3已經執行了三次回圈,
執行相同函式的超級回圈與執行這些函式的輪回呼度例程之間的一個極其重要的區別是這樣的: 任務3在任務2之前完成了其適度緊密的回圈,當超級回圈以串行方式運行函式時,函式3甚至不會開始,直到函式2運行完成,所以,雖然調度器沒有為我們提供真正的并行性,但每個任務都得到了它公平的CPU周期份額,所以,在這種調度方案下,如果任務有較短的回圈,它將比有較長回圈的任務執行得更頻繁,

所有這些切換都有一個(輕微的)代價--調度器需要在任何有背景關系切換的時候被呼叫,在這個例子中,任務沒有明確地呼叫調度器來運行,在FreeRTOS運行在ARM Cortex-M上的情況下,調度器將被從SysTick中斷中呼叫(更多細節可在第7章FreeRTOS調度器中找到),為了確保調度器內核非常有效,并盡可能地減少運行時間,我們付出了相當多的努力,然而,事實是,它將在某些時候運行并消耗CPU周期,在大多數系統中,少量的開銷通常不會被注意到(或顯著),但在某些系統中,它可能成為問題,例如,如果一個設計處于可行性的極端邊緣,因為它有非常嚴格的時間要求和非常少的空閑CPU周期,如果超級回圈/中斷方法已經被仔細地描述和優化,那么增加的開銷可能是不可取的(或者完全有必要),然而,最好是盡可能地避免這種型別的情況,因為即使是在中等復雜的系統中,忽視中斷堆積(或嵌套條件陳述句偶爾需要更長的時間)并導致系統錯過最后期限的可能性也是非常大的,

基于搶占式的調度

搶占式調度提供了一種機制,以確保系統總是在執行其最重要的任務,搶占式調度演算法將優先考慮最重要的任務,不管系統中還有什么事情發生--除了中斷,因為它們發生在調度器下面,總是有更高的優先級,這聽起來非常直接--而且確實如此--只是有一些細節需要考慮到,
讓我們看一下同樣的三個任務,這三個任務都有相同的功能:簡單的while回圈,無休止地增加不穩定的變數,
現在,考慮以下三種情況,看看這三個任務中哪個會得到背景關系,下圖中的任務與之前介紹的輪流調度的任務相同,三個任務中都有足夠多的作業要做,這將防止任務脫離背景關系:

那么,當三個不同的任務被設定為三組不同的優先級(A、B、C)時會發生什么?

A(左上角): 任務1在系統中擁有最高的優先級--它獲得了所有的處理器時間 不管任務1執行了多少次迭代,如果它是系統中優先級最高的任務,并且它有作業要做(不需要等待系統中的其他東西),它將被賦予背景關系并運行,
B(右上方): 任務2是系統中優先級最高的任務,由于它有足夠多的作業要做,不需要等待系統中的其他東西,任務2將被賦予背景關系,由于任務2被配置為系統中的最高優先級,它將執行,直到它需要在系統中等待其他東西,
C(左下角): 任務3被配置為系統中的最高優先級任務,沒有其他任務運行,因為它們的優先級較低,
現在,很明顯,如果你真的在設計一個需要多個任務并行運行的系統,如果系統中所有的任務都需要100%的CPU時間,并且不需要等待任何東西,那么搶占式調度器就沒有什么用了,這種設定對于實時系統來說也不是很好的設計,因為它完全超載了(而且忽略了系統所要執行的三個主要功能中的兩個)!這種情況被稱為 "任務"!所呈現的情況被稱為任務饑餓,因為只有系統中優先級最高的任務獲得了CPU時間,而其他任務則被剝奪了處理器時間,

另一個值得指出的細節是,調度器仍然以預定的時間間隔運行,無論系統中發生了什么,調度器都會勤奮地按照預定的時間間隔運行,
這有一個例外,FreeRTOS有無滴答的調度器模式,旨在用于極低功率的設備,它可以防止調度器在相同的預定間隔內運行,

這里顯示了一個使用搶占式調度器的更現實的用例:

在這種情況下,任務1是系統中優先級最高的任務(它也恰好很快完成執行)--任務1只有在調度器需要運行的時候才會被剝奪背景關系;否則,它將保持背景關系直到沒有任何額外的作業要執行,

任務2是下一個最高優先級的任務--你也會注意到,這個任務被設定為在每個RTOS調度器的勾選中執行一次(由向下的箭頭表示),任務3是系統中優先級最低的任務:只有當系統中沒有其他值得做的事情時,它才會得到背景關系,在這張圖中,有三個要點值得關注:
A:任務2有背景關系,即使它被調度器打斷了,但在調度器運行后,它又立即得到了背景關系(因為它還有作業要做),
B: 任務2已經完成了迭代0的作業,調度器已經運行并確定(因為系統中沒有其他任務需要運行)任務3可以擁有處理器時間,
C:任務2已經開始運行迭代4,但是任務1現在有一些作業要做--盡管任務2還沒有完成該迭代的作業,任務1立即被調度器切換到執行其更高優先級的作業,在任務1完成了它需要做的事情后,任務2被切換回來完成迭代4,這一次,迭代運行到下一個tick,任務2再次運行(迭代5),在任務2迭代5完成后,沒有更高優先級的作業要執行,所以系統中最低優先級的任務(任務3)再次運行,看起來任務3終于完成了迭代0,所以它進入了迭代1并繼續運行......,
希望你還在聽我說! 如果沒有,那也沒關系,因為這只是一個非常抽象的例子,關鍵的啟示是,系統中優先級最高的任務是優先的,

RTOS任務與超級回圈的對比--利與弊

超級回圈對于責任有限的簡單系統是非常好的,如果系統足夠簡單,它們可以在回應事件時提供非常低的抖動,但前提是回圈足夠緊密,隨著系統越來越復雜,獲得更多的責任,輪詢率會下降,這種輪詢率的降低導致對事件的回應抖動大得多,中斷可以被引入到系統中,以應對抖動的增加,隨著基于超級回圈的系統變得越來越復雜,跟蹤和保證對事件的反應能力變得越來越難,
對于那些不僅有耗時的任務,而且還需要對外部事件有良好的回應能力的更復雜的系統,實時作業系統變得非常有價值,對于實時作業系統來說,系統復雜性、ROM、RAM和初始設定時間的增加是為了換取一個更容易理解的系統,它可以更容易地保證對外部事件的及時回應,

參考

如果你對中斷和DMA感到陌生,這里有兩個資源可以很好地描述它們的用途(相對于MCU而言):
對于中斷:https://www.renesas.com/eu/en/support/technical-resources/engineer-school/mcu-programming-peripherals-04-interrupts.html
STM應用說明AN4031--在STM32F7上使用DMA:https://www.st.com/content/ccc/resource/technical/document/application_note/27/46/7c/ea/2d/91/40/a9/DM00046011.pdf/files/DM00046011.pdf/jcr:content/translations/en.DM00046011.pdf

釘釘或微信號: pythontesting 微信公眾號:pythontesting

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/554508.html

標籤:嵌入式

上一篇:Tinyhttpd:原始碼分析【3】

下一篇:返回列表

標籤雲
其他(160505) Python(38206) JavaScript(25478) Java(18205) C(15237) 區塊鏈(8270) C#(7972) AI(7469) 爪哇(7425) MySQL(7234) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4585) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1983) 功能(1967) HtmlCss(1952) Web開發(1951) C++(1932) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1879) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • 微控制器實時作業系統實踐2了解RTOS任務

    ## 2了解RTOS任務 超級回圈編程范式通常是嵌入式系統工程師最先接觸到的編程方法之一。用超級回圈實作的程式有一個單一的頂層回圈,在系統需要執行的各種功能之間回圈。這些簡單的while回圈很容易創建和理解(當它們很小的時候)。在FreeRTOS中,任務與超級回圈非常相似--主要區別在于,系統可以有 ......

    uj5u.com 2023-06-07 08:22:25 more
  • Tinyhttpd:原始碼分析【3】

    ## 一、問題引入 通過 **Tinyhttpd:運行測驗【1】 和 抓包分析【2】**,基本完成了對程式的功能測驗和通信原理。此時可以進一步對原始碼進行分析,本文不考慮代碼一行一行的分析,僅對關鍵部分代碼決議。 ## 二、解決程序 ### 2-1 main()函式 主函式主要創建http的監聽套接字 ......

    uj5u.com 2023-06-06 13:49:45 more
  • Tinyhttpd:原始碼分析【3】

    ## 一、問題引入 通過 **Tinyhttpd:運行測驗【1】 和 抓包分析【2】**,基本完成了對程式的功能測驗和通信原理。此時可以進一步對原始碼進行分析,本文不考慮代碼一行一行的分析,僅對關鍵部分代碼決議。 ## 二、解決程序 ### 2-1 main()函式 主函式主要創建http的監聽套接字 ......

    uj5u.com 2023-06-06 13:47:49 more
  • WIN11安卓子系統WSA閃退之后無法打開應用的解決方法

    網上很多方法都試過,什么“修復”,關掉行程,重啟都試過了,但是想保留資料所以不想重置 **最后發現打不開的原因:C盤空間滿了** 但是我在安裝的時候明明設定在別的盤 ![image](https://img2023.cnblogs.com/blog/2580807/202306/2580807-20 ......

    uj5u.com 2023-06-06 07:42:29 more
  • 一分鐘學一個 Linux 命令 - mkdir 和 touch

    大家好,我是god23bin。歡迎來到《一分鐘學一個 Linux 命令》系列,今天需要你花兩分鐘時間來學習下,因為今天要講的是兩個命令,mkdir 和 touch 命令。前一個命令是操作目錄的,后一個命令是操作檔案的。 ......

    uj5u.com 2023-06-06 07:42:09 more
  • 手把手實踐丨基于STM32+NBIOT+華為云IOT設計智能井蓋

    摘要:本文介紹基于STM32微控制器、BC26 NBIOT模組和華為云IOT平臺,實作了一款智能井蓋系統。 本文分享自華為云社區《基于STM32+NBIOT+華為云IOT設計的智能井蓋》,作者:DS小龍哥 。 一、概述 智能井蓋是一種通過物聯網技術實作對井蓋狀態監測和管理的設備。當前介紹基于STM3 ......

    uj5u.com 2023-06-06 07:41:21 more
  • 如何對VMware虛擬機磁盤擴容?

    ## 前置知識 動態卷管理(LVM,Logical Volume Manger)實作將多個硬碟和硬碟磁區做成一個邏輯卷,并將邏輯卷統一管理。創建LVM順序為:物理卷PV->卷組VG->邏輯卷LV。 物理卷(PV,Physical Volume):物理硬碟或磁區; 卷組(VG,Volume Group ......

    uj5u.com 2023-06-06 07:34:25 more
  • 龍芯、海光、飛騰、兆芯同桌對比性能力求公平

    此日海光新至,為其接風飲宴。席間其樂融融,眾CPU互報姓名,曰:海光C86-3250、龍芯3A5000、飛騰D2000、兆芯KX-U6780A。其間海光3250言其太上蠻橫,只許子弟行走于服務器和作業站之間,圍坐桌面乃是越矩,此番被拘于此方知桌面之妙,愿以文會友,以人鑒己。老夫雖知其本意,卻亦有意相... ......

    uj5u.com 2023-06-02 09:50:25 more
  • kprobe_events shell模式使用教程

    kprobe_events shell模式使用教程 kprobe 使用前提 需要內核啟用以下配置 CONFIG_KPROBES=y CONFIG_HAVE_KPROBES=y CONFIG_KPROBE_EVENT=y kprobe_events kprobe_events有兩種型別:kprobe, ......

    uj5u.com 2023-06-02 09:43:27 more
  • 龍芯、海光、飛騰、兆芯同桌對比性能力求公平

    此日海光新至,為其接風飲宴。席間其樂融融,眾CPU互報姓名,曰:海光C86-3250、龍芯3A5000、飛騰D2000、兆芯KX-U6780A。其間海光3250言其太上蠻橫,只許子弟行走于服務器和作業站之間,圍坐桌面乃是越矩,此番被拘于此方知桌面之妙,愿以文會友,以人鑒己。老夫雖知其本意,卻亦有意相... ......

    uj5u.com 2023-06-02 09:29:01 more