溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何進(jìn)行RT-Thread中斷管理

發(fā)布時(shí)間:2021-12-17 15:47:53 來(lái)源:億速云 閱讀:197 作者:柒染 欄目:互聯(lián)網(wǎng)科技

本篇文章給大家分享的是有關(guān)如何進(jìn)行RT-Thread中斷管理,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。

下面是關(guān)于RT-Thread中斷管理的學(xué)習(xí)總結(jié),包括簡(jiǎn)單地介紹了什么是中斷,裸機(jī)中斷與RT-Thread中斷有什么區(qū)別,RT-Thread是如何處理中斷的,RT-Thread內(nèi)核提供哪些中斷相關(guān)的接口,等等。

從以下幾個(gè)方面總結(jié)一下RT-Thread中斷管理的學(xué)習(xí)過(guò)程

如何進(jìn)行RT-Thread中斷管理
中斷相關(guān)的概念描述

什么是中斷?中斷,顧名思義就是一項(xiàng)正在進(jìn)行的工作,突然間被其他事情打斷,導(dǎo)致原來(lái)正在進(jìn)行的工作不能繼續(xù)正常進(jìn)行,而需要去把其他事情處理完,才能回來(lái)繼續(xù)進(jìn)行原來(lái)的工作。

如何通俗地理解中斷?想象一下這樣的場(chǎng)景,周末你正在家里愉快地寫(xiě)著代碼,突然間你的手機(jī)鈴聲響了,你必須停下手里的工作,記錄代碼寫(xiě)到哪個(gè)階段,然后就去接這個(gè)電話了。“寫(xiě)代碼”就是正在進(jìn)行的工作,“電話響起”就是中斷事件。

這個(gè)電話是媳婦打過(guò)來(lái)的,她讓你去菜市場(chǎng)買(mǎi)點(diǎn)韭菜和豬肉,晚上包餃子吃,媳婦的話哪敢不聽(tīng),于是你覺(jué)得菜市場(chǎng)買(mǎi)東西比較重要,掛掉電話后就去買(mǎi)東西了,買(mǎi)完?yáng)|西回來(lái)后,再接著寫(xiě)剛剛還沒(méi)完成的代碼?!安耸袌?chǎng)買(mǎi)東西”就是中斷服務(wù)程序,這就是一個(gè)典型的中斷處理過(guò)程。

關(guān)于中斷的操作模式和特權(quán)級(jí)別,Cortex-M的處理器有三種狀態(tài)劃分,分別是:特權(quán)級(jí)處理模式,特權(quán)級(jí)線程模式,用戶級(jí)線程模式。這三種狀態(tài)的關(guān)系,如下圖所示。
如何進(jìn)行RT-Thread中斷管理

從上圖可以看出,中斷或異常的服務(wù)程序,總是處于特權(quán)級(jí)處理模式的。而RT-Thread系統(tǒng)內(nèi)核復(fù)位上電時(shí)啟動(dòng)的主線程(main線程),是運(yùn)行在特權(quán)級(jí)線程模式的。其他用戶創(chuàng)建的線程,是運(yùn)行在用戶級(jí)線程模式的。

為什么處理器要區(qū)分特權(quán)級(jí)和用戶級(jí)?特權(quán),顧名思義就是處理器如果工作在這個(gè)級(jí)別下,權(quán)限就會(huì)比較高,就可以訪問(wèn)一些特殊的寄存器,以防止用戶級(jí)的代碼訪問(wèn)這些特殊寄存器,對(duì)數(shù)據(jù)進(jìn)行破壞。中斷由于其特殊性,所以,中斷函數(shù)是工作在特權(quán)級(jí)別下的。

裸機(jī)中斷與操作系統(tǒng)中斷兩者有什么區(qū)別呢?我們?cè)诼銠C(jī)代碼中處理硬件中斷的時(shí)候,一般只要編寫(xiě)中斷處理函數(shù)就可以了,這種方式處理中斷,簡(jiǎn)單且直接。

