FreeRTOS学习笔记-基于stm32(3)中断管理

一、什么是中断

        通俗点讲就是让CPU停止当前在做的事,转而去做更紧急的事。

二、中断优先级分组

        这个紧急的事也有一个等级之分,优先级越高越先执行。stm32使用中断优先配置寄存器的高4位,共16级的中断优先等级。

        stm32的中断优先等级可以分为抢占优先级和子优先级。抢占优先级高的中断可以打断正在执行的抢占优先级低的中断;当抢占优先级相同时,子优先级高的优先执行。

eg:抢占优先级2,子优先级1的中断可以打断抢占优先级3,子优先级0的中断;但抢占优先级2,子优先级1的中断不能打断抢占优先级2,子优先级2的中断;虽然前者子优先级高于后者,但子优先级不能打断其他中断

三、特征

        1、低于configMAX_SYSCALL_INTERRUPT_PRIORITY(一般默认设置为5)优先级的中断才允许调用FreeRTOS的API函数(带有“FromISR后缀的函数”);

        2、将所有优先级位指定为抢占优先级位,方便管理;

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 

        3、中断优先级越小越优先,任务优先级越大越优先;

四、FreeRTOS中断相关寄存器

        FreeRTOS 中,通过 SHPR3 寄存器,将 PendSV 和 Systick 中断优先级被设置为最低,因为要保证系统任务的切换不会阻塞系统其他中断的响应

1、FreeRTOS关闭中断:

        FreeRTOS 中,通过 BASEPRI 寄存器,屏蔽优先级低于某一阈值的中断。

eg:BASEPRI 寄存器设置为0x50,表示中断优先级在5~15内的均被屏蔽,0~4的正常执行。(因为中断寄存器使用的是8位寄存器的高4位)也就是关闭FreeRTOS的中断  。

portDISABLE_INTERRUPTS();       //关闭中断

         经过此函数的一层层回调,会发现最终此函数还是对寄存器 basepri 写入0x50来关闭中断;

#define portDISABLE_INTERRUPTS()				vPortRaiseBASEPRI()#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			15                      //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5                       //系统可管理的最高中断优先级
#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) 
//此处对5进行左移4位,正是因为控制中断的寄存器高4位有效static portFORCE_INLINE void vPortRaiseBASEPRI( void )
{
uint32_t ulNewBASEPRI = configMAX_SYSCALL_INTERRUPT_PRIORITY;__asm{/* Set BASEPRI to the max syscall priority to effect a criticalsection. */msr basepri, ulNewBASEPRI //将0x50写入寄存器basepridsbisb}
}

2、FreeRTOS开启中断:

        将 BASEPRI 寄存器值设置为0时,则不关闭任何中断。

portENABLE_INTERRUPTS();        //开启中断

        此处就比较简单了,与关闭中断函数类似,直接对中断寄存器 basepri 写0。

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

 五、中断管理例程

        创建函数与上一章说的类似,此处只展示 task1 代码:

注意:此处延时函数使用的是 delay_xms(); 而不是delay_ms(); 或 vTaskDelay(); 因为FreeRTOS提供的 vTaskDelay() 内部会调用到 vPortSetBASEPRI( 0 ) ,就是上面开启中断所调用的内部函数。也就是说 vTaskDelay() 会调用到开中断函数,而 delay_ms() 内部则是调用的 vTaskDelay() 函数所以如果调用 vTaskDelay() 函数会提前开启中断,从而得不到正确的实验现象。

void task1( void * pvParameters )
{uint8_t task1_num=0;while(1){if(++task1_num==5){printf("关中断!!!\r\n");portDISABLE_INTERRUPTS();       //关闭中断delay_xms(5000);printf("开中断!!!!!!\r\n");portENABLE_INTERRUPTS();        //开启中断}vTaskDelay(1000);}
}

        定时器部分,为了验证FreeRTOS的中断管理函数仅对5~15的优先级有效,所以 TIM3 的优先级为4,TIM5 的优先级为6;

void TIM3_Int_Init(u16 arr,u16 psc)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能//定时器TIM3初始化TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断//中断优先级NVIC设置NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;  //先占优先级4级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器TIM_Cmd(TIM3, ENABLE);  //使能TIMx					 
}//通用定时器5中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器5!
void TIM5_Int_Init(u16 arr,u16 psc)
{TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); //时钟使能//定时器TIM3初始化TIM_TimeBaseStructure.TIM_Period = arr; 					//设置在下一个更新事件装入活动的自动重装载寄存器周期的值	TIM_TimeBaseStructure.TIM_Prescaler =psc; 					//设置用来作为TIMx时钟频率除数的预分频值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 	//设置时钟分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); 			//根据指定的参数初始化TIMx的时间基数单位TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE ); 					//使能指定的TIM5中断,允许更新中断//中断优先级NVIC设置NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;  			//TIM5中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;  	//先占优先级6级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  		//从优先级0级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 			//IRQ通道被使能NVIC_Init(&NVIC_InitStructure);  							//初始化NVIC寄存器TIM_Cmd(TIM5, ENABLE);  									//使能TIM5					 
}

        中断服务函数

//定时器3中断服务函数
void TIM3_IRQHandler(void)
{if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断{printf("TIM3输出!!!\r\n");}TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}//定时器5中断服务函数
void TIM5_IRQHandler(void)
{if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET) //溢出中断{printf("TIM5输出!!!!!!\r\n");}TIM_ClearITPendingBit(TIM5,TIM_IT_Update);  //清除中断标志位
}

        由于FreeRTOS的中断管理函数仅对5~15的优先级有效,所以关闭中断后,TIM3会正常工作。

        实验现象:

        至于关中断时候输出的乱码,我个人觉得可能是抢占同一个串口导致的。

                                 

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

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

