1、DBG、DMB、DSB 和 ISB指令介紹
調試指令、數據内存屏障指令、數據同步屏障指令和指令同步屏障指令。
語法
DBG{cond} {#option}
DMB{cond} {option}
DSB{cond} {option}
ISB{cond} {option}
cond : 是一個可選的條件代碼(請參閱條件執行)。
option : 對提示操作的可選限制。
說明:如果指令未實現,則與 NOP 效果相同
(1)、DBG : 調試提示可向調試系統及其相關系統發送提示。
(2)、DMB :數據内存屏障可作為内存屏障使用。 它可确保會先檢測到程序中位于 DMB 指令前的所有顯式内存訪問指令,然後再檢測到程序中位于 DMB 指令後的顯式内存訪問指令。它不影響其他指令在處理器上的執行順序
option 的允許值為:SY, 完整的系統DMB 操作。 這是缺省情況,可以省略
舉個例子: 如下的操作,确保dmb之前的内存訪問已經完成了,即數據讀到了x1、x2、x3、x21,然後後面的inval_dcache_aera會使用這些參數。
(3)、DSB : 數據同步屏障是一種特殊類型的内存屏障。 隻有當此指令執行完畢後,才會執行程序中位于此指令後的指令。 當滿足以下條件時,此指令才會完成:
位于此指令前的所有顯式内存訪問均完成。
位于此指令前的所有緩存、跳轉預測和 TLB 維護操作全部完成
允許的值為:
SY : 完整的系統 DSB 操作。 這是缺省情況,可以省略。
UN : 隻可完成于統一點的DSB 操作。
ST : 存儲完成後才可執行的DSB 操作。
UNST : 隻有當存儲完成後才可執行的DSB 操作,并且隻會完成于統一點
(4)、ISB : 指令同步屏障可刷新處理器中的管道,因此可确保在 ISB 指令完成後,才從高速緩存或内存中提取位于該指令後的其他所有指令。這可确保提取時間晚于 ISB 指令的指令能夠檢測到 ISB 指令執行前就已經執行的上下文更改操作的執行效果,例如更改ASID 或已完成的 TLB 維護操作,跳轉預測維護操作以及對 CP15 寄存器所做的所有更改。
此外,ISB 指令可确保程序中位于其後的所有跳轉指令總會被寫入跳轉預測邏輯,其寫入上下文可确保 ISB 指令後的指令均可檢測到這些跳轉指令。這是指令流能夠正确執行的前提條件。
舉個例子:如果上述代碼中1和2處的之類,同時從icache中取的,那麼2處位置sp的值感測不到1處對sp的修改。那麼有了isb之類後,保證1處操作完成之後,再進行2處取指令,這樣就不會亂了。
ARMv8指令集提供了3條内存屏障指令。
總結:
在一些ARM程序代碼中,會用到__DSB() 指令,特别是在一些中斷處理函數中。例如:
程序通過中斷信号進入中斷處理函數時,首先應當清除相應的中斷标志位,但有些CPU的時鐘太快,快于中斷使用的時鐘,就會出現清除中斷标志的動作還未完成,CPU就又一次重新進入同一個中斷處理函數,導緻死循環,__DSB() 指令的作用就是避免上述情況的發生。—DSB()的原型是:
等待指令和數據同步,例如*ocramAddr = 0xCCU;執行完成後,實際單片機可能還未完成執行,使用__DSB() __ISB()命令可以确保該行代碼執行完成
static void OCRAM_Access(void)
{
uint32_t *ocramAddr = (uint32_t *)APP_FLEXRAM_OCRAM_START_ADDR;
/* enable FLEXRAM OCRAM access error interrupt*/
FLEXRAM_EnableInterruptSignal(APP_FLEXRAM, kFLEXRAM_OCRAMAccessError);
for (;;)
{
*ocramAddr = 0xCCU;
/* Synchronizes the execution stream with memory accesses */
APP_DSB();
APP_ISB();
/* check ocram access error event */
if (s_flexram_ocram_access_error_match)
{
s_flexram_ocram_access_error_match = false;
PRINTF("\r\nOCRAM access to 0x%x boundary.\r\n", ocramAddr);
break;
}
ocramAddr ;
}
}
程序通過中斷信号進入中斷處理函數時,首先應當清除相應的中斷标志位,但有些CPU的時鐘太快,快于中斷使用的時鐘,就會出現清除中斷标志的動作還未完成,CPU就又一次重新進入同一個中斷處理函數,導緻死循環,__DSB() 指令的作用就是避免上述情況的發生。以下代碼是NXP RT1021 單片機解決上述問題的代碼:
/*! @name ISR exit barrier
* @{
*
* ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
* exception return operation might vector to incorrect interrupt.
* For Cortex-M7, if core speed much faster than peripheral register write speed,
* the peripheral interrupt flags may be still set after exiting ISR, this results to
* the same error similar with errata 83869.
*/
#if (defined __CORTEX_M) && ((__CORTEX_M == 4U) || (__CORTEX_M == 7U))
#define SDK_ISR_EXIT_BARRIER __DSB()
#else
#define SDK_ISR_EXIT_BARRIER
#endif
在一些ARM程序代碼中,會用到__DSB() 指令,特别是在一些中斷處理函數中。例如:
程序通過中斷信号進入中斷處理函數時,首先應當清除相應的中斷标志位,但有些CPU的時鐘太快,快于中斷使用的時鐘,就會出現清除中斷标志的動作還未完成,CPU就又一次重新進入同一個中斷處理函數,導緻死循環,__DSB() 指令的作用就是避免上述情況的發生。—DSB()的原型是:
作為應用程序開發,我們一般不需要詳細了解到這一步。按照官方要求做就好了。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!