ARM32开发——(九)中断优先级Priority

1. NVIC中断控制器

NVIC(Nested Vectored Interrupt Controller)是一种嵌套式向量中断控制器,它是用于控制和管理嵌入式设备中的中断的硬件模块。NVIC可以自动地响应中断,并管理中断优先级、中断处理程序等,从而实现多个中断的快速、有序、有效地响应。

NVIC是通过对中断向量表的修改来处理中断的。在NVIC中,中断向量表是一个数组,存储了所有中断处理函数的地址。当一个中断触发时,处理器会在中断向量表中查找对应中断号的处理函数地址,并跳转到该地址执行对应中断的处理。

ARM系统的中断,内置的就是这种控制器。

2. 中断优先级

中断优先级分为抢占优先级,响应优先级和自然优先级

2.1 抢占优先级

抢占优先级用于确定在多个中断请求同时发生时,哪个中断可以中断当前正在执行的中断。具有更高抢占优先级的中断请求可以抢占 正在执行的较低抢占优先级的中断。这个机制允许高优先级的任务在需要时能够立即得到处理。

2.2 响应优先级

响应优先级用于确定中断请求被接收并开始执行的优先级。在多中断环境中,不同中断请求可能同时发生,系统需要根据响应优先级来决定哪个中断会首先得到处理。但响应优先级不会导致中断处理的打断,它仅在中断请求同时发生且抢占优先级相同时决定处理顺序。

2.3 自然优先级

自然优先级实际上是中断向量表的序号,序号越小优先级越高。

优先级的界定: 无论是抢占优先级还是响应优先级,都是用数值表示的,数值越小,优先级越高。

3. 优先级分组

优先级分组主要是说明抢占优先级和响应优先级的关系。

在ARM中,为了表示抢占优先级和响应优先级,仅用了4个Bit表示了优先级的等级。

|-------|------|----------|------|----------|
| 优先级分组 | 抢占优先级 || 响应优先级 ||
| 优先级分组 | 位数 | 范围 | 位数 | 范围 |
| 分组0 | 0bit | NONE | 4bit | [0,15] |
| 分组1 | 1bit | [0,1] | 3bit | [0,7] |
| 分组2 | 2bit | [0,3] | 2bit | [0,3] |
| 分组3 | 3bit | [0,7] | 1bit | [0,1] |
| 分组4 | 4bit | [0,15] | 0bit | NONE |

在代码中我们可以对全局进行中断优先级分组:

objectivec 复制代码
nvic_priority_group_set(NVIC_PRIGROUP_PRE0_SUB4);
nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
nvic_priority_group_set(NVIC_PRIGROUP_PRE3_SUB1);
nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);

对与具体的中断,我们可以进行配置抢占和响应优先级

objectivec 复制代码
nvic_irq_enable(xxx_irqn, 抢占优先级, 响应优先级);

4. 案例准备

  • 创建多个外部中断
  • 配置不同的中断优先级
  • 中断中进行耗时操作(不对的行为,仅仅是用来观察执行结果)
  • 比较中断执行

4.1 外部中断级别逻辑

4.1.1 中断初始化
objectivec 复制代码
static void EXTI0_config() {
    uint32_t extix = EXTI_0; // 哪个中断
    uint32_t extix_irq = EXTI0_IRQn;

    /********************* EXTI config *********************/
    // 时钟配置
    rcu_periph_clock_enable(RCU_SYSCFG);
    // 中断初始化
    exti_init(extix, EXTI_INTERRUPT, EXTI_TRIG_NONE);
    // 配置中断优先级
    nvic_irq_enable(extix_irq, 2, 1);
    // 使能中断
    exti_interrupt_enable(extix);
    // 清除中断标志位
    exti_interrupt_flag_clear(extix);
}
4.1.2 中断函数
objectivec 复制代码
void EXTI0_IRQHandler(void)
{
    if(SET == exti_interrupt_flag_get(EXTI_0)) {
        uint32_t i;
        for(i = 0; i < 10; i++) {
            printf("exti 0 : %d \r\n", i);
            delay_1ms(1000);
        }
    }
    // 清除中断标志位
    exti_interrupt_flag_clear(EXTI_0);
}

4.1.3 中断触发

objectivec 复制代码
exti_software_interrupt_enable(EXTI_0);

4.2 串口接收中断逻辑

objectivec 复制代码
if(data[0] == 0x00) {
    printf("0\r\n");
    exti_software_interrupt_enable(EXTI_0);
} else if(data[0] == 0x01) {
    printf("1\r\n");
    exti_software_interrupt_enable(EXTI_1);
} else if(data[0] == 0x02) {
    printf("2\r\n");
    exti_software_interrupt_enable(EXTI_2);
}

5. 测试一

