问题: 对于基于ARM Cortex M0内核的STM32芯片各类应用开发时,有的时候需要进行总的中断的开、关处理。那就究竟有没有开、关总的中断的函数或者指令呢?
回答: 随着Corte Mn各种内核的MCU的芯片越来越多和相关编译工具的升级换代,编译工具在有关内核指令操作的文档安排以及函数书写等方面可能发生了细微的变化。所以即使用过STM32 F1系列产品的工程师,在使用晚推出的STM32 F0芯片开发时,发现那些跟内核操作有关的指令或函数不知道哪里去找了。以STM32各系列的标准固件库为例,与内核相关的指令及函数都可以在...\libraries\cmsis\...
后面目录的相关文件里找到。于不同系列的标准库中对应的子目录以及相关文件名会略微有差异。
一般来讲我们是不需要做总的中断的关闭操作,或许个别情况真的需要。当然也不排除部分人出于之前使用MCU开发习惯或者好奇怎么用。
对于开、关STM32芯片总的中断,是针对ARM CortexM内核的操作指令。在各类的ARM内核的编程手册上一定可以找到,但是STM32芯片相关手册上是找不到的。开、关总中断的汇编指令分别就是CPSIE i
、CPSID i
,对于各个ARM Cortex系列MCU芯片来说,都是一样的。
CPSID i; // Disable all interrupts except NMI(includes a non-maskable interrupt).set PRIMASK
CPSIE i; // Enable interrupts.clear PRIMASK
CPS(Change Processor State)改变的是PRIMASK
(Interrupt mask register)寄存器值。CPSID
通过PRIMASK
置1中断disable,CPSID
通过PRIMASK
清0操作中断enable。
内在函数 | 操作码 | PRIMASK | FAULTMASK |
---|---|---|---|
__enable_irq | CPSIE i | 0 | |
__disable_irq | CPSIE i | 1 | |
__enable_fiq | CPSIE i | 0 | |
__disable_fiq | CPSIE i | 1 |
目前各编译工具都把与内核相关ARM指令根据指令功能将其中某一条或几条汇编指令封装为C函数,函数名相对更为直观、好记,方便用户需要时拿来使用。比方在ARM MDK环境下,上面两个开关总中断的指令封装成如下2个内嵌函数。
关闭总中断的指令函数:
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
打开总中断的指令函数:
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
需要关闭总中断时,用户代码里直接放置__disable_irq()
需要开启总的中断时,用户代码里直接放置__enable_irq()