【FreeRTOS】——中断优先级设置中断相关寄存器临界段代码保护调度器挂起与恢复

news/2024/10/31 5:27:36/

目录

前言:

一、中断优先级设置

二、中断相关寄存器(STM32-Cortex M3)

三、临界段代码保护

四、任务调度器的挂起和恢复

总结:


前言:

博客笔记根据正点原子视频教程编辑,仅供学习交流使用!

一、中断优先级设置

①中断概念回顾

让CPU打断正常运行的程序,转而去处理紧急的事件(程序),就叫中断。可简单概括为以下三步:

                   

② 优先级分组设置

ARM Cortex-M 使用了 8 位宽的寄存器(256级)来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器。但STM32,只用了中断优先级配置寄存器的高4位 [7 : 4],所以STM32提供了最大16级的中断优先等级。

             

 STM32 的中断优先级可以分为抢占优先级子优先级抢占优先级: 抢占优先级高的中断可以打断正在执行但抢占优先级低的中断。子优先级:当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的优先执行。(中断优先级数值越小越优先)

优先级的设置有5 种分配方式,对应着中断优先级分组的 5 个组,通过在在HAL_Init()中调用函数HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)即可完成设置(FreeRTOS中常用NVIC_PriorityGroup_4):

            

 注意:低于5级优先级的中断里才可调用FreeRTOS的API函数。在FreeRTOS中常把4位都设置为抢占优先级即NVIC_PriorityGroup_4。中断优先级数值越小越优先,任务优先级数值越大越优先。


二、中断相关寄存器(STM32-Cortex M3)

①三个系统中断优先级配置寄存器

一个寄存器是32位的,它的地址是这一段区域的首地址(8位),要设置一个寄存器区域的非首地址(如PendSV和SysTick),通过首地址偏移bit即可。

SHPR1寄存器地址:0xE000ED1

SHPR2寄存器地址:0xE000ED1C

SHPR3寄存器地址:0xE000ED20

         

 注意:PendSV和SysTick设置最低优先级,保证系统任务切换不会阻塞系统其他中断的响应。即中断可打断任务,但任务不可打断中断。

②三个中断屏蔽寄存器

  

注意:FreeRTOS利用的BASEPRI这个寄存器完成对中断的管理。该寄存器屏蔽优先级低于某个阈值(或优先级号大于某个值)的中断,如BASEPRI设置为0x50(配置优先级只用到低4位,只用到高四位[7:4],所以这里写的是5向左偏移4位的值),代表中断优先级在5~15内的均被屏蔽,0~4的中断优先级正常执行。当BASEPRI设置为0,不关闭任何中断(不是屏蔽所有中断的意思)。

关闭中断优先级在5-15的中断程序示例:

#define portDISABLE_INTERRUPTS() 		vPortRaiseBASEPRI()
static portFORCE_INLINE void vPortRaiseBASEPRI( void ) 
{ uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY; __asm {msr basepri, ulNewBASEPRI dsb isb} 
}
#define configMAX_SYSCALL_INTERRUPT_PRIORITY            ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )  
/*STM32中断优先级只用高4位配置,偏移4位*/
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY        5      
/* FreeRTOS可管理的最高中断优先级 ,也即把BASEPRI设置为0x50*/ 

  

 FreeRTOS说:“我可以中断你,可以让你用我的API函数;我不能中断你,你也不能用我的API函数!”

注意:中断服务函数的优先级需在FreeRTOS所管理的范围内;中断服务函数里边需调用FreeRTOS的API函数,必须使用带“FromISR”后缀的函数。

 开中断代码示例(即BASEPRI设置为0):

#define portENABLE_INTERRUPTS()		 vPortSetBASEPRI( 0 )
static portFORCE_INLINE void vPortSetBASEPRI( uint32_t ulBASEPRI ) 
{ __asm{msr basepri, ulBASEPRI} 
}

三、临界段代码保护

临界段代码:也叫做临界区,是指那些必须完整运行,不能被打断的代码段。

使用场合:①外设:需严格按照时序初始化的外设,如I2C、SPI等。②系统在自身需求。③用户的某些需求。

能够打断当前程序运行的:中断、任务调度(PendSV相关)。要想程序不被打断,关中断即可(指FreeRTOS所管辖的最高级别中断),因为PendSV是与任务切换有关的一个中断,被设置成了最低优先级,所以关中断后,PendSV(与任务调度器有关)也一定不会响应。

