FreeRTOS_中断

2023-11-09

笔记内容参考(正点原子的FreeRTOS开发手册、cortex-m3权威指南、Cortex-M3和Cortex-M4权威指南等)

文中stm32指的是F1及F4



1、中断配置宏

STM32使用FreeRTOS,须将优先级分组设为组4(4位全部是抢占优先级),所以就有(0-15)16个优先级。且优先级数字越小,优先级越高。

1.1 configPRIO_BITS

设置MCU使用几位作为优先级配置,定义优先级的寄存器有8位,但STM32只使用了高4位做为优先级配置,所以此宏定义为4

1.2 configLIBRARY_LOWEST_INTERRUPT_PRIORITY

设置最低优先级15

1.3 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY

定义了受FreeRTOS管理的最高优先级中断。简单的说就是允许用户在这个中断服务程序里面调用FreeRTOS的API的最高优先级。设置NVIC的优先级分组为4的情况下。配置configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY为5,表示用户可以在抢占式优先级为5-15的中断里面调用FreeRTOS的API函数,抢占式优先级为0-4的中断里面是不允许调用的。不受FreeRTOS管理的中断有什么深层的含义吗?

讲解不受FreeRTOS管理的中断之前要说一个小知识点----中断延迟。中断延迟时间是衡量RTOS实时操作系统的一项重要指标,那什么又是中断延迟呢?从中断触发到执行中断服务程序的第一条指令这段时间就是中断延迟时间。

FreeRTOS内核源码中有多处开关全局中断的地方,这些开关全局中断会加大中断延迟时间。比如在源码的某个地方关闭了全局中断,但是此时有外部中断触发,这个中断的服务程序就需要等到再次开启全局中断后才可以得到执行。开关中断之间的时间越长,中断延迟时间就越大,这样极其影响系统的实时性。如果这是一个紧急的中断事件,得不到及时执行的话,后果是可想而知的。

针对这种情况,FreeRTOS就专门做了一种新的开关中断实现机制。关闭中断时仅关闭受FreeRTOS管理的中断,不受FreeRTOS管理的中断不关闭,这些不受管理的中断都是高优先级的中断,用户可以在这些中断里面加入需要实时响应的程序。FreeRTOS能够实现这种功能的奥秘就在于FreeRTOS开关中断使用的是寄存器BASEPRI,这个在下面的链接记录(2.3.1 PRIMASK, FAULTMASK 和 BASEPRI)

2、配置Pendsv和Systick优先级

设置Pendsv和Systick优先级为最低优先级(优先级0-15,数字越大优先级越高,所以在此设置优先级为15),为什么要设置最低,因为任务切换就是在PendSV中运行,为了让其他中断能够及时的运行,为什么要在PendSV中切换任务。

这个涉及到了任务切换,在其他博客记录。

在任务调度器开始函数vTaskStartScheduler() 里面有接口xPortStartScheduler(),用来初始化与调度器相关的硬件(比如滴答定时器、FPU单元[浮点运算]、PendSV中断)

//代码缩减后
void vTaskStartScheduler( void )
{
		if( xPortStartScheduler() != pdFALSE )
}

/*
 * See header file for description.
 */
BaseType_t xPortStartScheduler( void )
{
	/* Make PendSV and SysTick the lowest priority interrupts. */
	portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
	portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
}
/*-----------------------------------------------------------*/

设置PENDSV_PRI和SYSTICK_PRI优先级是向portNVIC_SYSPRI2_REG写数据

#define portNVIC_SYSPRI2_REG				( * ( ( volatile uint32_t * ) 0xe000ed20 ) )

在这里插入图片描述

4 个相临的优先级寄存器(8位)拼成一个 32 位寄存器。所以上面就是直接对0xE000_ED20进行写设置PendSV和Systick优先级

#define portNVIC_PENDSV_PRI					( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )
#define portNVIC_SYSTICK_PRI				( ( ( uint32_t ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )

这里的configKERNEL_INTERRUPT_PRIORITY分别左移16和24,因为这是由4个相邻的寄存器拼接成一个32位寄存器,所以左移16位设置PendSV,左移24设置Systick。

