我们已经阅读 了 http://www.ti.com/lit/an/spna218/spna218.pdf 以及"4.5.1节"它(幻象中断)是如何发生的?" 有文本
" 在这种情况下、由于 VBUS 写入操作的时序不精确、中断服务例程(ISR)可以在 CPU nIRQ 或 nFIQ 中断请求信号变为非活动状态之前返回。 (笑声) 当一个读取操作清除了外设中断挂起标志时、读取指令将在至少3个 VBUS 周期后返回、并且当中断服务例程退出时、CPU nIRQ 或 nFIQ 中断请求信号已经为低电平。 在这种情况下不会发生幻象中断。"
我的解释是、只要我们想要提出、清除或屏蔽精确的中断、我们就保证、如果我们在写入给定寄存器后从该寄存器读回、就会发生这种情况。 但我不确定内存障碍是否可以实现相同的功能、因为给定的应用手册根本不会讨论它们。 例如、下面是我们在 VIM 中启用中断所使用的简化代码:
// vimREG 为易失 性 void VimEnableInterrupt (uint32_t 通道){ vimREG->REQMASKSET[通道/32]=(uint32_t) 1U <<(通道% 32); (void) vimREG->REQMASKSET[通道/32]; }
请注意最后的回读、以保证对 vimREG 的写入将在该函数执行结束时生效。
这个代码是否会完成同样的操作来保证到函数执行结束时对 vimREG 的写入将生效?
// vimREG 为易失
性 void VimEnableInterrupt (uint32_t 通道){
vimREG->REQMASKSET[通道/ 32]=(uint32_t) 1U <<(通道% 32);
__ASM____volatile__("DSB sy"::::"存储器");
}
我有一个关于提出软件中断的类似问题。 目前、我们有以下用于产生软件中断的代码:
#define portSYS_SSIR1_REG (*(volatile portUInt32Type *) 0xFFFFFFB0UL) #define portSYS_SSIR1_SSKEY (0x7500UL) portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY; __asm volatile ( " DSB \n" "ISB" :::"内存");
它在写入后不会从端口 SYS_SSIR1_REG 读回、但包含 DSB。 假设中断没有被屏蔽、我们是否需要添加一个来自 PORTSYS_SSIR1_REG 的回读来保证在 ISB 被执行后立即产生一个中断、或者在假定的情况下、ISB 和被产生的中断之间是否会有一些延迟? 或者我们是否需要完全执行其他操作?
上面的两个代码示例是指特定的模块、但是保证写入已影响到活动中断的序列是否会根据我们要写入的模块而改变? 例如、在 VIM、DMA 模块和 GIO 模块中启用或禁用或清除中断。