有人使用STM32芯片從事產(chǎn)品開發(fā),代碼中有涉及到除以0操作。他們發(fā)現(xiàn)基于相同的代碼,使用不同IDE會出現(xiàn)不同結(jié)果。在IAR或ARM MDK環(huán)境下除以0操作所得結(jié)果為0,而在STM32CubeIDE環(huán)境下的運(yùn)行時(shí)則產(chǎn)生HardFault異常。他們對這個(gè)結(jié)果感覺很奇怪,甚至懷疑是不是CubeIDE環(huán)境有bug。
根據(jù)ARM內(nèi)核相關(guān)手冊描述,關(guān)于除以0事件或非對齊訪問事件是否進(jìn)行捕捉并觸發(fā)異常是可以配置的。如下圖所示:
其中,除以0事件由內(nèi)核的配置控制寄存器CCR的DIV_0_TRP控制。該位清0時(shí),系統(tǒng)不對除以0事件觸發(fā)異常,結(jié)合下面截圖描述得知,此時(shí)硬性返回0值作為結(jié)果。
也就是說,只有控制位配置為1并發(fā)生除以0事件時(shí)才觸發(fā)異常。另外,上圖最后一句明確說明,復(fù)位后該位值為0.
結(jié)合客戶的描述,感覺在ARM MDK和IAR環(huán)境下,該位默認(rèn)值或者說復(fù)位值為0,而STM32CubeIDE環(huán)境下該位復(fù)位默認(rèn)值則為1。這似乎有點(diǎn)說不通。因?yàn)檫@個(gè)默認(rèn)復(fù)位值應(yīng)該是跟著內(nèi)核芯片走,不會跟著開發(fā)環(huán)境走?!居脩舸a一樣】
我隨手找個(gè)STM32開放板,先基于IAR環(huán)境做了個(gè)測試。在測試代碼里制造了除以0事件,的確沒有觸發(fā)異常,而且還返回了結(jié)果0。查看IAR開發(fā)環(huán)境下了SCB->CCR->DIV_0_TRP控制位,如下圖所示,其值為0。結(jié)合內(nèi)核資料描述,這點(diǎn)跟測試結(jié)果吻合。
我嘗試將該控制位改為1后再運(yùn)行除以0代碼,立即觸發(fā)異常。如下圖所示:
當(dāng)我將測試代碼轉(zhuǎn)到CubeIDE去調(diào)試,也馬上觸發(fā)異常,并明確提示發(fā)生除以0事件。
順便在SFR寄存器里查看SCB->CCR->DIV_0_TRP位的值,果真是1,見下圖:
我在用戶代碼里并未對該控制位進(jìn)行改寫,按理其復(fù)位值應(yīng)該是0。難道哪里改寫它了?
我嘗試到STM32CubeIDE的用戶手冊UM2609找找,看看能否找到相關(guān)信息。在里面搜索DIV_0還真找到相關(guān)信息了。
這里的文字表明,調(diào)試狀態(tài)下關(guān)于除以0事件的異常捕獲是默認(rèn)使能的,目的是為了幫助用戶在調(diào)試時(shí)及時(shí)發(fā)現(xiàn)除以0異常。這個(gè)說法沒毛病,問題是在哪里對其使能置位的呢?ARM內(nèi)核復(fù)位后可是清零了的。
繼續(xù)查找相關(guān)信息,看到了該段文字上方有個(gè)截圖,如下圖所示:
從上圖可以看出,關(guān)于除以0操作或非對齊訪問是否觸發(fā)異常,這里可以選擇配置。在STM32CubeIDE調(diào)試狀態(tài)下,除以0操作的異常捕獲默認(rèn)被使能,基于該配置并在工程啟動(dòng)時(shí)借助調(diào)試部件修改了相關(guān)寄存器。
當(dāng)我把這個(gè)地方取消勾選后,使用前面相同代碼做驗(yàn)證調(diào)試,此時(shí)不再觸發(fā)異常并返回0值結(jié)果。到此,也就解釋了發(fā)生除以0操作時(shí),為什么STM32CubeIDE會出現(xiàn)與MDK、IAR不同的調(diào)試結(jié)果。
顯然,STM32CubeIDE默認(rèn)調(diào)試狀態(tài)下使能除以0事件的捕獲,這樣的確便于我們在調(diào)試時(shí)就能及時(shí)發(fā)現(xiàn)除以0事件,若是不該出現(xiàn)的,趕緊查錯(cuò)糾錯(cuò),避免其發(fā)生。如果是允許出現(xiàn)的特別應(yīng)用場景,調(diào)試時(shí)可以通過CubeIDE配置關(guān)閉其異常捕獲。
相比其它IDE,STM32CubeIDE在這個(gè)地方顯得更為方便些。我們只需基于調(diào)試環(huán)境做簡單的勾選即完成修改,每次程序啟動(dòng)時(shí)即生效,在IAR、ARM MDK環(huán)境下往往需要事先添加用戶代碼修改SCB->CCR寄存器內(nèi)容。
講到這里,我要特別提醒下,對于除以0事件或?qū)R事件的捕獲與否,最終取決于用戶代碼。
STM32CubeIDE只是在調(diào)試狀態(tài)下根據(jù)配置修改了相關(guān)控制寄存器位,不等于用戶代碼對其做了修改。
前面提過,除以0事件相關(guān)寄存器控制位復(fù)位后默認(rèn)值為0,即默認(rèn)不觸發(fā)除以0異常。如果說CubeIDE的調(diào)試配置跟其芯片復(fù)位后默認(rèn)值一致倒沒什么,如果CubeIDE里的調(diào)試配置是使能除以0異常的捕獲,而在用戶代碼里卻沒有相應(yīng)實(shí)現(xiàn)代碼,這時(shí)代碼運(yùn)行若有除以0事件,調(diào)試時(shí)自然可以發(fā)現(xiàn),但全速運(yùn)行時(shí)還是不會觸發(fā)異?!敬藭r(shí)代碼運(yùn)行脫離了調(diào)試組件】。所以,要保證全速運(yùn)行時(shí)也能對除以0事件進(jìn)行異常捕獲,我們終究還得在用戶代碼里對SCB->CCR寄存器的DIV_0_TRP位進(jìn)行置位。
STM32CubeIDE這里的調(diào)試配置為我們提供了方便,同時(shí)個(gè)人認(rèn)為其默認(rèn)的調(diào)試配置也是合理的,畢竟并非所有人都知道芯片復(fù)位后默認(rèn)除以0事件不觸發(fā)異常,當(dāng)然,一般來講編譯時(shí)會有警告。
-
芯片
+關(guān)注
關(guān)注
455文章
50818瀏覽量
423715 -
寄存器
+關(guān)注
關(guān)注
31文章
5343瀏覽量
120383 -
STM32
+關(guān)注
關(guān)注
2270文章
10900瀏覽量
356087
原文標(biāo)題:關(guān)于除以0異常捕獲的配置話題
文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論