有人使用STM32G4系列芯片開發產品。他發現程序中如果遇到除以0的操作時,會跑進出錯異常中斷而影響程序運行。他想知道能否通過設置,即使發生除以0操作也不讓程序跑進異常中斷,并期望此時的除法運行結果【也就是商】直接等于當前變量類型所支持的最大值,比如,若被除數為16位變量,則經過該除以零操作后直接為其賦值為0xffff。【實際應用中客戶的需求往往也是五彩斑斕的。^_^】
事實上是否可以如該STM32用戶所愿呢?我們不妨一起看看。
首先,這個問題不屬于STM32外設相關的,而是內核相關的。客戶選用的是Cortex M4的內核STM32芯片,那我們就從M4內核手冊中尋找相關內容。
我們通過查看ARM M4的內核手冊,可以看到除以0操作會導致用法異常[UsageFault],同時它又說了,該操作和非對齊訪問操作是否觸發異常是可以配置的。詳見下方綠色方框內文字。
那么對該用法異常的監測控制是通過哪個寄存器進行配置的呢?經瀏覽手冊得知它是通過配置控制寄存器[SCB-》CCR]進行配置的。
根據上面描述可知,當CCR寄存器的DIV_0_TRP位被配置0時,即使發生除以0操作也不會觸發異常,只有當該位被置1前提下,當發生除以0操作時才觸發異常事件并產生相應中斷。
下面我們具體驗證下。我找了塊M4內核的STM32芯片的開發板。我們先使用ARM MDK來驗證。
測試代碼很簡單,就是下面截圖中的幾行,簡單的閃燈操作,里面夾了一句除法操作。SCB-》CCR被賦值0x00000210即置位了DIV_0_TRP,當被賦值0x00000200時對其進行清零。
經過測試,當我們置位上面CCR寄存器的DIV_0_TRP位,在發生除以0操作時就會進入HardFault中斷,同時被除數的結果【Result】即商變為0.
而當我們對DIV_0_TRP位清零,即SCB-》CCR被賦值0x00000200時發生除以0操作不會觸發Hardfault中斷,但被除數除以0后其結果依然保持為0。整個程序運行起來感覺不到任何阻滯。
上面是基于ARM MDK環境測試的,我們換為IAR IDE測試看看。
我們依然先驗證CCR寄存器的DIV_0_TRP位被置1的情況。經測試,結果跟ARM MDK環境下的測試結果完全一致。
當我們對CCR寄存器的DIV_0_TRP位清零時,測試結果也跟ARM MDK環境下的一致。
顯然,結合Cortex M4內核手冊的描述和實際驗證,當發生除以0操作時是否觸發異常事件是可以配置的,至于發生除以0操作后的商,它始終是0,這個結果其實在上面截圖有明確提及,這里再單獨截圖出來。
不過,這個結果跟開篇客戶所期望的不一致,這是由硬件決定的,不同的硬件在這個地方處理不盡相同。其實,其它Cortex M內核芯片這個地方約定是一樣的。
聊到這里,或許有人發現了一個問題。從手冊上看,這個除以0操作觸發的應該是用法異常【UsageFault】,而我們在實際測試時進入的中斷卻是HardFault異常,這兩個異常并不一樣啊?
這是怎么回事呢?在此拋磚引玉吧,有興趣的話不妨查找相關資料繼續尋找相關答案。
【注:上面部分截圖來自于Cortex-M4的各種手冊,有需要可以到arm網站自行搜索下載】
編輯:jq
-
芯片
+關注
關注
455文章
50816瀏覽量
423672 -
ARM
+關注
關注
134文章
9097瀏覽量
367581 -
寄存器
+關注
關注
31文章
5343瀏覽量
120377 -
MDK
+關注
關注
4文章
209瀏覽量
32069
原文標題:基于STM32的除以0運算話題
文章出處:【微信號:stmcu832,微信公眾號:茶話MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論