05_FreeRTOS中断管理

2023-05-16

目录

什么是中断

中断相关寄存器

源码实验


什么是中断

简介:让CPU打断正常运行的程序,转而去处理紧急的事件(程序) ,就叫中断

举例:上课可以比做CPU正常运行的程序,上厕所可以比做中断程序。

 中断执行机制,可简单概括为三步:

中断请求:外设产生中断请求(GPIO外部中断、定时器中断等)

响应中断:CPU停止执行当前程序,转而去执行中断处理程序(ISR)

退出中断:执行完毕,返回被打断的程序处,继续往下执行

中断优先级分组设置

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

 

STM32 的中断优先级可以分为抢占优先级和子优先级

抢占优先级:抢占优先级高的中断可以打断正在执行但抢占优先级低的中断

子优先级:当同时发生具有相同抢占优先级的两个中断时,子优先级数值小的优先执行

注意:中断优先级数值越小越优先

一共有5种分配方式,对应着中断优先级分组的5个组

 通过调用函数HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4)即可完成设置

特点:

1.低于configMAX_SYSCALL_INTERRUPT_PRIORITY优先级的中断里才允许调用FreeRTOS 的API函数

2.建议将所有优先级位指定为抢占优先级位,方便FreeRTOS管理

3.中断优先级数值越小越优先,任务优先级数值越大越优先

 

中断相关寄存器

三个系统中断优先级配置寄存器,分别为SHPR1、SHPR2、SHPR3

SHPR1寄存器地址:0xE000ED18

SHPR2寄存器地址:0xE000ED1C

SHPR3寄存器地址:0xE000ED20

 FreeRTOS如何配置PendSV和Systick中断优先级

 

 

 所以: PendSV和SysTick设置最低优先级

设置最低:保证系统任务切换不会阻塞系统其他中断的响应

三个中断屏蔽寄存器,分别为PRIMASK、 FAULTMASK和BASEPRI

 FreeRTOS所使用的中断管理就是利用的BASEPRI这个寄存器

BASEPRI:屏蔽优先级低于某一个阈值的中断

比如:BASEPRI设置为0x50,代表中断优先级在5~15内的均被屏蔽,0~4的中断优先级正常执行

BASEPRI:屏蔽优先级低于某一个阈值的中断,当设置为0时,则不关闭任何中断

关中断程序示例:

 中断优先级在5~15的全部被关闭

当BASEPRI设置为0x50时:

 在中断服务函数中调度FreeRTOS的API函数需注意:

1.中断服务函数的优先级需在FreeRTOS所管理的范围内

2.在中断服务函数里边需调用FreeRTOS的API函数,必须使用带“FromISR”后缀的函数

BASEPRI:屏蔽优先级低于某一个阈值的中断,当设置为0时,则不关闭任何中断

开中断程序示例:

 FreeRTOS中断管理就是利用BASEPRI寄存器实现的

源码实验

/**
  ******************************************************************************
  * @file           : user_timer.c
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "user_timer.h"
/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

/*!
	\brief		定时器初始化
	\param[in]	装载值
	\param[in]	分频系数
	\retval 	none
*/
void Tim3_Init(uint16_t arr, uint16_t psc)
{	
	/*定时器结构体*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeDefstruct;
	/*NVIC结构体*/
	NVIC_InitTypeDef NVIC_InitTypeDefstruct;
	
	TIM_TimeBaseInitTypeDefstruct.TIM_Period = arr; //自动装载值
	TIM_TimeBaseInitTypeDefstruct.TIM_Prescaler = psc; //分频系数
	TIM_TimeBaseInitTypeDefstruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
	TIM_TimeBaseInitTypeDefstruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频
	/*写入定时器3*/
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitTypeDefstruct);

	/*使能定时器更新中断配置*/
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
	
	/*定时器中断优先级配置*/	
	NVIC_InitTypeDefstruct.NVIC_IRQChannel=  TIM3_IRQn; //USART1中断通道
	NVIC_InitTypeDefstruct.NVIC_IRQChannelCmd = ENABLE;  //使能USART1中断
	NVIC_InitTypeDefstruct.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
	NVIC_InitTypeDefstruct.NVIC_IRQChannelSubPriority = 0;//子优先级
	
	/*写入NVIC中*/
	NVIC_Init(&NVIC_InitTypeDefstruct);
	
	/*使能定时器*/
	TIM_Cmd(TIM3,ENABLE);
	
	
}