/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

configKERNEL_INTERRUPT_PRIORITY是实际写入寄存器的数,因为不可能将configLIBRARY_LOWEST_INTERRUPT_PRIORITY(15)直接写入寄存器,所以需要转换,因为STM32使用了高四位作为优先级,所以需要将15左移4位才是真正的优先级。(8 - configPRIO_BITS) 就是4。

2.1 硬件调试查看Pendsv和Systick优先级

在进入调试后全速运行,选择外设-> 内核外设 -> NVIC
在这里插入图片描述
这里pendsv和systick的优先级都是15,即最低优先级,240是15左移4位构成的,因为定义优先级的寄存器是8位,而STM32使用高四位作为优先级配置,所以15左移4位
在这里插入图片描述

3、用于中断屏蔽的特殊寄存器

PRIMASK, FAULTMASK 和 BASEPRI这三个寄存器,可以参考上面链接【Cortex-M3笔记_基础】,大致了解这三个中断屏蔽寄存器。BASEPRI寄存器可以只屏蔽低于某一阈值的优先级中断FreeRTOS的开关中断就是通过BASEPRI这个寄存器实现。

想屏蔽某一阈值之下的优先级,直接将优先级写进寄存器即可,写入0就停止屏蔽中断

4、FreeRTOS开关中断

开中断vPortRaiseBASEPRI,关中断vPortSetBASEPRI,关中断写0

static portFORCE_INLINE void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;

	__asm
	{
		/* Set BASEPRI to the max syscall priority to effect a critical
		section. */
		msr basepri, ulNewBASEPRI
		dsb
		isb
	}
}

static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI )
{
	__asm
	{
		/* Barrier instructions are not used as this function is only used to
		lower the BASEPRI value. */
		msr basepri, ulBASEPRI
	}
}

这里的configMAX_SYSCALL_INTERRUPT_PRIORITY定义如下

/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

相关宏定义在上面。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FreeRTOS_中断 的相关文章

  • 生成项目目录结构(based on windows system)

    描述 作为程序员 在工作中 我们经常会有需求 需要罗列出项目的结构图 如果手工来整理的话 太过浪费时间 其实我们可以借助tree命令来快速生成目录结构 本文主要介绍一下 基于windows系统 如何快速生成目录结构的方法 步骤 1 开始 g