相关文章

让开源浏览器Chromium正常显示中文

什么是 Chromium &#xff1f; Chromium 是一个开源浏览器项目&#xff0c;旨在为所有用户构建一种更安全、更快、更稳定的网络体验方式。 和老苏之前介绍的 Firefox 的作用是一样的 文章传送门&#xff1a;给群晖安装firefox浏览器 因为是基于 vnc 的应用&#xff0c;感觉资源…

Elasticsearch 通过索引阻塞实现数据保护深入解析

Elasticsearch 是一种强大的搜索和分析引擎&#xff0c;被广泛用于各种应用中&#xff0c;以其强大的全文搜索能力而著称。 不过&#xff0c;在日常管理 Elasticsearch 时&#xff0c;我们经常需要对索引进行保护&#xff0c;以防止数据被意外修改或删除&#xff0c;特别是在进…

mysql笔记:1. 数据库创建与删除

可以使用show databases语句来查看当前所有存在的数据库。 mysql> show databases; Database ---------- information_schema mysql performance_schema sys其中&#xff0c;mysql用来描述用户访问权限。 创建数据库 创建数据库可以使用create database命令。 例如&#…

动态规划 第一期 背包问题

前言 动态规划难度较高&#xff0c;但是也十分重要&#xff0c;希望大家能够好好的理解&#xff01;&#xff01;&#xff01; 一、背包问题 思维导图&#xff1a; 背包问题(Knapsack problem)是一种组合优化的NP完全问题。问题可以描述为&#xff1a;给定一组物品&#xff…

c++ primer中文版第五版作业第十四章

见仓库 文章目录 14.114.214.314.414.514.614.714.814.914.1014.1114.1214.1314.1414.1514.1614.1714.1814.1914.2014.2114.2214.2314.2414.2514.2614.2714.2814.2914.3014.3114.3214.3314.3414.3514.3614.3714.3814.3914-4014.4114.4214.4314.4414.4514.4614.4714.4814.4914.5…

实现QT中qDebug()的日志重定向

背景&#xff1a; 在项目开发过程中&#xff0c;为了方便分析和排查问题&#xff0c;我们需要将原本输出到控制台的调试信息写入日志文件&#xff0c;进行持久化存储&#xff0c;还可以实现日志分级等。 日志输出格式&#xff1a; 我们需要的格式包括以下内容&#xff1a; 1.…

MySQL死锁详细介绍

首先死锁产生的原因&#xff1a;两个及以上事务争夺资源导致互相等待造成的 比如事务A先修改id为1的数据再去修改id为2的数据&#xff0c;事务B先修改id为2的数据再去修改id为1的数据&#xff0c;因为事务A先拿到id1的锁再去拿id2的锁&#xff0c;而事务B先拿到id2的锁又去拿id…

“成像光谱遥感技术中的AI革命:ChatGPT应用指

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境&#xff0c;是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型&#xff0c;在理解和生成人类语言方面表现出了非凡的能力。本文重点介绍ChatGPT在遥感中的应用&#xff0c;人工智能…

【Algorithms 4】算法(第4版)学习笔记 16 - 4.2 有向图