然而,有了操作系統(tǒng)之后,所有的東西都變了,要考慮的問(wèn)題就多了很多。因?yàn)椴僮骼锩孢\(yùn)行了很多線程,中斷來(lái)了之后,就要告知操作系統(tǒng),把當(dāng)前運(yùn)行線程的信息保存到棧里面,再去處理中斷服務(wù)程序,處理完中斷要再回去處理線程,此時(shí)又可能涉及到線程切換調(diào)度,而線程切換本身又需要PendSV中斷參與。

所以,在裸機(jī)處理中斷和在操作系統(tǒng)中處理中斷,簡(jiǎn)直就是天壤之別。
RT-Thread 中斷處理機(jī)制

了解過(guò)Cortex-M系列單片機(jī)的工程師,一般都知道在芯片的匯編啟動(dòng)文件startup_xxx.s里面,有一個(gè)中斷向量表,所有的中斷都是通過(guò)這個(gè)中斷向量表來(lái)進(jìn)行處理的。

當(dāng)一個(gè)中斷異常觸發(fā)的時(shí)候,處理器將會(huì)判斷是哪個(gè)中斷源,然后跳轉(zhuǎn)到固定位置進(jìn)行處理,每個(gè)中斷服務(wù)程序的地址入口必須是放到統(tǒng)一的地址上,也就是需要設(shè)置到NVIC的中斷向量偏移寄存器里面。

其實(shí),不管有沒(méi)有操作系統(tǒng)的參與,一旦硬件發(fā)送中斷和異常之后,中斷的入口都是在這個(gè)中斷向量表的。區(qū)別無(wú)非就是在裸機(jī)環(huán)境下,直接處理中斷服務(wù)程序,而在有操作系統(tǒng)的情況下,需要先保留線程的運(yùn)行情況,然后再處理中斷,處理完中斷后,再恢復(fù)線程的運(yùn)行環(huán)境。

硬件中斷的優(yōu)先級(jí)是最高的,任何線程的優(yōu)先級(jí)都要低于硬件中斷,因此,只要發(fā)生了硬件中斷事件,系統(tǒng)就必須要進(jìn)行相應(yīng)的處理。

RT-Thread在處理中斷的時(shí)候,一般都會(huì)有三個(gè)階段:中斷前導(dǎo)程序,中斷服務(wù)程序,中斷后續(xù)程序,這三個(gè)階段,如下圖所示。
如何進(jìn)行RT-Thread中斷管理

中斷前導(dǎo)程序的主要工作是,當(dāng)中斷事件發(fā)生的時(shí)候,處理器的硬件會(huì)把當(dāng)前CPU相關(guān)的寄存器參數(shù)自動(dòng)壓入中斷棧里面。程序需要調(diào)用rt_interrupt_enter()函數(shù),把全局變量rt_interrupt_nest進(jìn)行加1操作,這個(gè)全局變量是用來(lái)記錄中斷的嵌套層數(shù)的。

用戶中斷服務(wù)程序的主要工作分兩種情況,一種是不進(jìn)行線程切換,另一種是進(jìn)行線程切換。不進(jìn)行線程切換的話,中斷服務(wù)程序和中斷后續(xù)程序運(yùn)行完成后,將返回被中斷的線程。

而如果要進(jìn)行線程切換,則會(huì)調(diào)用rt_hw_context_switch_interrupt() 函數(shù)進(jìn)行上下文切換,這個(gè)函數(shù)主要是設(shè)置變量rt_interrupt_to_thread,然后觸發(fā)PendSV中斷。