随机推荐

  • vue项目中点击非刷新按钮,页面刷新并且路由多了个问号解决方案

    问题描述 在vue项目开发过程中 点击查询或重置按钮 结果页面刷新了一遍 发现路径变成了 localhost 8080 advanced 原因 这是因为在 form 表单里 点击了button 按钮 触发了表单的默认事件 也就是触发了提交行
  • 自动化部署MySQL 5.6 步骤 制作到ftp共享,永远使用

    首先需要搭建ftpserver yum install vsftpd service vsftpd start 这样ftp服务就起来了 这里只是简单的使用 所以没有使用配置文件 这样我们只要将需要的文件置于 var ftp pub 文件夹下
  • http包通信方式,通信过程,包解析过程

    HTTP Hypertext Transfer Protocol 是一种客户端 服务器协议 用于在Web上传输数据 HTTP协议定义了客户端和服务器之间的通信方式 通信过程以及数据包解析过程 本文将详细讲解HTTP包通信方式 通信过程和包解
  • Dubbo调用过程监控

    MonitorFilter 主要对调用过程进行监控 public Result invoke Invoker
  • 【代码规范】函数命名总结

    Service DAO 层方法命名规约 Get 完整的拿出某一固定存在的结构 不修改 Build 需要根据一些因素构建一个结构 List 获取批量 Fetch 不用传参数获取 Handle handleFilePathFail这种 用于处理
  • java的windows脱机,Win32 API LogonUser对本地帐户的脱机访问

    是否有一系列标志允许 LogonUser 在计算机未连接到网络时返回可用于冒充本地用户的令牌 但所有帐户已在本地存在 我有域帐户执行应用程序 MYDOMAIN FooUser 而我正试图获得一个假冒令牌 MYLAPTOP TestUser
  • Kubernetes快速入门

    前言 本文旨在为Kubernetes入门使用者 提供使用Kubernetes需要掌握的基本知识 1 基础概念 1 1 集群与节点 kubernetes是一个开源的容器引擎管理平台 实现容器化应用的自动化部署 任务调度 弹性伸缩 负载均衡等功
  • 罗剑锋透视HTTP协议学习笔记---26

    26 信任始于握手 TLS1 2连接过程解析 TLS的几种子协议及结构 一个TLS报文由若干记录层 Record Layer 组成 记录层相当于是一个消息容器 承载其它协议 它包括一个TVL 描述其承载的其它协议 如上图 这是一个Serve
  • git 拉取上游仓库tag并同步

    git remote add upstream https github com xxxx xxxx git git fetch upstream tag vX X git tag git push origin refs tags vX
  • 拦截验证每个请求的权限

    前面做的虽然在界面内看不见没有权限的链接 但可以直接在地址栏输入链接进行访问 所以我们这里要使用拦截器拦截每个访问action的请求 1 struts配置
  • C++ 实现守护进程

    文章目录 1 守护进程概念 1 什么是守护进程 2 守护进程的特点 3 如何查看linux系统中已存在的守护进程 2 守护进程编写的步骤 3 示例 1 守护进程概念 1 什么是守护进程 Linux Deamon守护进程是运行在后台的一种特殊
  • 爬虫高级应用(14. 可见即可爬Selenium)

    本章主要内容 1 安装Selenium和WebDriver 2 Selenium的基本使用方法 3 查找节点 4 节点交互 5 管理Cookie 6 执行JavaScript代码 7 改变节点属性值 Selenium的主要功能 1 打开浏览
  • C++bitset处理二进制位的神器

    初始化 string str1 abc tftf 初始化 bitset lt 20 gt b1 bitset lt 20 gt b2 0xaa bitset lt 20 gt b3 str1 4 4 f t 字符串 起始位置 数量 代表0的
  • 重磅!Cloud Ace 在硅谷设立第一家美国办事处!

    Cloud Ace Corporation 总部位于东京千代田区 Makoto Aoki 总裁 于 2023 年 4 月 12 日成立了一家美国公司 作为其母公司 Yoshidumi Holdings Inc 的子公司 Cloud Ace
  • DBC编辑问题——无法设置报文发送类型和周期

    DBC编辑问题 无法设置报文发送类型和周期 提示 以下为实际CANdb Editor界面 均为置灰状态 无法设置 文章目录 DBC编辑问题 无法设置报文发送类型和周期 前言 一 自定义属性 二 修改发送方式和周期 1 回到message 2
  • 斯坦福密码学课程-笔记-02-Stream Ciphers流密码

    斯坦福密码学课程笔记 02 流密码 Stream Ciphers The One Time Pad Symmetric Ciphers definition The One Time Pad Vernam 1917 Information
  • yml注入map

    记录一次yml文件注入Map 首先是配置类 Component Configuration PropertySource value classpath application yml encoding utf 8 Configuratio
  • tensorflow 模型文件

    我的书 购买链接 京东购买链接 淘宝购买链接 当当购买链接 tensorflow生成的模型文件主要有三个 meta index和 data 分成三个文件的原因是tensorflow将计算图结构和变量值存储在不同的文件里 meta文件描述的是
  • 优雅地理解线程池源码

    线程池源码 网上的一些博客对线程池的讲解都是逐行解读源码 看起来可能会比较费力 本文从功能角度出发 以整个流程为切入点 省去一些没必要的源码 带你逐层抽丝剥茧 理解线程池设计的精髓所在 前置知识 几个常量和变量 ctl是一个int类型的组合
  • FreeRTOS_中断

    传送门 博客汇总帖 传送门 Cortex M3 中断 异常 传送门 Cortex M3笔记 基础 笔记内容参考 正点原子的FreeRTOS开发手册 cortex m3权威指南 Cortex M3和Cortex M4权威指南等 文中stm32