文章目录 前言参考目录学习笔记1&#xff1a;介绍1.1&#xff1a;有向图简介1.2&#xff1a;应用举例1.3&#xff1a;相关问题2&#xff1a;有向图 API2.1&#xff1a;有向图表示2.1.1&#xff1a;邻接表数组 Adjacency-list2.1.2&#xff1a;Java 实现&#xff1a;邻接表数组2…

2. gin中间件注意事项、路由拆分与注册技巧

文章目录 一、中间件二、Gin路由简介1、普通路由2、路由组 三、路由拆分与注册1、基本的路由注册2、路由拆分成单独文件或包3、路由拆分成多个文件4、路由拆分到不同的APP 一、中间件 在日常工作中&#xff0c;经常会有一些计算接口耗时和限流的操作&#xff0c;如果每写一个接…

Sftp服务器搭建(linux)

Sftp服务器搭建&#xff08;linux&#xff09; 一、基本工作原理 FTP的基本工作原理如下&#xff1a; 1&#xff09;建立连接&#xff1a;客户端与服务器之间通过TCP/IP建立连接。默认情况下&#xff0c;FTP使用端口号21作为控制连接的端口。​​​​​​​ 2&#xff09;身…

基于AI软件平台 HEGERLS智能托盘四向车机器人物流仓储解决方案持续升级

随着各大中小型企业对仓储需求的日趋复杂&#xff0c;柔性、离散的物流子系统也不断涌现&#xff0c;各种多类型的智能移动机器人、自动化仓储装备大量陆续的应用于物流行业中&#xff0c;但仅仅依靠传统的物流技术和单点的智能化设备&#xff0c;已经无法更有效的应对这些挑战…

Office 2007软件安装教程(附软件下载地址)

软件简介&#xff1a; 软件【下载地址】获取方式见文末。注&#xff1a;推荐使用&#xff0c;更贴合此安装方法&#xff01; 微软Office 2007是一款具有重大创新与革命性的办公软件套件。它引入了全新设计的用户界面&#xff0c;提供稳定安全的文件格式&#xff0c;并实现了无…

数据结构 - 堆(优先队列)+ 堆的应用 + 堆练习

文章目录 前言堆一、什么是堆二、堆又分为大根堆和小根堆三、由于堆的逻辑结构被看成完全二叉树&#xff0c;那么我们先来了解一下完全二叉树。四、堆使用数组还是链表储存数据呢&#xff1f;五、数组构建二叉树和父子节点之间的定位六、堆进行的操作七、实现小根堆1、堆的初始…

算法(数据结构)面试问题准备 二分法/DFS/BFS/快排

一、算法概念题 1. 二分法 总结链接几种查找情况的模板另一个好记的总结总结&#xff1a;搜索元素两端闭&#xff0c;while带等&#xff0c;mid1&#xff0c;结束返-1 搜索边界常常左闭右开&#xff0c;while小于&#xff0c;mid看边界开闭&#xff0c;闭开&#xff0c;结束i…

vue2【详解】生命周期(含父子组件的生命周期顺序)

1——beforeCreate&#xff1a;在内存中创建出vue实例&#xff0c;数据观测 (data observer) 和 event/watcher 事件配置还没调用&#xff08;data 和 methods 属性还没初始化&#xff09; 【执行数据观测 (data observer) 和 event/watcher 事件配置】 2——created&#xf…

指纹加密U盘/指纹KEY方案——采用金融级安全芯片 ACH512

方案概述 指纹加密U盘解决方案可实现指纹算法处理、数据安全加密、数据高速存取&#xff08;EMMC/TF卡/NandFlash&#xff09;&#xff0c;可有效保护用户数据安全。 方案特点 • 采用金融级安全芯片 ACH512 • 存储介质&#xff1a;EMMC、TF卡、NandFlash • 支持全系列国密…

解决白屏问题:让你的网站重焕生机

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

[Flutter]使用Provider进行状态管理

一、使用Provider进行状态管理的基本用法 Provider是Flutter中一个非常流行的状态管理工具&#xff0c;它可以帮助开发者更有效地管理Widget树中的数据。Provider的核心思想是将数据模型放置在Widget树中可以被多个子Widget访问的地方&#xff0c;而不必通过构造函数手动传递。…

软件测试 —— 如何测试图片上传功能?

作为一名专业的软件测试人员&#xff0c;测试图片上传功能是一个重要的任务&#xff0c;以下是一些测试该功能的常用方法&#xff1a; 1. 上传功能测试&#xff1a;确保图片上传功能正常工作&#xff0c;包括选择图片文件、点击上传按钮、上传进度显示、上传成功/失败的提示等。…