我有一个 ARM stm32f107 芯片。我正在将一个项目从 IAR 移植到 GCC
IAR 提供以下函数来启用和禁用中断:
#define __disable_interrupt() ...
#define __enable_interrupt() ...
如何使用 GCC 为我的芯片启用/禁用中断?
在为 STM32 开发时,RM0008是您最好的朋友。从第 199 页的第 10.2.4 节:
要产生中断,应配置并启用中断线。这是通过使用所需的边沿检测对两个触发寄存器进行编程并通过将“1”写入中断屏蔽寄存器中的相应位来启用中断请求来完成的。
所以你需要在适当的寄存器中设置适当的屏蔽位。对于外部中断,即 EXTI_IMR 和 EXTI_EMR 寄存器。还有很多其他的。
我无法回答 ARM,但 Coldfire 中的相同功能归结为设置/清除 CPU 中的中断优先级屏蔽寄存器。将其设置为最高数字会禁用/忽略除不可屏蔽之外的所有内容,将其设置为 0 会启用所有 (YMMV)。
值得注意的是,在“禁用”时回读值并在“启用”时恢复以确保堆栈中断不会相互中断,这很方便:
ipl = DisableInts(); // Remember what the IPL was
<"Risky" code happens here>
EnableInts(ipl); // Restore value
这在玩弄中断掩码时很有用,这可能会导致虚假中断,或者做不应该被中断的事情。
功能如下:
uint8 DisableInts(void)
{
return(asm_set_ipl(7));
}
uint8 EnableInts(uint8 ipl)
{
return(asm_set_ipl(ipl));
}
两者都映射到这个 asm:
asm_set_ipl:
_asm_set_ipl:
/* Modified for CW7.2! */
link A6,#-8
movem.l D6-D7,(SP)
move.l D0,D6 /* save argument */
move.w SR,D7 /* current sr */
move.l D7,D0 /* prepare return value */
andi.l #0x0700,D0 /* mask out IPL */
lsr.l #8,D0 /* IPL */
andi.l #0x07,D6 /* least significant three bits */
lsl.l #8,D6 /* move over to make mask */
andi.l #0x0000F8FF,D7 /* zero out current IPL */
or.l D6,D7 /* place new IPL in sr */
move.w D7,SR
movem.l (SP),D6-D7
//lea 8(SP),SP
unlk A6
rts
ARM 文档说编译为“ _enable_irq();
CPSIE I”,意思是清除所有掩码。另一方面_disable_irq();
编译为设置掩码。