0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

利用TIMER事件和棧幀體驗(yàn)中斷響應(yīng)

茶話MCU ? 來源:茶話MCU ? 2023-11-05 16:45 ? 次閱讀

目前STM32芯片都是基于各種ARM Cortex-M內(nèi)核的芯片,支持可編程中斷優(yōu)先級(jí)。支持中斷搶占的同時(shí),還中斷響應(yīng)的晚到和咬尾機(jī)制。中斷搶占不難理解,就是某中斷在運(yùn)行時(shí)產(chǎn)生了另外的更高優(yōu)先級(jí)的中斷事件,低優(yōu)先級(jí)的中斷服務(wù)程序被暫停而去執(zhí)行優(yōu)先級(jí)更高的中斷服務(wù)程序【后面中斷服務(wù)程序用ISR表示】。所謂晚到機(jī)制,就是中斷響應(yīng)還在壓棧階段但沒有正式進(jìn)入ISR時(shí)又來了更高優(yōu)先級(jí)的中斷請(qǐng)求,等壓棧操作完成后,則立刻執(zhí)行高優(yōu)先級(jí)的ISR,此時(shí)高優(yōu)先級(jí)中斷省去壓棧操作,它執(zhí)行完后再返回執(zhí)行剛才申請(qǐng)壓棧的低優(yōu)先級(jí)ISR。而咬尾機(jī)制則是指某ISR正在執(zhí)行過程中產(chǎn)生了新的不高于當(dāng)前中斷優(yōu)先級(jí)的中斷事件,一直等到當(dāng)前中斷ISR執(zhí)行完畢,在退棧之前立即響應(yīng)處于等待執(zhí)行的ISR,此時(shí)該中斷也無須再做壓棧。不難理解,不論晚到機(jī)制還是咬尾機(jī)制都是為了提高中斷響應(yīng)速度,提高芯片性能。

下面是三幅分別代表中斷搶占、中斷晚到、中斷咬尾的示意圖?!咀ⅲ簭臅r(shí)間上講,雖然發(fā)生中斷晚到、中斷咬尾可以顯著節(jié)省時(shí)間,但也不等于從中斷申請(qǐng)到進(jìn)入ISR完全不要時(shí)間,下面圖中沒有體現(xiàn)出來?!?/p>

651c51b4-7bb7-11ee-939d-92fbcf53809c.png

6527b1e4-7bb7-11ee-939d-92fbcf53809c.png

653cdd12-7bb7-11ee-939d-92fbcf53809c.png

對(duì)于這幾個(gè)中斷響應(yīng)的概念,我們是否可以比較直觀地感受下呢?

或許有人想過一些諸如時(shí)間記錄、波形輸出等方法來感受之。這里,我想從中斷響應(yīng)先后順序加上棧幀內(nèi)容變化來體會(huì)中斷搶占、中斷晚到和中斷咬尾。

對(duì)于Cortex M系列芯片【這里暫時(shí)將M33除外,我不知這個(gè)地方加上Security是否有很大差異。印象中只是有兩套而已】,發(fā)生中斷需要壓棧的話,壓棧內(nèi)容根據(jù)是否啟用浮點(diǎn)存儲(chǔ)來進(jìn)行。

654a5fd2-7bb7-11ee-939d-92fbcf53809c.png

上圖表述了兩種壓棧格式。這里我們只關(guān)注右邊的壓棧格式,后面試驗(yàn)不使用浮點(diǎn)存儲(chǔ)。

我這里借助Cortex-M4內(nèi)核的STM32G4芯片的TIM1/TIM2的更新中斷來完成試驗(yàn)。二者建立主從同步啟動(dòng)關(guān)系,TIM1的搶占優(yōu)先級(jí)高于TIM2的,均工作在單脈沖模式,即每次啟動(dòng)后都能且只能產(chǎn)生1次更新中斷。通過給二者設(shè)置相應(yīng)的溢出時(shí)間參數(shù),來模擬實(shí)現(xiàn)上面的三種情形。我們從中關(guān)注棧幀和個(gè)別特定寄存器的內(nèi)容。【注:本試驗(yàn)過程中僅開啟了TIM1/TIM2更新事件中斷,再無其它?!?/p>

654e30a8-7bb7-11ee-939d-92fbcf53809c.png

65664b98-7bb7-11ee-939d-92fbcf53809c.png

對(duì)于發(fā)生搶占情形,我們通過在代碼里設(shè)置斷點(diǎn),一方面可以看到2個(gè)中斷的響應(yīng)先后,另一方面可以看到因搶占動(dòng)作導(dǎo)致棧幀內(nèi)容的變動(dòng)。