/*!
	\brief		TIM3_IRQHandler
	\param[in]	none
	\param[in]	none
	\retval 	none
*/

void TIM3_IRQHandler(void)
{
	/*判断是不是更新中断*/
	if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET)
	{
		printf("定时器3时间到任务优先级2********\r\n");
	}		
	/*清除更新中断*/
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
	
}


/*!
	\brief		定时器初始化
	\param[in]	装载值
	\param[in]	分频系数
	\retval 	none
*/
void Tim4_Init(uint16_t arr, uint16_t psc)
{	
	/*定时器结构体*/
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeDefstruct;
	/*NVIC结构体*/
	NVIC_InitTypeDef NVIC_InitTypeDefstruct;
	
	TIM_TimeBaseInitTypeDefstruct.TIM_Period = arr; //自动装载值
	TIM_TimeBaseInitTypeDefstruct.TIM_Prescaler = psc; //分频系数
	TIM_TimeBaseInitTypeDefstruct.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
	TIM_TimeBaseInitTypeDefstruct.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频
	/*写入定时器4*/
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitTypeDefstruct);

	/*使能定时器更新中断配置*/
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
	
	/*定时器中断优先级配置*/	
	NVIC_InitTypeDefstruct.NVIC_IRQChannel=  TIM4_IRQn; //USART1中断通道
	NVIC_InitTypeDefstruct.NVIC_IRQChannelCmd = ENABLE;  //使能USART1中断
	NVIC_InitTypeDefstruct.NVIC_IRQChannelPreemptionPriority = 6; //抢占优先级
	NVIC_InitTypeDefstruct.NVIC_IRQChannelSubPriority = 0;//子优先级
	
	/*写入NVIC中*/
	NVIC_Init(&NVIC_InitTypeDefstruct);
	
	/*使能定时器*/
	TIM_Cmd(TIM4,ENABLE);
	
	
}

/*!
	\brief		TIM4_IRQHandler
	\param[in]	none
	\param[in]	none
	\retval 	none
*/

void TIM4_IRQHandler(void)
{
	/*判断是不是更新中断*/
	if(TIM_GetITStatus(TIM4,TIM_IT_Update) == SET)
	{
		printf("定时器4时间到任务优先级6!!!!\r\n");
	}		
	/*清除更新中断*/
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
	
}

/************************************************************** END OF FILE ****/
 
/**
  ******************************************************************************
  * @file           : user_mian.h
  * @brief          : V1.00
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Include 包含---------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdbool.h>
#include "user_gpio.h"
#include "user_delay.h"
#include "user_rcc_config.h"
#include "user_uart.h"
#include "user_timer.h"
#include "FreeRTOS.h"
#include "task.h"

/* Typedef 类型----------------------------------------------------------------*/
/* Define  定义----------------------------------------------------------------*/
/* Macro   宏------------------------------------------------------------------*/
/* Variables 变量--------------------------------------------------------------*/ 
/* Constants 常量--------------------------------------------------------------*/
/* Function  函数--------------------------------------------------------------*/

//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_STK_SIZE 		128  
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);


//任务优先级
#define Interruption_TASK_PRIO		2
//任务堆栈大小	
#define Interruption_STK_SIZE 		50  
//任务句柄
TaskHandle_t InterruptionTask_Handler;
//任务函数
void Interruption_task(void *pvParameters);





 int main(void)
 {	

	/*配置系统中断分组为4位抢占*/
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	 /*延时函数初始化*/
	 delay_init();
	/*RCC配置*/
	 Rcc_config();
	/*GPIO初始化*/ 
	 Gpio_Init();
	/*USART1初始化*/
	 Uart1_Init(9600);
	 /*初始化定时器3,1s中断*/ 
	 Tim3_Init(10000-1,7200-1);
	 /*初始化定时器4,1s中断*/ 
	 Tim4_Init(10000-1,7200-1);
	/*创建开始任务*/
    xTaskCreate((TaskFunction_t )start_task,            //任务函数
                (const char*    )"start_task",          //任务名称
                (uint16_t       )START_STK_SIZE,        //任务堆栈大小
                (void*          )NULL,                  //传递给任务函数的参数
                (UBaseType_t    )START_TASK_PRIO,       //任务优先级
                (TaskHandle_t*  )&StartTask_Handler);   //任务句柄              
    vTaskStartScheduler();          //开启任务调度
		

}
 

