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_InitStruct)
设置对应的抢占优先级和响应优先级
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStruct);
FreeRTOS优先级设置
对于 STM32F103, FreeRTOSConfig.h 中需要配置 configKERNEL_INTERRUPT_PRIORITY 和 configMAX_SYSCALL_INTERRUPT_PRIORITY, 另外在 FreeRTOS 调度启动前调用函数NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 )
将全部优先级设为抢占优先级.
configKERNEL_INTERRUPT_PRIORITY
- 设置 FreeRTOS 内核本身使用的中断优先级, 因为FreeRTOS内核中断不应当抢占用户使用的中断, 因此一般定义为硬件最低优先级
- 对于STM32F103, 优先级总共4-bit, 在字节的最高位, bit[7:4], 全一表示的最低优先级, 所以在 FreeRTOSConfig.h 中将其设置为 0B1111xxxx 的任一个值就行 [240, 255]
- 对于AIR32F103, 优先级总共3-bit, 字节最高位 bit[7:5], 所以设置为 0B111xxxxx 的任一个值就行 [160, 255]
configMAX_SYSCALL_INTERRUPT_PRIORITY
设置可以在中断服务程序中, 调用中断安全的FreeRTOS API函数的最高中断优先级.
FreeRTOS 中断嵌套方案将可用的中断优先级分成2组: 被 FreeRTOS 临界区覆盖的, 和不会被覆盖的(这些中断是无法被屏蔽的), 优先级高于配置值的中断, 不受FreeRTOS管控, 在 FreeRTOS 中无法通过进入临界区屏蔽这些中断, 因此也不能在这些中断中调用 FreeRTOS API, 否则系统会有崩溃的风险
例如将这个优先级设置为5, 那么如果有一个中断优先级等于4, 在这个中断中调用了FreeRTOS API, 则系统会有崩溃的风险, 如果使能了configASSERT宏, 会触发断言失败.
在STM32中要保证所有的优先级设置为可抢占优先级, 具体实现方式是在 FreeRTOS 启动前, 调用函数NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4)
STM32使用了中断优先级寄存器中的4位, bit[7:4], 如果设置优先级为5, 对应的二进制值为0x101
,
- 对应STM32使用的 bit[7:4] 就是
0x0101
, 剩余的 bit[3:0] 可以设置成任何值, 但为了兼容,最好将他们设置成1. 因此就是0x0101 1111 = 0x5F = 95
- 对应AIR32/MH32使用的是 bit[7:5] 就是
0x101
, 剩余的 bit[4:0] 可以设置成任何值, 设成全1就是0x1011 1111 = 0xBF = 191
/* AIR32F103 only use 3 bits(bit[7:5]) for priority */
/* This is the raw value as per the Cortex-M3 NVIC. Values can be 255
(lowest) to 0 (1?) (highest). */
/* equivalent to 0xFF (0x111x xxxx, x=1), or priority 7. */
#define configKERNEL_INTERRUPT_PRIORITY 255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See //www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
/* equivalent to 0xBF (0x101x xxxx, x=1), or priority 5. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 191
链接
- FreeRTOS的中断说明
STM32F103和AIR32F103的FreeRTOS中断优先级的更多相关文章
- FreeRTOS中断优先级配置(重要)
FreeRTOS中断优先级配置(重要) 本章节为大家讲解FreeRTOS中断优先级配置,此章节非常重要,初学者经常在这里犯迷糊.对于初学者来说,本章节务必要整明白.12.1 NVIC基础知识12.2 ...
- FreeRTOS 中断优先级配置(重要)
以下转载自安富莱电子: //forum.armfly.com/forum.php NVIC 的全称是 Nested vectored interrupt controller,即嵌套向量中断 ...
- FreeRTOS 中断优先级嵌套错误引发HardFault异常解决(转)
最近在使用FreeRTOS的时候,突然发现程序在运行了几分钟之后所有的任务都不再调用了,只有几个中断能正常使用,看来是系统挂掉了,连续测试了几次想找出问题,可是这个真的有点不知所措. 我 ...
- FreeRTOS 中断优先级嵌套错误引发HardFault异常解决
最近在使用FreeRTOS的时候,突然发现程序在运行了几分钟之后所有的任务都不再调用了,只有几个中断能正常使用,看来是系统挂掉了,连续测试了几次想找出问题,可是这个真的有点不知所措. ...
- AIR32F103(五) FreeRTOSv202112核心库的集成和示例代码
目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...
- 使用 FreeRTOS 时注意事项总结(基础篇教程完结)
以下转载自安富莱电子: //forum.armfly.com/forum.php FreeRTOS 的初始化流程推荐的初始化流程如下,本教程配套的所有例子都是采用的这种形式,当然,不限制必须 ...
- FreeRTOS基础篇教程目录汇总
以下教程(大部分章节)(尤其理论介绍部分)转载自安富莱电子,官网链接: //forum.armfly.com/forum.php 然后根据安富莱的教程自己做了分析和测试,希望大家共同进步. ...
- STM32F10x SPL V3.6.2 集成 FreeRTOS v202112
STM32F10x SPL 集成 FreeRTOS 在整理 GCC Arm 工具链的Bluepill代码示例, 常用外设都差不多了, 接下来是 FreeRTOS, 网上查到的基本上都是基于旧版本的集成 ...
- STM32用FreeRTOS时任务优先级和中断优先级说明
下面对 FreeRTOS 优先级相关的几个重要知识点进行下说明,这些知识点在以后的使用中务必要掌握牢固. FreeRTOS 中任务的最高优先级是通过 FreeRTOSConfig.h 文件中的 co ...
- [FreeRTOS].FreeRTOS CortexM3 M4中断优先级设置总结
转自://blog.csdn.net/xukai871105/article/details/53516857 前言本文将说明在FreeRTOS嵌入式操作系统中,如何设置STM32 Cor ...
随机推荐
- .Net Core中获取appsettings.json中的节点数据
获取ConnectionStrings节点数据 //appsettings.json { "ConnectionStrings": { //DEV "DbConn&quo ...
- Nginx配置-1
1.绑定nginx到指定cpu [root@nginx conf.d]# vim /apps/nginx/conf/nginx.conf worker_processes 2; worker_cpu_ ...
- jmeter——JSON提取器(从上一个请求的响应结果提取参数传给下一个请求)
记录一个参数提取过程,可供后续参考. 1. 查看响应报文的结构 将上一个请求的响应报文复制到Notepad++编辑器 JSON Viewer是Notepad++的JSON插件, Notepad++的P ...
- python-名称空间与作用域
名称空间与作用域 (1)名称空间(namespaces) 用来存放名字的地方是对栈区的划分 有了名称空间,就可在栈区中放相同的名字 1.1.内置名称空间 存放的名字:是Python解释器内置的名字 & ...
- day31 1 tomcat介绍与创建web项目 & 2 继承HttpServlet类、配置webxml全局配置文件 & 3 servlet生命周期 & 4 请求对象HttpServletRequest与响应对象HttpServletResponse
Servlet Java Servlet是运行在Web服务器或应用服务器上的程序,作为客户端(Web浏览器或其他HTTP客户端)和服务端(HTTP服务器上的数据库或应用程序)之间的中间层. 使用Ser ...
- 数电第六周周结_by_yc
时序逻辑电路的设计要点: ①只有时钟信号和复位信号可以放在敏感列表里: ②使用非阻塞赋值,即使用"<="; ③无需对所有分支进行描述,对于未描述的分支,变量将保持 ...
- 漫谈计算机网络:应用层 ----- 从DNS域名解析到WWW万维网再到P2P应用
2022-12-04 18:31:01 纪念一下博主的<漫谈计算机网络>连载博客 浏览量破500了! 今天更新完结篇! 面试答不上?计网很枯燥? 听说你学习 计网 每次记了都会忘? 不妨抽 ...
- 【每日一题】【DFS+存已加的值】2022年2月27日-二叉树根节点到叶子节点的所有路径和
描述给定一个二叉树的根节点root,该树的节点值都在数字0−9 之间,每一条从根节点到叶子节点的路径都可以用一个数字表示.1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点2.叶子节点是 ...
- 【每日一题】【map存值】2022年2月25日-NC112 进制转换
描述给定一个十进制数 M ,以及需要转换的进制数 N .将十进制数 M 转化为 N 进制数. 当 N 大于 10 以后, 应在结果中使用大写字母表示大于 10 的一位,如 'A' 表示此位为 10 , ...
- 【每日一题】【list转int数组】【Lambda的简化-方法引用】2022年1月15日-NC45 实现二叉树先序,中序和后序遍历
描述 给定一棵二叉树,分别按照二叉树先序,中序和后序打印所有的节点. 数据范围:0 \le n \le 10000≤n≤1000,树上每个节点的val值满足 0 \le val \le 1000≤ ...