對(duì)于晚到情形和晚到情形,同樣也會(huì)通過在代碼里設(shè)置斷點(diǎn)查看中斷執(zhí)行先后順序。

對(duì)于晚到情形,申請(qǐng)壓棧的是低優(yōu)先級(jí)中斷事件,先得到執(zhí)行的則是高優(yōu)先級(jí)中斷,同時(shí)會(huì)發(fā)現(xiàn)雖然響應(yīng)了2次中斷,卻只看到1次壓棧,兩次ISR運(yùn)行時(shí)維持同一棧內(nèi)容。對(duì)于咬尾情形在棧幀內(nèi)容變化上跟晚到情形類似,但實(shí)現(xiàn)機(jī)理不同,它申請(qǐng)壓棧的是高優(yōu)先級(jí)或同級(jí)中斷事件,做咬尾操作的是低優(yōu)先級(jí)或晚發(fā)生中斷請(qǐng)求的同級(jí)中斷。

先介紹兩個(gè)跟中斷返回有關(guān)的寄存器LR(R14)和EXC_RETURN。糾正下,EXC_RETURN不是寄存器,是微處理器動(dòng)態(tài)生成的跟中斷返回有關(guān)的一個(gè)值。這個(gè)值有點(diǎn)神秘,也很重要。神秘的就是這個(gè)值怎么產(chǎn)生的、放在哪里的,似乎在ARM相關(guān)手冊(cè)找不到具體說明。另外,這個(gè)值本身很特別,大大區(qū)別于通用程序運(yùn)行地址。如果程序里不啟用浮點(diǎn)存儲(chǔ),它的值可能是下面三個(gè)。

65814524-7bb7-11ee-939d-92fbcf53809c.png

這里我們重點(diǎn)關(guān)注圖中的前2個(gè),后面試驗(yàn)過程中會(huì)見到這兩個(gè)值。結(jié)合圖中信息,如果該值等于0xfffffff1,ISR執(zhí)行完畢后要返回Handle Mode和Main Stack,極大可能地發(fā)生了中斷嵌套;如果該值等于0xfffffff9,ISR執(zhí)行完畢后要返回Thread Mode和Main Stack,意味著當(dāng)前中斷是在線程中產(chǎn)生的,不用OS的話,即Main程序被打斷。

它很重要,中斷返回得仰仗它。沒有它,中斷返回可能就亂套了。

每當(dāng)中斷壓棧申請(qǐng)完成后,這個(gè)EXC_RETURN值就被硬件根據(jù)中斷發(fā)生時(shí)CPU運(yùn)行狀態(tài)、運(yùn)行模式、所用棧幀模式給生成好了,并在開始運(yùn)行ISR之前將該值主動(dòng)賦給LR寄存器。硬件在ISR執(zhí)行完畢即將退棧返回時(shí)又自動(dòng)將LR的內(nèi)容提供給PC寄存器。當(dāng)PC寄存器發(fā)現(xiàn)這個(gè)特殊的值后會(huì)不會(huì)一臉懵逼,啥玩意?地址不像地址。我們可以把這個(gè)值理解成中斷返回告知書,并非程序地址。EXC_RETURN值通過LR寄存器做中間人傳達(dá)給PC,主要傳達(dá)下面幾個(gè)信息:

1、恭喜我們完美地處理了剛才的突發(fā)事件,要?dú)w隊(duì)返回了;

2、我們清楚剛才處理事情時(shí)的狀態(tài)和待遇,但更要清楚返回后的狀態(tài)、模式,不得以剛才的模式或狀態(tài)來套返回后的模式或狀態(tài),不能因出了趟差就不知回家后的姿態(tài)和責(zé)任;

3、記住上面提到的,具體返回路線會(huì)專人提供【即之前壓棧的PC值經(jīng)出棧提供】;

戲說下,知道大意即可,更多細(xì)節(jié)可以查看相關(guān)手冊(cè)。退一步講,個(gè)中細(xì)節(jié)我們旁人也真的難以知曉。

鋪墊性的話題就聊到這里。下面具體看看針對(duì)中斷搶占、中斷晚到、中斷咬尾的試驗(yàn)。

先看中斷搶占的情形。下面截圖是有關(guān)TIM1/TIM2時(shí)基參數(shù)的配置。

659e4368-7bb7-11ee-939d-92fbcf53809c.png