FreeRTOS 在进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断!

    

 无论是任务级还是中断级临界区本质都是关中断,代码是成对使用的,且支持嵌套,可尽量保持临界段耗时短

//任务级临界区调用格式示例
taskENTER_CRITICAL() ;
{… …	/* 临界区 */
}
taskEXIT_CRITICAL()	;//中断级临界区调用格式示例(这段写在中断服务函数里)
uint32_t  save_status;
save_status  = taskENTER_CRITICAL_FROM_ISR();
{… …	/* 临界区 */
}
taskEXIT_CRITICAL_FROM_ISR(save_status );

四、任务调度器的挂起和恢复

 调用挂起任务调度器的函数时不需要关闭中断;仅仅是防止了任务之间的资源争夺,中断照样可以直接响应。

挂起调度器的方式,适用于临界区位于任务与任务之间;既不用去延时中断,又可以做到临界区的安全。

           

vTaskSuspendAll() ;
{… …	/* 内容 */
}
xTaskResumeAll()	;

总结:

实时操作系统是嵌入式学习的进阶内容,掌握好在面试时会有巨大优势!

往期精彩:

电机应用控制——直流无刷电机

OpenCV机器视觉系列专栏

C语言进阶


http://www.ppmy.cn/news/97597.html

相关文章

线程池实现

一、线程池介绍 1&#xff09;应用场景 当并发数很多的时候&#xff0c;并且每个线程执行时间很短的任务&#xff0c;这样就会频繁创建线程&#xff0c;而这样的频繁创建和销毁线程会大大降低系统的执行效率。对于这种场景我们可以使用线程池来复用之前创建的线程&#xff0c…

C++中queue的用法(超详细,入门必看)

博主简介&#xff1a;Hello大家好呀&#xff0c;我是陈童学&#xff0c;一个与你一样正在慢慢前行的人。 博主主页&#xff1a;陈童学哦 所属专栏&#xff1a;CSTL 前言&#xff1a;Hello各位小伙伴们好&#xff01;欢迎来到本专栏CSTL的学习&#xff0c;本专栏旨在帮助大家了解…

认识http协议---3

hi,大家好,今天为大家带来http协议的相关知识 &#x1f347;1.http状态响应码 &#x1f347;2.构造http请求 1.直接在地址栏里输入一个URL 2.html的一些特殊标签,触发get请求 3.提交form表单,可以触发get请求和post请求 4.使用ajax &#x1f347;3.再次谈同步和异步 &#x1f3…

JavaEE Tomcat Servelet第一个helloworld程序

Tomcat & Servelet第一个程序helloworld&#xff01; 文章目录 JavaEE & Tomcat & 第一个Servelet程序1. HTTP服务器 - Tomcat1.1 Tomcat的目录结构&#xff1a;1.2 启动Tomcat1.3 Tomcat的优点 2. Servelet框架2.1 创建Maven项目2.2 引入依赖2.3 创建目录2.4 写代…

Mac电脑读写移动硬盘软件Tuxera NTFS2023中文版

日常工作中&#xff0c;我们经常会使用移动硬盘拷贝文件&#xff0c;因为移动硬盘传输文件方便、传输速度快。但我们在mac电脑上使用移动硬盘却发现硬盘无法正常读写。本文向大家介绍mac能读写的移动硬盘有哪些以及移动硬盘怎么在mac上读写。 一、Mac能读写的移动硬盘有哪些 移…

开源情报搜集系统的核心技术

随着科技快速发展&#xff0c;科研方向的开源情报搜集系统的应用越来越广泛。为了满足科研工作者的需求&#xff0c;开发人员大力研发了许多功能强大的科研开源情报系统。这些系统不仅可以帮助科研人员更加高效地获取、管理和利用科研信息资源&#xff0c;还能为他们提供全方位…

有序表2:跳表

跳表是一个随机化的数据结构&#xff0c;可以被看做二叉树的一个变种&#xff0c;它在性能上和红黑树&#xff0c;AVL树不相上下&#xff0c;但是跳表的原理非常简单&#xff0c;目前在Redis和LeveIDB中都有用到。 它采用随机技术决定链表中哪些节点应增加向前指针以及在该节点…

Hadoop---10、生产调优手册

1、HDFS—核心参数 1.1 NameNode 内存生产配置 1、NameNode内存计算 每个文件块大概占用150byte&#xff0c;一台服务器128G内存为例&#xff0c;能储存多少文件块呢&#xff1f; 12810241024*1024/150Byte ≈ 9.1 亿 G M KB Byte 2、Hadoop2.x系列&#xff0c;配置 NameNode…