STM32F103和AIR32F103的FreeRTOS中断优先级

news2024/11/14 15:36:39

关于 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_PriorityGroupNVIC_
IRQChannelPreemptionPriority
NVIC_
IRQChannelSubPriority
Description
NVIC_PriorityGroup_000-150 bits for pre-emption priority
4 bits for subpriority
NVIC_PriorityGroup_10-10-71 bits for pre-emption priority
3 bits for subpriority
NVIC_PriorityGroup_20-30-32 bits for pre-emption priority
2 bits for subpriority
NVIC_PriorityGroup_30-70-13 bits for pre-emption priority
1 bits for subpriority
NVIC_PriorityGroup_40-1504 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 http://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的中断说明 http://www.openrtos.net/RTOS-Cortex-M3-M4.html
  • Cutting Through the Confusion with Arm Cortex-M Interrupt Priorities
  • A Beginner’s Guide on Interrupt Latency - and Interrupt Latency of the Arm Cortex-M processors

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端初学者的Ant Design Pro V6总结(上)

前端初学者的Ant Design Pro V6总结(上) 一、UI组件开发流程 () > {} 通用(异步)函数useEmotionCss 定义CSSuseModel获取全局状态useCallback 处理React合成事件JSX 拆分组件initiateState 中CurrentUser空值处理initiateSta…

8. 数字类型讲解

python3 数字类型的使用 1. 基础知识 Python 数字数据类型用于存储数值。 数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间。 可以使用del语句删除一些数字对象的引用。 del var1[,var2[,var3[....,varN]]]Python 支持三种不同的…

计算机视觉算法——基于深度学习的高精地图算法(HDMapNet / VectorMapNet / MapTR / VectorNet)

计算机视觉算法——基于深度学习的高精地图算法(HDMapNet / VectorMapNet / MapTR / VectorNet)计算机视觉算法——基于深度学习的高精地图算法(HDMapNet / VectorMapNet / MapTR / VectorNet)1. HDMapNet1.1 网络结构及特点1.1.1…

SAP SD 自定义销售订单审批状态

自定义销售订单审批状态 销售订单可以在其抬头或者项目中定义审批状态,一般在抬头定义的话就相当于针对整单的审批,可以实现多级审批,每级审批设置能进行何种操作,这里就需要在IMG中定义审批状态参数文件。 一、定义状态参数文件…

[精] MySQL和Oracle下Mybatis批量操作示例和获取影响行数介绍

手打不易,如果转摘,请注明出处! 注明原文:https://zhangxiaofan.blog.csdn.net/article/details/117933877 目录 前言 Mybatis 执行器 表结构定义 Mybatis批量新增 批量新增——Mysql写法 批量新增——Oracle写法 Mybatis批…

【甄选靶场】Vulnhub百个项目渗透——项目五十四:jarbas-1(类git反弹shell,计划任务提权)

Vulnhub百个项目渗透 Vulnhub百个项目渗透——项目五十四:jarbas-1(类git反弹shell,计划任务提权) 🔥系列专栏:Vulnhub百个项目渗透 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 …

SpringMvc源码分析(四) 请求执行过程之执行MethodHandler

在上文SpringMvc源码分析(三)中我们分析了DispatcherServlet类中的doDispatcher方法, 并通过分析方法1和方法2了解了请求执行时是怎么获取MethodHandler链的,本文接上文继续分析方法3、方法4和方法5了解MethodHandler是如何执行的…

springboot rabbitmq 非阻塞重试机制实现

重试的应用场景 比如,系统之间同步数据,A系统发送数据给B系统,因为网络原因或者B系统正在重启,可能收不到信息,为了确保B能收到消息就得重试几次;经典的比如,微信支付回调 对后台通知交互时&am…

VScode远程连接Linux

文章目录一、下载安装二、使用三、连接四、基本操作五、VScode内置命令行六、推荐插件一、下载安装 下载的问题就不用多说了把,可能存在的问题就是下载的速度比较慢 前往官网进行下载:前往官网找到适合自己的版本: 但是由于官网是国外的&am…