在這里要注意一下:由于PendSV中斷的優(yōu)先級(jí)最低,不能進(jìn)行中斷搶占,因此即使觸發(fā)了該中斷,但由于此時(shí)還在用戶中斷處理函數(shù)里面,所以PendSV中斷還處于等待階段,只有退出了中斷后續(xù)程序,才會(huì)進(jìn)行PendSV中斷處理,才會(huì)進(jìn)行線程的上下文切換。所以,線程的上下文切換是不會(huì)在用戶中斷里面進(jìn)行的,是在中斷結(jié)束后進(jìn)行的。

中斷后續(xù)程序的主要工作是,通知系統(tǒng)內(nèi)核離開(kāi)中斷狀態(tài),通過(guò)調(diào)用rt_interrupt_leave()函數(shù),將全局變量rt_interrupt_nest進(jìn)行減1操作,然后從中斷棧里面恢復(fù)恢復(fù)CPU相關(guān)的寄存器參數(shù)。

這里恢復(fù)CPU寄存器參數(shù)的時(shí)候需要注意,如果在用戶中斷里面涉及到線程切換,那么這個(gè)時(shí)候就需要恢復(fù)到新的線程CPU寄存器參數(shù),而不是恢復(fù)到被中斷打斷的線程CPU寄存器參數(shù)。

RT-Thread操作系統(tǒng)在處理中斷的時(shí)候,通常采用“上半部分(Top Half)”和“底半部分(Bottom Half)”這種方式。原因在于,操作系統(tǒng)本身不會(huì)對(duì)中斷服務(wù)程序的處理時(shí)間做任何假設(shè)和限制,但為了保證系統(tǒng)的實(shí)時(shí)性,用戶需要保證中斷服務(wù)程序在盡可能短的時(shí)間內(nèi)完成。

如何理解“上半部分(Top Half)”和“底半部分(Bottom Half)”這種中斷處理方式?還是以買(mǎi)菜為例。媳婦來(lái)電話讓你到菜市場(chǎng)買(mǎi)菜(中斷事件),但你考慮到如果長(zhǎng)時(shí)間中斷不寫(xiě)代碼,會(huì)導(dǎo)致思路斷鏈,為了避免這種情況(避免長(zhǎng)時(shí)間處理中斷服務(wù)),完全可以在網(wǎng)上下單購(gòu)買(mǎi)(短時(shí)間的中斷處理),生鮮超市收到下單信息(信號(hào)量、郵件、消息隊(duì)列),就會(huì)安排快遞小哥送貨上門(mén),買(mǎi)菜這么耗時(shí)的工作就由其他人(其他線程)去完成了。

“上半部分(Top Half)”和“底半部分(Bottom Half)”這種中斷處理方式,主要是應(yīng)用在一些需要耗時(shí)處理中斷事務(wù)的場(chǎng)合,比如數(shù)據(jù)的接收和處理。通常接收數(shù)據(jù)的時(shí)間比較短,只要把接收到的數(shù)據(jù)保存下來(lái)即可,但處理數(shù)據(jù)的過(guò)程就可能比較耗時(shí),這樣就需要分開(kāi)來(lái)處理,上半部分就是接收數(shù)據(jù),底半部分就是耗時(shí)的數(shù)據(jù)處理。
RT-Thread中斷相關(guān)的API函數(shù)接口

為了把操作系統(tǒng)和硬件底層的中斷異常隔離開(kāi)來(lái),RT-Thread系統(tǒng)內(nèi)核把中斷和異常封裝為一組抽象的接口,具體的函數(shù)接口如下圖所示。
如何進(jìn)行RT-Thread中斷管理
RT-Thread中斷相關(guān)的應(yīng)用示例

RT-Thread中斷相關(guān)的應(yīng)用示例,主要是為了驗(yàn)證中斷相關(guān)的API接口函數(shù),例如全局中斷開(kāi)關(guān)的使用示例,通過(guò)按鍵中斷示例來(lái)驗(yàn)證“上半部分(Top Half)”和“底半部分(Bottom Half)”這種中斷處理方式。