在前面提到的固定配置前提下,我將TIM2溢出周期比TIM1少21個(gè)脈沖【這個(gè)地方不是固定的,14~24應(yīng)該都可以,具體自行驗(yàn)證】,二者同步啟動(dòng)。這樣配置的目的就是確保TIM2一定是先進(jìn)中斷但又不至于它執(zhí)行完畢了TIM1中斷還沒來,否則就沒法看到搶占情形了。下圖是TIM2首先進(jìn)入中斷時(shí)的情形:

65a6759c-7bb7-11ee-939d-92fbcf53809c.png

從上圖可以看出,TIM2首先進(jìn)入中斷,棧幀有新內(nèi)容放入。LR寄存器為0xfffffff9,表示當(dāng)前中斷ISR是從線程模式下發(fā)生的,這里就是main程序被打斷了。

下圖是TIM1中斷搶占TIM2中斷的情形。

65d0abfa-7bb7-11ee-939d-92fbcf53809c.png

從上圖中,明顯看到棧幀內(nèi)容再次被添加了8個(gè)字的內(nèi)容,內(nèi)容變多。我們還可以從LR寄存器的內(nèi)容看出,結(jié)尾是F1,說明當(dāng)前中斷是搶占了其它低優(yōu)先級(jí)中斷,即發(fā)生了中斷嵌套,它執(zhí)行完后返回的還是handle模式,這跟它搶占了TIM2 ISR相吻合。

下圖是TIM1 ISR執(zhí)行完畢CPU再回來執(zhí)行剛才被打斷的TIM2ISR情形。

65eaa8ca-7bb7-11ee-939d-92fbcf53809c.png

從上圖可以看出,TIM1中斷搶占TIM2中斷并完成ISR后,在返回TIM2 ISR之前還做了出棧操作。在當(dāng)前TIM2 ISR里可以看到棧幀恢復(fù)到TIM2中斷剛被響應(yīng)時(shí)的情形,內(nèi)容變少了。同樣,我們可以發(fā)現(xiàn)LR寄存器內(nèi)容也恢復(fù)到剛被響應(yīng)時(shí)的值。

顯然,發(fā)生搶占時(shí)除了看到ISR執(zhí)行的順序外,明顯地看到棧幀內(nèi)容的變化。

接著看看中斷晚到的情形。先看TIM1/TIM2基本時(shí)基配置。

65f02f0c-7bb7-11ee-939d-92fbcf53809c.png

這樣配置的目的,就是讓優(yōu)先級(jí)低的TIM2提前一點(diǎn)點(diǎn)發(fā)生中斷,讓它在申請(qǐng)壓棧完成附近發(fā)生TIM1中斷,TIM2 ISR并不能立即執(zhí)行反而是TIM1搶先【不是搶占】執(zhí)行ISR,之后再來運(yùn)行TIM2 ISR。整個(gè)過程,只發(fā)生1次壓棧、出棧操作。TIM1中斷事件雖然晚發(fā)生,由于其高優(yōu)先級(jí)和卡著點(diǎn)發(fā)生而搶先執(zhí)行其ISR。

開始運(yùn)行程序后,TIM1 ISR首先得到響應(yīng)?!緟⒓訄D中備注說明】

6603cb5c-7bb7-11ee-939d-92fbcf53809c.png

下圖是TIM2 ISR得到執(zhí)行的情形:

6629440e-7bb7-11ee-939d-92fbcf53809c.png

TIM1中斷執(zhí)行完畢后,回頭來繼續(xù)執(zhí)行TIM2 ISR時(shí),棧幀內(nèi)容無變化。兩次中斷得到執(zhí)行,只看到1次壓棧操作。執(zhí)行順序靠TIMER時(shí)間參數(shù)保證TIM2的中斷事件先發(fā)生并由其申請(qǐng)壓棧, TIM1事件雖晚到卻因高優(yōu)先級(jí)而被優(yōu)先執(zhí)行其ISR。

最后來看看中斷咬尾的情形。TIM1/TIM2時(shí)基參數(shù)配置如下:

66493e26-7bb7-11ee-939d-92fbcf53809c.png

二者設(shè)置的時(shí)基參數(shù)一樣,上面TIM1的溢出周期減個(gè)1不是必須的,這里主要是為了確保TIM1中斷事件不要晚于TIM2的即可,因?yàn)門IM1優(yōu)先級(jí)高。二者同時(shí)申請(qǐng)中斷,自然先響應(yīng)TIM1的。

下圖是TIM1 中斷首先得到響應(yīng)的情形:

664e00f0-7bb7-11ee-939d-92fbcf53809c.png

