设为首页 加入收藏

TOP

STM32F103和AIR32F103的FreeRTOS中断优先级(一)
2023-07-23 13:30:18 】 浏览:83
Tags:STM32F103 AIR32F103 FreeRTOS

关于 Arm Cortex M 系列内核的中断优先级

Cortex M 的中断和优先级

首先要区分开 中断中断优先级 这是两个不同的东西, 不要搞混了

  • 对于 Cortex-M0 和 Cortex-M0+ 内核, 除了系统内建中断外, 支持最多 32 个中断
  • 对于 Cortex-M3 内核, 除了 16 个内核中断外, 支持最多 240 个中断
  • 有8-bit的优先级, M0是固定的 2-bit, 即4个优先级, M3/M4 至少需要实现3-bit, 即大于等于8个优先级

厂商的实现

  • STM32 F1 只使用了其中的 84个中断, 包括 16个内核中断和 68 个可屏蔽中断
  • STM32 F1 实现了 4-bit 的优先级, 具有16级可编程的中断优先级.
  • STM32F103系列, 只使用了60个可屏蔽中断

优先级的数值和优先级的关系

The most important fact to know is that Cortex-M uses the “reversed” priority numbering scheme for interrupts, where priority zero corresponds to the highest urgency interrupt and higher numerical values of priority correspond to lower urgency. This numbering scheme poses a constant threat of confusion

注意,Cortex-M 对中断优先级编号的方案, 数值是倒序的, 优先级0对应最高优先级, 数值越大对应的优先级越低.

NVIC(Nested Vectored Interrupt Controller) 中的中断优先级配置

The number of priority levels in the Arm Cortex-M core is configurable, meaning that various silicon vendors can implement different number of priority bits in their chips. However, there is a minimum number of interrupt priority bits that need to be implemented, which is 2 bits in Arm Cortex-M0/M0+ and 3 bits in Arm Cortex-M3/M4.

Cortex-M 内核的中断优先级数量不全是固定的, Cortex-M0/M0+ 是固定的2-bit, Cortex-M3/M4 至少需要3-bit, 各个厂商可以在芯片产品里根据需要实现不同的优先级位数.

上图是 NVIC 优先级寄存器中的位表示方法. 优先级的有效数值是左对齐的, 如果直接往寄存器写值, 需要对应地左移.

CMSIS 中的中断优先级

CMSIS(Cortex Microcontroller Software Interface Standard) 是面向 Cortex M 的通用底层实现, 在标准的 CMSIS 实现中提供了函数 NVIC_SetPriority(IRQn, priority) 用于设置中断优先级. 这个函数中的 priority 不需要左移, 在函数里已经根据 __NVIC_PRIO_BITS 自动处理了. 例如 调用 NVIC_SetPriority(7, 6) 对于 3-bit 优先级的 Cortex-M, 会将 IRQ#7 的优先级设为 1100,0000, 对于4-bit 优先级的 Cortex-M, 会将 IRQ#7 的优先级设为 0110,0000.

抢占优先级 Preempt Priority 和 子优先级 Supbpriority

优先级被分成两类

  • Preemption Priorities, 抢占优先级
  • Sub Priorities, 子优先级

这两种优先级的区别

  • 更高的抢占优先级中断 可以打断 正在进行的低抢占优先级中断
  • 抢占优先级相同的中断, 高子优先级 不可以打断 低子优先级的中断
  • 抢占优先级相同的中断, 中断同时发生时, 子优先级高的先执行
  • 抢占优先级和子优先级都一样时, 哪个中断先发生哪个就先执行

在大多数应用中, 建议将所有优先级bits分配给preempt priority group, 不使用 Supbpriority. 避免使中断优先级之间的关系复杂化. 一些第三方代码库(例如STM32的驱动库)会将优先级组配置为非标准, 建议在初始化此类驱动库后, 通过调用CMSIS函数 NVIC_SetPriorityGrouping(0U) 显式地将优先级分组重新设置为默认值.

使用库函数void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)设置优先级组, 参数是以下宏定义

#define NVIC_PriorityGroup_0         ((uint32_t)0x700)
#define NVIC_PriorityGroup_1         ((uint32_t)0x600)
#define NVIC_PriorityGroup_2         ((uint32_t)0x500)
#define NVIC_PriorityGroup_3         ((uint32_t)0x400)
#define NVIC_PriorityGroup_4         ((uint32_t)0x300)

下面的表格是宏定义对应的抢占优先级和子优先级的拆分关系, 以及拆分后的优先级取值范围

NVIC_PriorityGroup NVIC_
IRQChannelPreemptionPriority
NVIC_
IRQChannelSubPriority
Description
NVIC_PriorityGroup_0 0 0-15 0 bits for pre-emption priority
4 bits for subpriority
NVIC_PriorityGroup_1 0-1 0-7 1 bits for pre-emption priority
3 bits for subpriority
NVIC_PriorityGroup_2 0-3 0-3 2 bits for pre-emption priority
2 bits for subpriority
NVIC_PriorityGroup_3 0-7 0-1 3 bits for pre-emption priority
1 bits for subpriority
NVIC_PriorityGroup_4 0-15 0 4 bits for pre-emption priority
0 bits for subpriority

中断优先级由抢占优先级和子优先级共同组成, NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority表示抢占优先级, NVIC_InitStruct->NVIC_IRQChannelSubPriority表示子优先级

系统运行后先调用函数void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)设置中断优先级分组

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

整个系统执行过程中,只设置一次中断分组.

针对每个中断,void NVIC_Init(NVIC_InitTypeDef* NVIC_

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Ubuntu下的LGT8F328P MiniEVB Ard.. 下一篇微机原理与系统设计笔记2 | 8086C..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目