|-------|---------|-------|-------|
| 中断类型 | 全局优先级分组 | 抢占优先级 | 响应优先级 |
| 串口接收 | 分组2 | 0 | 0 |
| 外部中断0 | 分组2 | 1 | 0 |
| 外部中断1 | 分组2 | 2 | 0 |
| 外部中断2 | 分组2 | 3 | 0 |

5.1 优先级配置

objectivec 复制代码
#define EXTI0_PRIORITY	1, 0
#define EXTI1_PRIORITY	2, 0
#define EXTI2_PRIORITY	3, 0

响应优先级相同,抢占优先级不同,测试不同的结果。

5.2 测试逻辑

通过串口,依次控制先执行 外部中断2,外部中断1,外部中断0,观察打印输出结果。

5.3 结论

  • 抢占优先级数值越小,优先级高
  • 抢占优先级高的中断,可以打断优先级低的,先执行,执行完成后,其他中断接着执行

6. 测试二

|-------|---------|-------|-------|
| 中断类型 | 全局优先级分组 | 抢占优先级 | 响应优先级 |
| 串口接收 | 分组2 | 0 | 0 |
| 外部中断0 | 分组2 | 2 | 0 |
| 外部中断1 | 分组2 | 2 | 1 |
| 外部中断2 | 分组2 | 2 | 2 |

6.1 优先级配置

objectivec 复制代码
#define EXTI0_PRIORITY	2, 0
#define EXTI1_PRIORITY	2, 1
#define EXTI2_PRIORITY	2, 2

应优先级相同,抢占优先级不同,测试不同的结果。

6.2 测试逻辑

通过串口,依次控制先执行 外部中断2,外部中断1,外部中断0,观察打印输出结果。

6.3 结论

  • 响应优先级数值越小,优先级高
  • 响应优先级高的中断,在中断排队时,享有更靠前的优先级

7. 测试三

|-------|---------|-------|-------|
| 中断类型 | 全局优先级分组 | 抢占优先级 | 响应优先级 |
| 串口接收 | 分组2 | 0 | 0 |
| 外部中断0 | 分组2 | 1 | 0 |
| 外部中断1 | 分组2 | 2 | 1 |
| 外部中断2 | 分组2 | 2 | 2 |

7.1 优先级控制

objectivec 复制代码
#define EXTI0_PRIORITY	1, 0
#define EXTI1_PRIORITY	2, 1
#define EXTI2_PRIORITY	2, 2

响应优先级相同,抢占优先级不同,测试不同的结果。

7.2 测试逻辑

通过串口,依次控制先执行 外部中断2,外部中断1,外部中断0,观察打印输出结果。

7.3 结论

  • 中断优先级中,抢占优先级优于响应优先级

8. 测试四

|-------|---------|-------|-------|
| 中断类型 | 全局优先级分组 | 抢占优先级 | 响应优先级 |
| 串口接收 | 分组2 | 0 | 0 |
| 外部中断0 | 分组2 | 2 | 0 |
| 外部中断1 | 分组2 | 2 | 0 |
| 外部中断2 | 分组2 | 2 | 0 |

8.1 优先级配置

objectivec 复制代码
#define EXTI0_PRIORITY	2, 0
#define EXTI1_PRIORITY	2, 0
#define EXTI2_PRIORITY	2, 0

响应优先级相同,抢占优先级不同,测试不同的结果。

8.2 测试逻辑

通过串口,依次控制先执行 外部中断2,外部中断1,外部中断0,观察打印输出结果。

8.3 结论

  • 抢占优先级和响应优先级相同时,比较自然优先级

9. 测试五

全局优先级分组和中断优先级冲突。

相关推荐
模拟IC攻城狮39 分钟前
华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目——共8套(每套四十题)
嵌入式硬件·华为·硬件架构·芯片
IT B业生1 小时前
51单片机教程(六)- LED流水灯
单片机·嵌入式硬件·51单片机
一枝小雨1 小时前
51单片机学习心得2(基于STC89C52):串口通信(UART)
单片机·嵌入式硬件·51单片机
IT B业生2 小时前
51单片机教程(一)- 开发环境搭建
单片机·嵌入式硬件·51单片机
好想有猫猫4 小时前
【51单片机】串口通信原理 + 使用
c语言·单片机·嵌入式硬件·51单片机·1024程序员节
云卓科技4 小时前
无人车之路径规划篇
人工智能·嵌入式硬件·算法·自动驾驶
stm 学习ing6 小时前
C语言 循环高级
c语言·开发语言·单片机·嵌入式硬件·算法·嵌入式实时数据库
w微信150135078126 小时前
小华一级 代理商 HC32F005C6PA-TSSOP20 HC32F005系列
c语言·arm开发·单片机·嵌入式硬件
北京迅为7 小时前
【北京迅为】《STM32MP157开发板嵌入式开发指南》-第七十八章 Qt控制硬件
linux·stm32·单片机·嵌入式硬件
憧憬一下7 小时前
Pinctrl子系统中Pincontroller和client驱动程序的编写
arm开发·嵌入式·c/c++·linux驱动开发