前不久在研究SYSTICK有關(guān)問(wèn)題閱讀相關(guān)技術(shù)資料時(shí),無(wú)意間產(chǎn)生了個(gè)小疑惑。
問(wèn)題是這樣的,我們知道SYSTICK定時(shí)器是個(gè)24位向下計(jì)數(shù)器,每當(dāng)發(fā)生從1記到0時(shí)會(huì)讓一個(gè)名為COUNTFLAG的標(biāo)志位置1,如果此時(shí)SYSTICK的滴答中斷請(qǐng)求使能了的話,可以對(duì)CPU發(fā)起中斷請(qǐng)求。
根據(jù)我們平常STM32的開(kāi)發(fā)經(jīng)驗(yàn),通常各種外設(shè)事件發(fā)起中斷請(qǐng)求時(shí),往往有相應(yīng)的事件標(biāo)志跟中斷響應(yīng)關(guān)聯(lián),在中斷服務(wù)程序里并將相關(guān)事件標(biāo)志做清零操作,否則它會(huì)沒(méi)完沒(méi)了地發(fā)起中斷請(qǐng)求?;谶@點(diǎn),我想這個(gè)COUNTFLAG標(biāo)志應(yīng)該也是跟SYSTICK中斷密切相關(guān),溢出時(shí)被置位,在SYSTICK中斷服務(wù)程序里將其清零。
可是,我們平常的SYSTICK的中斷服務(wù)程序里根本沒(méi)看到哪里有對(duì)COUNTFLAG標(biāo)志做清零。ARM
Cortex內(nèi)核手冊(cè)針對(duì)COUNTFLAG標(biāo)志的描述中涉及它可以清零的地方有兩處:
第一個(gè)地方是在SYSTICK控制寄存器【SYST_CSR】里有介紹,讀它可以清零。說(shuō)實(shí)在的,這點(diǎn)我是通過(guò)咨詢ARM公司才理解到位的。第二個(gè)地方是在介紹SYSTCIK的當(dāng)前計(jì)數(shù)器寄存器時(shí)提到,即對(duì)當(dāng)前計(jì)數(shù)器寄存器進(jìn)行寫(xiě)操作時(shí)也會(huì)將COUNTFLAG標(biāo)志清零。
問(wèn)題是平常的SYSTICK的中斷服務(wù)程序里根本就沒(méi)有涉及到上面提到的可能對(duì)COUNTFLAG標(biāo)志清零的操作???!既沒(méi)有讀SYSTICK控制寄存器,也沒(méi)有對(duì)計(jì)數(shù)器做寫(xiě)操作。那這個(gè)標(biāo)志啥時(shí)候被清零的呢?如果不清零的話,難道不會(huì)沒(méi)完沒(méi)了地申請(qǐng)中斷,可現(xiàn)在的實(shí)踐結(jié)果又不是這樣的!
后來(lái),找同事咨詢、討論,有同事說(shuō)他印象中計(jì)數(shù)器重裝時(shí)會(huì)將該標(biāo)志清零。如果說(shuō)重裝可以清COUNTFLAG的話,這樣可以很好地解釋目前的結(jié)果。因?yàn)榧热幻看沃匮b可以清零,自然用不著到中斷服務(wù)程序里再做清零,那么在中斷服務(wù)程序里見(jiàn)不到對(duì)COUNTFLAG的清零操作也就再正常不過(guò)了。也因此一時(shí)以為找到了答案??珊髞?lái)一想,還是有些不對(duì)勁的地方。至少有2點(diǎn)說(shuō)不通。
第一、如果是重裝時(shí)清零,該標(biāo)志是溢出時(shí)被置1的,而溢出和重裝兩個(gè)動(dòng)作可以看成同一時(shí)刻完成,即置位后馬上被清零。這樣的話,用戶永遠(yuǎn)沒(méi)有機(jī)會(huì)見(jiàn)到該標(biāo)志為1的時(shí)候。何時(shí)能被軟件用得上呢?定義這個(gè)標(biāo)志意義何在呢?
第二、關(guān)于這個(gè)標(biāo)志,在ARM 內(nèi)核手冊(cè)里還說(shuō)了一句話
意思就是說(shuō)用戶軟件可以通過(guò)查看COUNTFLAG標(biāo)志來(lái)確認(rèn)SYSTICK之前有發(fā)生過(guò)溢出。如果重裝可以清零的話,用戶軟件是不可能有機(jī)會(huì)讀到該標(biāo)志為1的時(shí)候。也就是說(shuō)重裝清零結(jié)論跟這句話是矛盾的。
經(jīng)過(guò)與同事的來(lái)回討論,以及查找其它相關(guān)信息,后來(lái)認(rèn)為這個(gè)標(biāo)志可能跟中斷沒(méi)有必然關(guān)系。這個(gè)過(guò)程中我也意識(shí)到我提出這個(gè)標(biāo)志哪里清零的問(wèn)題,可能是先入為主的慣性思維在作怪。具體點(diǎn)說(shuō),我們認(rèn)為這個(gè)COUNTFLAG標(biāo)志在發(fā)生溢出時(shí)置位沒(méi)問(wèn)題,前面提到的兩種情形下會(huì)被清零也沒(méi)問(wèn)題。但是,SYSTICK的滴答中斷不跟這個(gè)標(biāo)志位關(guān)聯(lián),它只與計(jì)數(shù)器發(fā)生從1計(jì)到0的事件有關(guān),即手冊(cè)中下面綠色方框框住的這句話。
說(shuō)實(shí)在的,這句話我老早就看到了,只是覺(jué)得溢出做為中斷觸發(fā)條件沒(méi)錯(cuò),但一門(mén)心思老糾結(jié)著哪個(gè)地方對(duì)COUNTFLAG清零了。
如果說(shuō)COUNTFLAG只是個(gè)溢出事件標(biāo)志,滴答中斷不跟它關(guān)聯(lián)也是可以理解和接受的。首先,根據(jù)ARM手冊(cè)描述來(lái)理解這個(gè)結(jié)論沒(méi)有問(wèn)題,沒(méi)有說(shuō)不通的地方,然后,實(shí)現(xiàn)邏輯上也沒(méi)啥問(wèn)題,反正溢出一次就申請(qǐng)一次中斷。
聊到這里,很多STM32用戶【包括本人在內(nèi)】可能會(huì)覺(jué)得有點(diǎn)別扭或不習(xí)慣,這點(diǎn)我們下面繼續(xù)聊。我就我們針對(duì)COUNTFLAG標(biāo)志跟SYSTICK中斷的關(guān)系的理解,說(shuō)得直白點(diǎn)就是SYSTICK中斷跟COUNTFLAG有無(wú)關(guān)系、服務(wù)程序里要不要清零再次找ARM公司做了確認(rèn),他們完全認(rèn)同我們的理解。即COUNTFLAG只是個(gè)溢出事件標(biāo)志,SYSTICK中斷不跟它關(guān)聯(lián),只與計(jì)數(shù)器溢出事件本身關(guān)聯(lián),并不關(guān)心COUNTFLAG的值是0還是1。到此,關(guān)于COUNTFLAG要不要在服務(wù)程序里清零的疑惑算是塵埃落定。
但是------
用過(guò)STM32外設(shè)事件申請(qǐng)中斷的人應(yīng)該很清晰地知道,要想各個(gè)外設(shè)事件中斷申請(qǐng)能得到響應(yīng)的話,除了NVIC端接受響應(yīng)、外設(shè)端允許申請(qǐng)中斷外,還得有相應(yīng)的事件發(fā)生【包括軟件方式】以及對(duì)應(yīng)的事件標(biāo)志被置位【或者說(shuō)應(yīng)該有效】,中斷服務(wù)程序跟相應(yīng)事件標(biāo)志直接相關(guān),即發(fā)生中斷響應(yīng)時(shí)中斷事件標(biāo)志必須有效,并需在中斷服務(wù)程序里對(duì)標(biāo)志清零,否則會(huì)沒(méi)完沒(méi)了地申請(qǐng)中斷、響應(yīng)中斷。顯然,這個(gè)過(guò)程跟前面SYSTICK中斷有點(diǎn)不一樣。SYSTICK中斷雖然設(shè)置了溢出事件標(biāo)志,但其中斷并沒(méi)有跟該標(biāo)志關(guān)聯(lián)起來(lái)。事實(shí)上這樣運(yùn)行起來(lái)也沒(méi)有任何問(wèn)題,那么ST設(shè)計(jì)的外設(shè)申請(qǐng)中斷怎么非要跟標(biāo)志位關(guān)聯(lián)在一起呢?我們平常做STM32開(kāi)發(fā)時(shí),有時(shí)因?yàn)槭韬龌蛟聿粔蚯逦?,沒(méi)及時(shí)清零中斷請(qǐng)求標(biāo)志讓CPU沒(méi)完沒(méi)了地進(jìn)中斷而陷入異常。
why?
整體上,STM32微控制器是由ARM處理器和ST外設(shè)集成而來(lái),ARM
處理器又包括內(nèi)核、核外設(shè)【以示區(qū)別于ST公司設(shè)計(jì)的外設(shè)】。其中SYSTICK、FPU、MPU、NVIC等均屬于核外設(shè)。也就是說(shuō),SYSTICK是ARM的外設(shè),不是ST設(shè)計(jì)的。既然這樣,難道只是設(shè)計(jì)思路上的差異?但是,SYSTICK中斷可以不跟事件標(biāo)志關(guān)聯(lián)起來(lái),可以行得通,為什么ST不也這樣設(shè)計(jì)呢?
一起來(lái)看看,嘗試找找原因。
原因在于SYSTICK外設(shè)就一個(gè)溢出事件可以申請(qǐng)中斷,在NVIC那邊獨(dú)立對(duì)應(yīng)一個(gè)中斷請(qǐng)求號(hào)【IRQ#],所以CPU在響應(yīng)SYSTICK中斷時(shí)根本無(wú)需關(guān)注那個(gè)溢出標(biāo)志,有那個(gè)溢出事件就夠了,因?yàn)槌诉@個(gè)溢出事件沒(méi)別的事件來(lái)申請(qǐng)TICK中斷。
而ST的外設(shè)申請(qǐng)中斷時(shí)就沒(méi)有SYSTICK那么好的福分了。往往是一個(gè)外設(shè)的多個(gè)事件共用1個(gè)中斷請(qǐng)求。比方以上面STM32G4系列ADC3的中斷來(lái)看,因?yàn)樗挥?個(gè)中斷申請(qǐng)?zhí)?,在CPU看來(lái)就一個(gè)中斷入口,即所有ADC3相關(guān)事件觸發(fā)的中斷共用一個(gè)中斷服務(wù)程序入口,但可以申請(qǐng)中斷的事件可多了,見(jiàn)下圖【我后面把能觸發(fā)同一中斷請(qǐng)求的事件稱之為兄弟事件】:
再以SPI3和LPTIM1的中斷為例,它倆也各只有一個(gè)中斷請(qǐng)求號(hào),同樣可以申請(qǐng)中斷的事件也不少。
顯然,ST設(shè)計(jì)的外設(shè)不能照搬SYSTICK的玩法。如果中斷服務(wù)程序不跟觸發(fā)事件標(biāo)志關(guān)聯(lián)起來(lái),進(jìn)了中斷就不知該基于哪個(gè)事件來(lái)運(yùn)行程序;基于某個(gè)事件運(yùn)行了中斷服務(wù)程序若不對(duì)它清零【包括讀清零、寫(xiě)清零等】,等兄弟事件觸發(fā)再進(jìn)來(lái)時(shí)如何分得清哪是過(guò)時(shí)事件、哪是新觸發(fā)的即時(shí)事件?
或許有人會(huì)說(shuō),為什么不給每個(gè)ST外設(shè)事件都安排一個(gè)中斷請(qǐng)求號(hào)呢?這要考慮到必要性和中斷請(qǐng)求號(hào)的有限性。不難理解必要性并不強(qiáng),目前ST的設(shè)計(jì)其實(shí)沒(méi)有啥不合理的地方。另外,內(nèi)核開(kāi)放的中斷請(qǐng)求號(hào)數(shù)目是也有限的,視不同內(nèi)核而定。
-
STM32
+關(guān)注
關(guān)注
2293文章
11031瀏覽量
364266 -
控制
+關(guān)注
關(guān)注
5文章
1023瀏覽量
123777 -
Systick
+關(guān)注
關(guān)注
0文章
63瀏覽量
13563
發(fā)布評(píng)論請(qǐng)先 登錄
有關(guān)systick問(wèn)題
請(qǐng)問(wèn)有關(guān)SysTick的幾個(gè)函數(shù)在哪個(gè)文件里?
有關(guān)SysTick定時(shí)器基礎(chǔ)知識(shí)
有關(guān)SysTick相關(guān)的介紹
系統(tǒng)節(jié)拍定時(shí)(SysTick)
STM32—關(guān)于SYSTICK系統(tǒng)時(shí)鐘的詳解及學(xué)習(xí)筆記

SysTick 定時(shí)器

STM32_SysTick—系統(tǒng)定時(shí)器

systick定時(shí)器 延時(shí)計(jì)時(shí)

stm32之SysTick的理解(NVIC)

一文詳解STM32的嘀嗒時(shí)鐘(SysTick)

評(píng)論