/*!
	\brief		开始任务函数
	\param[in]	传递形参,创建任务时用户自己传入
	\param[out]	none
	\retval 	none
*/
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建LED0任务
    xTaskCreate((TaskFunction_t )Interruption_task,     	
                (const char*    )"Interruption_task",   	
                (uint16_t       )Interruption_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )Interruption_TASK_PRIO,	
                (TaskHandle_t*  )&InterruptionTask_Handler);   
         
    vTaskDelete(StartTask_Handler); //删除开始任务
    taskEXIT_CRITICAL();            //退出临界区
}


/*!
	\brief		led0_task任务函数
	\param[in]	传递形参,创建任务时用户自己传入
	\param[out]	none
	\retval 	none
*/
void Interruption_task(void *pvParameters)
{
	uint8_t i =0;
    while(1)
    {
		if(++i == 5)
		{
			i=0;
			printf("关闭中断*****\r\n");
			/*关闭中断*/
			portDISABLE_INTERRUPTS();
			/*延时5秒*/
			delay_us(5000000);
			printf("开启中断*****\r\n");
			/*开启中断*/
			portENABLE_INTERRUPTS();			
		}

		vTaskDelay(1000);
    }
} 

 /************************************************************** END OF FILE ****/

 

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

05_FreeRTOS中断管理 的相关文章

  • FreeRTOS例程4-串口DMA收发不定长数据

    FreeRTOS例程4 串口DMA收发不定长数据 知乎 zhihu com
  • 基于HAL库的FREERTOS----------二.任务API函数

    任务API函数览概 CUBEMX对 做了API的封装 很多 的函数没有封装到位 可以用原函数调用 任务API函数分别介绍 1 uxTaskPriorityGet 此函数用来获取指定任务的优先级 要使用此函数的话宏 INCLUDE uxTas
  • 【FreeRtos学习笔记】STM32 CubeMx——Timers(定时器)

    目录 1 软件定时器 2 示例程序 2 1 例程功能 2 2 步骤 2 3 实验结果 2 4 函数讲解 1 软件定时器 定时器是MCU常用的外设 我们在学习各种单片机时必然会学习它的硬件定时器 但是 MCU自带的硬件定时器资源是有限的 而且
  • FreeRTOS config开始的宏

    FreeRTOSConfig h系统配置文件中可以自定义 FreeRTOS h中定义默认值 configAPPLICATION ALLOCATED HEAP 默认情况下FreeRTOS的堆内存是由编译器来分配的 将宏configAPPLIC
  • STM32F103移植FreeRTOS必须搞明白的系列知识---3(堆栈)

    STM32F103移植FreeRTOS必须搞明白的系列知识 1 Cortex CM3中断优先级 STM32F103移植FreeRTOS必须搞明白的系列知识 2 FreeRTOS任务优先级 STM32F103移植FreeRTOS必须搞明白的系
  • FreeRTOS记录(七、FreeRTOS信号量、事件标志组、邮箱和消息队列、任务通知的关系)

    我们在前面单独介绍过FreeRTOS的任务通知和消息队列 但是在FreeRTOS中任务间的通讯还有信号量 邮箱 事件组标志等可以使用 这篇文章就这些成员与消息队列和任务通知的关系进行说明分析 增加邮箱部分 任务通知发送消息 Demo 202
  • FreeRTOS-内核控制函数

    FreeRTOS 内核控制函数 FreeRTOS中有一些内核函数 一般来说这些内核函数在应用层不会使用 但是内核控制函数是理解FreeRTOS中断的基础 接下来我们逐一分析这些内核函数 taskYIELD 该函数的作用是进行任务切换 这是一
  • FreeRTOS软件定时器创建、复位、开始和停止(备忘)

    目录 一 简介 1 1 开发环境 1 2 摘要 二 STM32CubeIDE配置 三 创建定时器 3 1 头文件声明 3 2 工程文件定义 3 3 创建定时器 3 4 开启 复位 和关闭定时器 四 定时器回调函数 一 简介 1 1 开发环境
  • 【FreeRTOS】多任务创建

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏资料 https pan baidu com s 1nc1rfyLiMyw6ZhxiZ1Cumg pwd free 点赞 收藏 再看 养成习惯 订阅的粉丝
  • FreeRTOS学习(八) 延时函数

    声明及感谢 跟随正点原子资料学习 在此作为学习的记录和总结 环境 keil stm32f103 FreeRTOS延时函数有两个 分别是 vTaskDelay vTaskDelayUntil 1 vTaskDelay 任务相对延时 函数原型
  • 基于HAL库的FREERTOS-----------三.队列

    一 队列简介 在实际的应用中 常常会遇到一个任务或者中断服务需要和另外一个任务进行 沟通交流 这个 沟通交流 的过程其实就是消息传递的过程 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式 但是如果在使用操作系统的应用中用
  • FreeRTOS基础五:软件定时器

    软件定时器简介 软件定时器的作用 在指定的时间到来时执行指定的函数 或者以某个频率周期性地执行某个函数 被执行的函数叫做软件定时器回调函数 软件定时器由FreeRTOS内核实现 不需要硬件支持 软件定时器只有在软件定时器回调函数被调用时才需
  • FreeRTOS笔记(一)简介

    这个笔记主要依据韦东山freertos快速入门系列记录 感谢韦东山老师的总结 什么是实时操作系统 操作系统是一个控制程序 负责协调分配计算资源和内存资源给不同的应用程序使用 并防止系统出现故障 操作系统通过一个调度算法和内存管理算法尽可能把
  • FreeRTOS学习---“定时器”篇

    总目录 FreeRTOS学习 任务 篇 FreeRTOS学习 消息队列 篇 FreeRTOS学习 信号量 篇 FreeRTOS学习 事件组 篇 FreeRTOS学习 定时器 篇 FreeRTOS提供了一种软件定时器 用来快速实现一些周期性的
  • 【FreeRTOS 事件】任务通知事件

    普通任务通知事件创建创建及运行 参阅安富莱电子demo define BIT 0 1 lt lt 0 define BIT 1 1 lt lt 1 static TaskHandle t xHandleTaskUserIF NULL sta
  • 13-FreeRTOS任务创建与删除

    任务创建和删除API函数位于文件task c中 需要包含task h头文件 task h里面包函数任务的类型函数 例如 对xTaskCreate的调用 通过指针方式 返回一个TaskHandle t 变量 然后可将该变量用vTaskDele
  • FreeRTOSConfig.h 配置优化及深入

    本篇目标 基于上一篇的移植freertos stm32f4 freertos 上 修改 FreeRTOSConfig h 文件的相关配置来优化辅助 FreeRtos 的使用 并且建立一些基本功能 信号量 消息地列等 的简单应用位于 stm3
  • 防止GCC LTO删除函数

    我使用 GCC ARM Embedded 和 FreeRTOS FreeRTOS具有的功能vTaskSwitchContext 仅在某些情况下使用 内联汇编代码 问题是 当我使用LTO时 GCC不考虑内联汇编代码并认为该函数没有被使用 因此
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 有关 CMake 错误的问题:没有为目标提供源

    我正在尝试使用 cmake 和 eclipse 将 FreeRtos 添加到我的项目中 但出现错误 我运行的是 debian 10 我的 cmake 版本是 3 13 4 cmake 的文件可以在以下位置找到这个 git 仓库 https