全局中斷開(kāi)關(guān)示例,主要是為了驗(yàn)證多線程訪問(wèn)同一個(gè)變量時(shí),使用開(kāi)關(guān)全局中斷的方式對(duì)該全局變量進(jìn)行臨界區(qū)保護(hù)。

按鍵中斷示例主要是為了驗(yàn)證“上半部分(Top Half)”和“底半部分(Bottom Half)”這種中斷處理方式。通過(guò)按鍵觸發(fā)中斷事件,在中斷服務(wù)函數(shù)里面發(fā)送郵件,通知線程進(jìn)行相應(yīng)的處理。
在irq_test.h頭文件里面,通過(guò)打開(kāi)相應(yīng)的宏定義開(kāi)關(guān),重新編譯工程源碼,下載到開(kāi)發(fā)板即可驗(yàn)證實(shí)驗(yàn)現(xiàn)象,如下圖所示。

RT-Thread中斷應(yīng)用的注意事項(xiàng)

中斷是一種異常,當(dāng)系統(tǒng)發(fā)生中斷異常的時(shí)候就必須要進(jìn)行處理,在RT-Thread實(shí)時(shí)操作系統(tǒng)里面處理中斷的時(shí)候,如果不及時(shí)處理或?qū)χ袛嗵幚聿划?dāng),輕則會(huì)造成系統(tǒng)出錯(cuò)或邏輯混亂,重則會(huì)導(dǎo)致系統(tǒng)毀滅性地癱瘓。

在處理RT-Thread中斷異常的時(shí)候,有以下注意事項(xiàng):

1.中斷服務(wù)程序工作在特權(quán)級(jí)處理模式,優(yōu)先級(jí)比任何線程要高,任何線程都不能搶占中斷服務(wù)程序。

2.在操作系統(tǒng)里面,可以支持中斷嵌套,高優(yōu)先級(jí)中斷可以搶占低優(yōu)先級(jí)中斷,線程的重新調(diào)度是在所有中斷都處理完之后才重新啟動(dòng)的。

3.在Cortex-M架構(gòu)里面,中斷發(fā)生時(shí)CPU的寄存器入棧是由硬件自動(dòng)完成的,中斷的前導(dǎo)程序通常只是記錄中斷的嵌套層數(shù)。

4.RT-Thread采用獨(dú)立的內(nèi)存空間作為中斷棧,而不是采用線程棧作為中斷棧,這種方式隨著線程的增加,減少內(nèi)存占用的效果也越明顯。

5.建議采用“上半部分(Top Half)”和“底半部分(Bottom Half)”這種方式來(lái)處理中斷異常,中斷服務(wù)程序的處理時(shí)間應(yīng)盡可能短。

6.使用全局中斷開(kāi)關(guān)是禁止多線程訪問(wèn)臨界區(qū)最簡(jiǎn)單的一種方式,這種方式可以應(yīng)用在任何場(chǎng)合,但要注意這種方式對(duì)系統(tǒng)實(shí)時(shí)性影響巨大,使用不當(dāng)會(huì)破壞系統(tǒng)的實(shí)時(shí)性能。使用全局中斷鎖的時(shí)間應(yīng)盡可能短。

7.全局中斷開(kāi)關(guān)支持多級(jí)中斷嵌套使用,每次調(diào)用rt_hw_interrupt_enable()函數(shù),可以讓系統(tǒng)恢復(fù)到關(guān)中斷之前的狀態(tài)(這個(gè)狀態(tài)有可能是關(guān)中斷也有可能是開(kāi)中斷)。

8.中斷服務(wù)程序是運(yùn)行在特權(quán)處理模式下的,在這種運(yùn)行模式里面是不能使用掛起當(dāng)前線程操作的相關(guān)函數(shù)的,因?yàn)橹袛喾?wù)程序的運(yùn)行環(huán)境里面根本不存在線程。

以上就是如何進(jìn)行RT-Thread中斷管理,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI