__DSB() __ISB()命令
等待指令和数据同步,例如*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
相关链接
https://blog.csdn.net/missiler/article/details/107796862
https://blog.csdn.net/weixin_34384915/article/details/91637912