随机推荐

  • opencv3.2安装opencv_contrib

    opencv3 2 增加opencv contrib组件 之前在ubuntu16 04下安装caffe和opencv3 2 xff0c 由于需要需要使用opencv contrib组件 xff0c 在安装中遇到一些问题 在已安装好openc
  • 最小二乘法

    最小二乘法 xff08 又称最小平方法 xff09 是一种数学优化技术 它通过最小化误差的平方和寻找数据的最佳函数匹配 利用最小二乘法可以简便地求得未知的数据 xff0c 并使得这些求得的数据与实际数据之间误差的平方和为最小 最小二乘法还可
  • python vstack

    Python numpy函数hstack vstack stack dstack vsplit concatenate 感觉numpy hstack 和numpy column stack 函数略有相似 xff0c numpy vstack
  • Linux下VNC Server的配置

    1 xff09 安装vnc server xff1a rpm ivh tigervnc server 1 1 0 5 el6 x86 64 rpm 2 修改配置文件 xff0c 1 表示第1号桌面 xff0c 对应端口号5901 2 表示2
  • WIN10_GTX1650_深度学习环境搭建

    这篇博客总结的非常好 xff0c 但安装过程中可能会碰到一些问题 在这记录 xff0c 分享一下解决方案 https blog csdn net weixin 45755980 article details 105397874 Tenso
  • Linux面试必备20个常用命令

    文章目录 第一章 什么是linux第二章 linux的基础命令1 pwd 命令2 ls 命令3 cd 命令4 man 命令5 grep 命令6 find 命令7 chmod 命令8 ps 命令9 kill 命令10 tail 命令11 ne
  • Python爬虫实战(一):翻页爬取数据存入SqlServer

    目录 前言爬取目标准备工作代码分析1 设置翻页2 获取代理ip3 发送请求4 获取详情页地址5 提取详情信息6 存入数据库7 循环实现翻页8 启动 前言 x1f525 x1f525 本文已收录于Python爬虫实战100例专栏 xff1a
  • 已解决error: subprocess-exited-with-error

    已解决 xff08 pip安装第三方模块lxml模块报错 xff09 Building wheels for collected packages lxml Building wheel for lxml setup py error er
  • 已解决此处缺少‘,‘, ‘]‘字符, 实际上是一个 ‘EOF‘

    已解决Python解析JSON xff0c 抛出此处缺少 39 39 39 字符 实际上是一个 39 EOF 异常的解决方法 xff0c 亲测有效 文章目录 报错问题报错原因解决方法千人全栈VIP答疑群联系博主帮忙解决报错 报错问题 粉丝群
  • 已解决E: Unable to locate package ros-kinetic-desktop-full

    已解决Ubuntu安装ros xff0c 抛出异常E Unable to locate package ros kinetic desktop full的正确解决方法 xff0c 亲测有效 xff0c 文末附上Ubuntu系统对应ros系统
  • 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn ) 概论思想(perfect shuffle 算法)

    perfect shuffle 算法 今天又发现一个关于完美洗牌的算法 这个比较简单一些 xff0c 由 microsoft的Peiyush Jain提出 原论文 xff1a A Simple In Place Algorithm for
  • Linux操作系统之命令

    Linux操作系统指令有很多 xff0c 这里就先介绍一些最最基础的吧 首先就是将操作界面显示 xff1a Ctrl 43 alt 43 t 显示当前目录内容 xff1a ls ls l xff1a 将目录内容使用列表显示 ls a xff
  • [操作系统]学习操作系统的经典书籍

    http blog chinaunix net u1 43966 showart 396940 html 介绍了一些操作系统学习的经典书籍 xff0c 包括理论上的 具体操作系统的 Abraham Silberschatz的两本书 xff1
  • 原创:史上最全最通俗易懂的,索引最左前缀匹配原则(认真脸)

    索引最左前缀匹配原则 对于最左前缀匹配原则居然没有百度百科 xff0c 实在是让我感觉不可思议 最左前缀匹配原则 xff0c 用几句话来概述就是 xff1a 顾名思义 xff0c 就是最左优先 xff0c 在创建多列索引时 xff0c 要根
  • MATLAB从文件读取数据

    一 从filename文件读取数据 1 readtable函数 语法 xff1a t 61 readtable xff08 filename xff09 支持的扩展名 xff1a txt csv xls xlsm xlsx xlsm xlt
  • 前端进阶之TS总结

    知识点 高频面试题TS装饰器axios二次封装 1 高频面试题 1 1 类型推论 amp 可赋值性 什么是类型推论 xff1f TypeScript 会在没有明确的指定类型的时候推测出一个类型 xff0c 这就是类型推论如果定义的时候没有赋
  • 岁月清浅,邀你入梦

    这世间本应美好 xff0c 怎无奈痛苦缠身 xff0c 卿心亦真 xff0c 免世人之苦 xff0c 乐自身之本 卿之容 xff0c 多沉醉 xff0c 于心赞 xff0c 日夜思 淡若微风的陪伴 xff0c 奈何情深缘浅 只相识 xff0
  • 记一次解BUG的心得感受

    今天遇到 了 一个 STP的问题 xff0c 从测试 现象 来看与之前一个FR的验证过程中表现出来的特征很相似 这种相似性将我引入了一种歧途 xff1a 怀疑原来的修改有问题 假设你知道第N次修改有潜在的case无法验证 那么这种潜在的风险
  • 02_Keil5报错 error: #5: cannot open source input file “XXX.h”: No such file or directory解决方法

    Keil5 error 5 cannot open source input file led h No such file or directory 是找不到包含文件 解决办法1 包含文件可以解决 解决办法2 如果包含了还是报 5找不到文
  • 05_FreeRTOS中断管理

    目录 什么是中断 中断相关寄存器 源码实验 什么是中断 简介 让CPU打断正常运行的程序 转而去处理紧急的事件 程序 就叫中断 举例 上课可以比做CPU正常运行的程序 上厕所可以比做中断程序 中断执行机制 可简单概括为三步 中断请求 外设产