下圖是TIM1 ISR執(zhí)行完后運(yùn)行TIM2 ISR的情形:

66713a84-7bb7-11ee-939d-92fbcf53809c.png

TIM2 ISR基于TIM1申請(qǐng)壓棧并完成ISR后接著執(zhí)行,也省去了壓棧過程,完成2次中斷只見1次壓棧。從棧幀內(nèi)容結(jié)果上看,中斷晚到和中斷咬尾很類似。不過,中斷晚到情形下,申請(qǐng)壓棧的是低優(yōu)先級(jí)的中斷事件,而咬尾中斷情形下,申請(qǐng)壓棧的是高優(yōu)先級(jí)或者是先申請(qǐng)壓棧的同級(jí)中斷事件。比方以現(xiàn)在討論的中斷咬尾情形為例,如果把TIM1/TIM2的搶占優(yōu)先級(jí)設(shè)置一樣,其它參數(shù)不變。這時(shí)玩咬尾動(dòng)作的就是TIM1中斷了,因?yàn)槎邇?yōu)先級(jí)一樣,TIM2先產(chǎn)生溢出中斷自然先響應(yīng)它的,TIM1的中斷則等它執(zhí)行完ISR基于咬尾機(jī)制而得以執(zhí)行。

不難看出,基于晚到機(jī)制和咬尾機(jī)制而得以執(zhí)行中斷的行為不屬于中斷搶占。順便提醒下,如果通過上面方式體驗(yàn)中斷響應(yīng)的話,測(cè)試代碼盡量簡(jiǎn)單,尤其中斷服務(wù)程序,否則若棧幀里壓入太多其它信息,觀察分析起來可能就不太方便了。


好,今天的分享就聊到這里。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 芯片
    +關(guān)注

    關(guān)注

    450

    文章

    49636

    瀏覽量

    417172
  • ARM
    ARM
    +關(guān)注

    關(guān)注

    134

    文章

    8967

    瀏覽量

    365039
  • STM32
    +關(guān)注

    關(guān)注

    2258

    文章

    10828

    瀏覽量

    352492
  • Cortex
    +關(guān)注

    關(guān)注

    2

    文章

    201

    瀏覽量

    46258
  • 中斷響應(yīng)
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    2933

原文標(biāo)題:利用TIMER事件和棧幀體驗(yàn)中斷響應(yīng)

