Cortex-m0 临界代码段保护
1. stm32中断
1.1 中断特殊功能寄存器PRIMASK
PRIMASK
寄存器用于控制中断的使能和禁止,它只有一个位,即PRIMASK位。当PRIMASK位被设置为1时,所有中断都被禁止,包括NMI
和HardFault
中断。当PRIMASK位被设置为0时,所有中断都被使能。
操作PRIMASK
寄存器的方法是使用MSR
指令,将1写入PRIMASK位即可禁止中断,将0写入PRIMASK位即可使能中断。要操作中断开关或PRIMASK
可以使用以下指令:
//汇编关闭中断
MSR PRIMASK, #1
或使用
CPSID I
//汇编开启中断
MSR PRIMASK, #0
或使用
CPSIE I
1.2 通过开关中断使能寄存器实现临界代码保护
void critical_section(void)
{
// 关闭中断
__disable_irq(); //关闭中断 PRIMASK = 1
{
// 临界代码段
// ...
}
// 开启中断
__enable_irq(); //开启中断 PRIMASK = 0
}
这里示例简单的实现了临界代码段的保护,但实际程序在设计是会使用到嵌套中断的情况
1.3 使用中断状态变量保存中断变化(嵌套中断)
void critical_section(void)
{
// 保存当前中断状态
uint32_t primask1,primask2;
primask1 = __get_PRIMASK(); //获取PRIMASK寄存器值
__disable_irq(); //关闭中断 PRIMASK = 1
{
// 临界代码段1
primask2 = __get_PRIMASK();
{
// 临界代码段2
}
//恢复中断(primask2接收的变量值为1)
__set_PRIMASK(primask2);
}
// 恢复中断状态
__set_PRIMASK(primask1); //恢复PRIMASK寄存器值
}
通过接收PRIMASK寄存器值来保存各个临界段的状态,确保每个代码段都会被执行
2 通过定时器来查看关闭中断的实际实现效果
可以通过这篇博文做为参考:STM32定时器中断
3.1 RT_thread临界段保护(基于cortex-m0)
在rt_thread中也是操作PRIMASK寄存器来实现
;/*
; * rt_base_t rt_hw_interrupt_disable();
; */
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0, PRIMASK //读取PRIMASK寄存器值到r0中
CPSID I //关闭中断响应
BX LR //程序跳转至LR寄存器 (PC)
ENDP
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC
EXPORT rt_hw_interrupt_enable
MSR PRIMASK, r0 //将r0中的值(level)写入PRIMASK寄存器
BX LR //程序跳转至LR寄存器
ENDP
RT_thread代码示例
PRIMASK = 0; /* PRIMASK 初始值为 0,表示没有关中断 */
rt_base_t level1;
rt_base_t level2;
/* 临界段代码 */
{
/* 临界段 1 开始 */
level1 = rt_hw_interrupt_disable(); /* 关中断,level1=0,PRIMASK=1 */
{
/* 临界段 2 */
level2 = rt_hw_interrupt_disable(); /* 关中断,level2=1,PRIMASK=1 */
{
}
rt_hw_interrupt_enable(level2); /* 开中断,level2=1,PRIMASK=1 */
}
/* 临界段 1 结束 */
rt_hw_interrupt_enable(level1); /* 开中断,level1=0,PRIMASK=0 */
}
标签:rt,中断,代码段,临界,Cortex,寄存器,interrupt,PRIMASK,m0
From: https://www.cnblogs.com/shangshang-blocks/p/18299843