DT-6_TTL-WiFi透传模块介绍

DT-6_TTL-WiFi透传模块简介TTL-WiFi模块基于ESP-M2WiFi 模块研发,引出串口TTL、EN、STATE等引脚。产品内置我司最新版本的串口透传固件可完成设备TTL 端口到WiFi/云的数据实时透传,具备低功耗控制,状态指示等功能。本模块可直接取代原有的有线…

【手写 Vue2.x 源码】第三十二篇 - diff算法-乱序比对

一,前言 上篇,diff算法-比对优化(下),主要涉及以下几个点: 介绍了儿子节点比较的流程介绍并实现了头头、尾尾、头尾、尾头4种特殊情况比对 本篇,继续介绍 diff算法-乱序比对 二,乱…

MATLAB | 全网最全边际图绘制模板(直方图、小提琴图、箱线图、雨云图、散点图... ...)

如标题所言,这应该是全网最全的边际图绘制模板,中心图有8种格式,边际图有11种格式,共计88种组合,另外模板中给了8款配色,我愿称其为888组合,只需要更换一下数据就能绘制出各种类型的边际图: 甚至…

中国机器视觉市场研究报告

目录 机器视觉行业概述机器视觉行业发展现状机器视觉行业典型企业分析机器视觉行业未来发展趋势 机器视觉行业概述 机器视觉定义 机器视觉(Machine Vision,MV)是人工智能正在快速发展的一个分支。根据美国制造工程师协会(SME&…

数字孪生虚拟电厂负荷控制系统可视化

随着国家“双碳”及“构建以新能源为主体的新型电力系统”等目标的提出,清洁化、数字化越来越成为电力系统面临的迫切需求,负控系统的发展对电力营销现代化建设具有重要的意义。负控管理系统是一个着眼于全面加强电力信息管理的,集负荷控制、…

Tips for Confluence Administrators: Part 2

Part 1中,我们谈到了 Confluence 自定义配置的案例,例如:如何禁用附件下载?如何将iFrame放入Confluence?如何使我的页面完全私有?如何防止空间管理员删除他们的空间?任何软件都有bug&#xff0c…

Minecraft 1.19.2 Forge模组开发 11.Mixin

我们本次使用Mixin在1.19.2中制作一个属于自己的不死图腾。 演示效果演示效果演示效果 什么是Mixin? 简单来说是通过注入一些我们的代码,达到对MC原版内容的修改。 详细内容可以参考Minecraft 17.1 Mixin 1.首先我们需要在开发包中引入mixin的依赖&a…

深度学习——双向循环神经网络(笔记)

双向循环神经网络: ①对于序列来讲,假设的目标是:给定观测的情况下(在时间序列的上下文或语言模型的上下文),对于下一个输出进行建模 ②对于序列模型来讲,可以从前往后看,也可以从…

Servlet基础

Servlet1. Servlet概述2. 快速入门3. 执行原理4. 生命周期方法5. Servlet3.06. 体系结构7. 相关配置8. HTTP8.1 概念8.2 Request8.3 Response8.4 ServletContext综合案例:文件下载:1. Servlet概述 Servlet是JavaEE规范(接口)之一Servlet是JavaWeb三大组件之一&…

使用sdk-npi-enablement-tool生成SVD文件和芯片头文件

使用sdk-npi-enablement-tool生成SVD文件和芯片头文件 文章目录使用sdk-npi-enablement-tool生成SVD文件和芯片头文件IntroductionOverviewOperation Steps创建芯片配置文件yaml填充外设模块的寄存器映射描述文件xlsx验证生成芯片头文件ConclusionIntroduction 芯片验证与测试…

【Linux杂篇】Linux系统终端常用配置文件更改

目录列表: 1.alias别名永久保存 2.解决vim文件没有颜色的问题 3.vim插件supertap插件安装(可支持自动补全,非函数代码补全,仅支持在当前编辑文档内补全) 4.vim插件管理 5.YCM下载 6.解决vim中使用backspace无法删…