文章出處:【微信號(hào):stmcu832,微信公眾號(hào):茶話MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    C函數(shù)調(diào)用機(jī)制與原理詳解

    當(dāng)一個(gè)C函數(shù)被調(diào)用時(shí),函數(shù)的參數(shù)如何傳遞、堆棧指針如何變化、是如何被建立以及如何被消除的,一直缺乏系統(tǒng)性的理解,因此決定花時(shí)間學(xué)習(xí)下函數(shù)調(diào)用時(shí)整個(gè)調(diào)用機(jī)制并總結(jié)成文,以便加深理解。本文將從匯編的角度講解函數(shù)調(diào)用時(shí),堆棧的變化,參數(shù)的傳遞方式、以及
    發(fā)表于 06-08 10:49 ?997次閱讀
    C函數(shù)調(diào)用機(jī)制與<b class='flag-5'>棧</b><b class='flag-5'>幀</b>原理詳解

    如何利用IDLE中斷去判斷一數(shù)據(jù)是否結(jié)束了呢

    stm32串口空閑中斷如何接受完整的不定長(zhǎng)的一數(shù)據(jù)?如何利用IDLE中斷去判斷一數(shù)據(jù)是否結(jié)束了呢?
    發(fā)表于 12-09 06:03

    如何利用STM32F1的串口空閑中斷實(shí)現(xiàn)不定長(zhǎng)的數(shù)據(jù)斷

    常見的數(shù)據(jù)方式有哪幾種?如何利用STM32F1的串口空閑中斷實(shí)現(xiàn)不定長(zhǎng)的數(shù)據(jù)斷呢?
    發(fā)表于 12-09 06:10

    利用STM32F1的串口空閑中斷實(shí)現(xiàn)不定長(zhǎng)的數(shù)據(jù)斷

    常見的數(shù)據(jù)方式有兩種,一種是通過固定的協(xié)議格式斷,另外一個(gè)是通過兩幀數(shù)據(jù)的時(shí)間斷,下面介紹最后一種,利用STM32F1的串口空閑
    發(fā)表于 02-17 07:55

    用一個(gè)實(shí)例展示一下Linux內(nèi)核的入和退過程

    1、Linux內(nèi)核調(diào)試方法總結(jié)之    和指針可以說是C語言的精髓。
    發(fā)表于 11-04 15:47

    基于單片機(jī)的中斷控制程序(蜂鈴器_timer1)【C語言】

    基于單片機(jī)的中斷控制程序(蜂鈴器_timer1)【C語言】
    發(fā)表于 12-29 18:17 ?13次下載

    基于單片機(jī)的中斷控制程序(timer0)【C語言版】

    基于單片機(jī)的中斷控制程序(timer0)【C語言版】
    發(fā)表于 12-29 18:17 ?0次下載

    基于TIMER3發(fā)生捕獲中斷丟失問題分析與總結(jié)

    在一洗衣機(jī)MC項(xiàng)目中,客戶選擇使用STM32F030作為主控芯片。使用TIMER3(CH3)來捕獲電機(jī)的HALL Sensor的中斷,同時(shí)使用TIMER3(CH2)的OC功能,在OC match
    的頭像 發(fā)表于 01-15 15:11 ?5753次閱讀
    基于<b class='flag-5'>TIMER</b>3發(fā)生捕獲<b class='flag-5'>中斷</b>丟失問題分析與總結(jié)

    基于51單片機(jī)的串口中斷發(fā)送數(shù)據(jù)

    很少看到有資料寫如何以中斷的方式發(fā)送一數(shù)據(jù),如果以等待的發(fā)送 數(shù)據(jù) ,對(duì)高速運(yùn)行的 單片機(jī) 來說是很浪費(fèi)時(shí)間的,下面就介紹一種使用中斷方式發(fā)送數(shù)據(jù)
    的頭像 發(fā)表于 06-03 09:23 ?1w次閱讀

    如何利用利用TimerA及中斷實(shí)現(xiàn)RTC

    D13x Demo - 利用Timer_A及中斷實(shí)現(xiàn)RTC,觀察LED燈的閃爍頻率 // 描述:利用Timer_A及
    發(fā)表于 11-26 14:59 ?1578次閱讀
    如何<b class='flag-5'>利用</b><b class='flag-5'>利用</b>TimerA及<b class='flag-5'>中斷</b>實(shí)現(xiàn)RTC

    什么是單片機(jī)的中斷響應(yīng)時(shí)間

    中斷響應(yīng)時(shí)間:從外部中斷請(qǐng)求有效(外部中斷請(qǐng)求標(biāo)志置1)到轉(zhuǎn)向中斷入口地址所需要的響應(yīng)時(shí)間。每個(gè)
    發(fā)表于 12-19 15:57 ?9653次閱讀
    什么是單片機(jī)的<b class='flag-5'>中斷</b><b class='flag-5'>響應(yīng)</b>時(shí)間

    MPSoC,XEN虛擬機(jī)運(yùn)行裸核的2種中斷響應(yīng)延遲情況

    作者:hankf,Xilinx Employee 修改Xilinx的定時(shí)器裸核應(yīng)用程序(baremetal, standalone)例子xttcps_intr_example.c,可以測(cè)量中斷響應(yīng)
    的頭像 發(fā)表于 12-08 12:29 ?1173次閱讀

    Keil MDK 5.33 運(yùn)行華大官方示例無法進(jìn)入 Timer0 中斷

    Keil MDK 5.33 運(yùn)行華大官方示例無法進(jìn)入 Timer0 中斷
    發(fā)表于 11-23 18:06 ?1次下載
    Keil MDK 5.33 運(yùn)行華大官方示例無法進(jìn)入 <b class='flag-5'>Timer</b>0 <b class='flag-5'>中斷</b>

    微機(jī)原理——8086中斷類型以及中斷向量表、中斷響應(yīng)、中斷返回

    響應(yīng)1、外部可屏蔽中斷響應(yīng)2、外部不可屏蔽中斷響應(yīng)3、內(nèi)部中斷
    發(fā)表于 11-24 16:51 ?16次下載
    微機(jī)原理——8086<b class='flag-5'>中斷</b>類型以及<b class='flag-5'>中斷</b>向量表、<b class='flag-5'>中斷</b><b class='flag-5'>響應(yīng)</b>、<b class='flag-5'>中斷</b>返回

    什么是中斷響應(yīng)次序?什么是中斷處理次序?

    什么是中斷響應(yīng)次序?什么是中斷處理次序? 中斷響應(yīng)次序和中斷處理次序是計(jì)算機(jī)系統(tǒng)中非常重要的概念
    的頭像 發(fā)表于 10-24 11:49 ?2014次閱讀