【问题标题】:How to disable/enable interrupts on a stm32f107 chip?如何在 stm32f107 芯片上禁用/启用中断?
【发布时间】:2012-11-22 16:17:14
【问题描述】:

我有一个 ARM stm32f107 芯片。我正在将一个项目从 IAR 移植到 GCC

IAR 提供以下函数来启用和禁用中断:

#define __disable_interrupt() ...
#define __enable_interrupt() ...

如何使用 GCC 为我的芯片启用/禁用中断?

【问题讨论】:

  • 解决这个问题的最简单方法是反汇编 IAR 生成的代码,从那里你会看到真正发生了什么,然后你可以编写可移植代码而不是编译器特定的代码。 (答案在架构参考手册和/或架构和核心的技术参考手册中,可在 infocenter.arm.com 上找到)

标签: c gcc assembly embedded iar


【解决方案1】:

在为 STM32 开发时,RM0008 是您最好的朋友。来自第 199 页的第 10.2.4 节:

要产生中断,应配置中断线并 启用。这是通过对两个触发寄存器进行编程来完成的 所需的边缘检测,并通过启用中断请求 将“1”写入中断屏蔽寄存器中的相应位。

因此您需要在适当的寄存器中设置适当的掩码位。对于外部中断,即 EXTI_IMR 和 EXTI_EMR 寄存器。还有很多其他的。

【讨论】:

    【解决方案2】:

    我无法回答 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
    

    【讨论】:

    • 只是补充一下-以上是全局中断启用/禁用。要启用/禁用单个中断,您需要对 CPU 的中断寄存器进行 RTFM 并旋转正确的位 - 同样,在 CF 中,这意味着在中断屏蔽寄存器中设置一个位以禁用该源。最好在旋转操作周围使用上面的代码,以防止操作期间出现虚假中断。
    【解决方案3】:

    ARM Documentation 表示 _enable_irq(); 编译为“CPSIE I”,意思是清除所有掩码。另一方面,_disable_irq(); 编译为设置掩码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多