FreeRTOS学习之路,以STM32F103C8T6为实验MCU(2-2:中断)

学习之路主要为FreeRTOS操作系统在STM32F103(STM32F103C8T6)上的运用,采用的是标准库编程的方式,使用的IDE为KEIL5。

注意!!!本学习之路可以通过购买STM32最小系统板以及部分配件的方式进行学习,也可以通过Proteus仿真的方式进行学习。

后续文章会同时发表在个人博客(jason1016.club)、CSDN;

视频会发布在bilibili(UID:399951374)

一、中断与FreeRTOS的关系

中断与FreeRTOS任务体系是共存的,通常我们把正常工作执行的工作放在任务,某个紧急工作触发或者需要单片机加急去做的工作放在中断。

操作系统和中断其实没有那么玄乎。中断就是中断,OS起到的作用只是管理中断运行不允许,起到一个调控作用。与任务无关,中断就是中断嘛。

二、FreeRTOS对中断的屏蔽(关闭)

在许多应用中,需要暂时屏蔽所有的中断一执行一些对时序要求严格的任务。

我们可以通过配置下列三个寄存器屏蔽中断

  1. PRIMASK 用于禁止除复位、 NMI 和 HardFalut 外的所有异常和中断
  2. FAULTMASK 比 PRIMASK 更狠,它可以连 HardFault 都屏蔽掉
  3. BASEPRI 寄存器相对柔和,只屏蔽优先级低于某一个阈值的中断(下面就引出我们中断保留的概念)

三、中断保留

但是我们有时候会觉得,一关就全关了,太傻了是不是,所以我们要对OS关闭的中断设置一个阈值,让它不会全部关掉,保留一些重要的中断是不是。

对于STM32而言,中断优先级一共16个。

FreeRTOS是建立在正常裸机系统上的,所以裸机自己的中断是全部保留的。

那我觉得有些裸机中断不允许被OS控制怎么办,所以我们设置了一个OS中断阈值优先级寄存器。

意思就是得保留部分裸机中断级别,让FreeRTOS不参与进这部分级别中断的的开发。所以我们设计一个中断宏的阈值,高于此中断阈值的中断优先级不能被FreeRTOS操控。

大家可以自由设置,这里我设置为了 5。也就是高于 5 的优先级(优先级数小于 5)不归 FreeRTOS 管理!

configMAX_SYSCALL_INTERRUPT_PRIORITY==5

四、开关中断

我们这里用配置BASEPRI 寄存器的方法控制中断的开关

关闭中断:vPortRaiseBASEPRI() 原理就是向BASEPRI寄存器写入上述configMAX_SYSCALL_INTERRUPT_PRIORITY的值,关闭阈值以下优先级的中断

开启中断:vPortSetBASEPRI(0)

portDISABLE_INTERRUPTS()    //关闭中断(关闭MAX阈值中断优先级之后的中断)
portENABLE_INTERRUPTS()     //开启中断

五、临界段保护

上面也讲到了OS可以对中断进行屏蔽,这是针对某些不能被中断打断的重要任务嘛。那我们统一将那些进行需要屏蔽中断来保护运行的代码称为临界段;那我们开启屏蔽就叫临界段保护。

临界段代码也叫做临界区,是指那些必须完整运行,不能被打断的代码段,比如有的外设的初始化需要严格的时序,初始化过程中不能被打断。

通常由两个函数组成,一个是临界段进入,一个是临界段退出

taskENTER_CRITICAL();  //临界段进入
taskEXIT_CRITICAL();   //临界段退出

代码:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "sys.h"
#include "interrupt.h"


#define START_TASK_PRIO 1 //任务优先级
#define START_STK_SIZE 256 //任务堆栈大小
TaskHandle_t StartTask_Handler; //任务句柄
void start_task(void *pvParameters); //任务函数
#define INTERRUPT_TASK_PRIO 2 //任务优先级
#define INTERRUPT_STK_SIZE 256 //任务堆栈大小
TaskHandle_t INTERRUPTTask_Handler; //任务句柄
void interrupt_task(void *p_arg); //任务函数


int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4
delay_init(); //延时函数初始化
uart_init(115200); //初始化串口
LED_Init(); //初始化 LED
TIM3_Int_Init(10000-1,7200-1); //初始化定时器 3,定时器周期 1S
TIM5_Int_Init(10000-1,7200-1); //初始化定时器 5,定时器周期 1S
//创建开始任务
 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(); //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
 taskENTER_CRITICAL(); //进入临界区
 //创建中断测试任务
 xTaskCreate((TaskFunction_t )interrupt_task, //任务函数 (1)
 (const char* )"interrupt_task", //任务名称
 (uint16_t )INTERRUPT_STK_SIZE, //任务堆栈大小
 (void* )NULL, //传递给任务函数的参数
 (UBaseType_t )INTERRUPT_TASK_PRIO, //任务优先级
 (TaskHandle_t* )&INTERRUPTTask_Handler); //任务句柄
vTaskDelete(StartTask_Handler); //删除开始任务
 taskEXIT_CRITICAL(); //退出临界区
}

//中断测试任务函数
void interrupt_task(void *pvParameters)
{
static u32 total_num=0;
 while(1)
 {
total_num+=1;
if(total_num==5) 
{
printf("关闭中断.............\r\n");
portDISABLE_INTERRUPTS(); //关闭中断 (3)
delay_xms(5000); //延时 5s (4)
printf("打开中断.............\r\n"); //打开中断
portENABLE_INTERRUPTS();
}
 LED0=~LED0;
 vTaskDelay(1000);
 }
}



//定时器 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 TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET) //溢出中断
{
printf("TIM4 输出.......\r\n");
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位
}

本文为作者独立编写,本BLOG上所有的原创文章未经本人许可,不得用于商业用途及传统媒体。网络媒体转载请注明出处,否则属于侵权行为。  

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python中使用pyzbar实现二维码生成和识别功能

目录 一、引言 二、pyzbar库介绍 三、安装pyzbar库 四、使用pyzbar生成二维码 五、使用pyzbar识别二维码 一、引言 随着二维码的普及和应用,二维码生成和识别功能在日常生活和工作中越来越重要。在Python中,我们可以使用pyzbar库来实现二维码生成和…

9.9 Windows驱动开发:内核远程线程实现DLL注入

在笔者上一篇文章《内核RIP劫持实现DLL注入》介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过NtCreateThreadEx这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首…

TikTok与精神健康:社交媒体在压力时代的作用

在当今数字化和社交化的时代,社交媒体已成为人们生活中不可或缺的一部分。其中,TikTok作为一款备受欢迎的短视频应用,不仅改变了人们的娱乐方式,也对精神健康产生了深远的影响。 本文将深入探讨TikTok在压力时代对精神健康的作用…

【VScode】安装配置、插件及远程SSH连接

一、VSCode安装 二、配置安装插件 三、配置远程连接SSH 四、MinGW 一、VSCode安装 VS官网 Visual Studio Code - Code Editing. Redefined下载安装包: 二、配置安装插件 安装中文插件 配置字体为20 配置文件–>首选项->设置->Font Size为20 设置 VSC…

【2021集创赛】基于ARM-M3的双目立体视觉避障系统 SOC设计

本作品参与极术社区组织的有奖征集|秀出你的集创赛作品风采,免费电子产品等你拿~活动。 团队介绍 参赛单位:上海电力大学 队伍名称:骇行队 总决赛奖项:二等奖 1.摘要 随着信息技术的发展,AGV(Automated Guided Vehic…

oracle的debjob挂載查詢

背景 有一個需求需要定時去執行一個produce,可以使用oracle的dbjob定時執行,相比較之前的vbs更加絲滑 --傳遞produce 開始的時間 頻率 declarea number;beginDBMS_JOB.SUBMIT(a,xx_warehouse_daliy_record_p;,to_date(202311230800,yyyymmddhh24mi),…

第二证券:北证50指数一枝独秀 短剧游戏概念股持续活跃

周三,沪深两市三大指数颤动调整,北证50指数“鹤立鸡群”,大涨超8%。到收盘,上证综指报3043.61点,跌0.79%;深证成指报9855.66点,跌1.41%;创业板指报1950.01点,跌1.73%。沪…

促进材料基因工程基础理论、前沿技术和关键装备的发展和应用,第七届材料基因工程高层论坛将于12月重庆举办,龙讯旷腾出席会议

为了进一步促进材料基因工程基础理论、前沿技术和关键装备的发展和应用,加强国际交流,加速我国新材料的研发和应用,由中国材料研究学会、西部科学城重庆高新区管理委员会主办,重庆大学、北京科技大学、北京云智材料大数据研究院等…

计算机毕业设计项目选题推荐(免费领源码)Java+ssm+MYSQL酒店大数据资源管理系统的设计与实现02029

摘要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对酒店大数据资源管理系统等问题,对…

Modbus转Profinet网关:PLC与天信流量计通讯的经典案例

无论您是PLC或工业设备的制造商,还是工业自动化系统的维护人员,可能会遇到需要将不同协议的设备连接组合并通讯的情况,Modbus和Profinet是现代工业自动化中常见的两种通信协议,在工业控制领域中被广泛应用。 在这种情况绝大多数会…

界面组件DevExpress Reporting v23.1 - Web报表设计器功能升级

DevExpress Reporting是.NET Framework下功能完善的报表平台,它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集,包括数据透视表、图表,因此您可以构建无与伦比、信息清晰的报表 界面组件DevExpress Reporting v23.1已经发布一段…

【正则插件】前端正则插件以及预览插件推荐

1) 2) any-rule Pegex Previewer 下载好插件之后 在代码层右键选择 选择你需要的正则表达式,随后可以使用第二个插件 正则表达式插入之后顶部会有 Test Regex.. 点击会出现以下内容 将他 ctrl a 删除,输入你对应的正则表达…

2023年中国油田工程建设市场规模现状及行业竞争分析[图]

油田工程建设是在确定油气田有开发生产的价值的基础上,进行系统的工程建设,油田工程建设包括井场建设、管道施工、土石方工程、道路建设及绿化等服务。 油田工程建设主要内容 资料来源:共研产业咨询(共研网) 油田服务…

UniApp打包教程:使用HBuilder X和AppUploader完成原生App云打包和上架指南“

目录 uniapp进行打包 使用上架工具appuplode进行发包 1.登录appuploder软件 2.登陆开发者App Store后台 uniapp进行打包 在HBuilder X编辑器中打开需要打包的项目,然后点击上面菜单栏中 发行 > 原生App-云打包,对以下弹出的弹窗进行内容填写 填写完…

八股文面试day6

什么是代理?为什么要用动态代理? 代理模式大概意思是:为其他对象提供一个代理项或者是占位符,以控制对这个对象的访问 代理模式核心思想:创建一个代理对象,在客户端和目标对象之间的一个中介,…

Visual NLP:图像信息自动提取的未来

本文旨在以简单的方式解释 Visual NLP 的关键概念,让你了解 Visual NLP 的含义、它的用例是什么、如何使用它以及为什么它是构建自动提取管道的未来 。 NSDT在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在…

Mybatis-Plus3.0默认主键策略导致自动生成19位长度主键id的坑

码字不易,如果对您有用,求各位看官点赞关注~ 原创/朱季谦 目前的Mybatis-Plus版本是3.0,至于最新版本是否已经没有这个问题,后续再考虑研究。 某天检查一位离职同事写的代码,发现其对应表虽然设置了AUTO_INCREMENT自…

k8s部署的java服务查看连接nacos缓存的配置文件

一、问题描述 k8s部署的java服务,使用nacos中的配置文件,需要在缓存中查看该服务具体是使用到了哪些配置文件 二、解决 参考文档: https://nacos.io/zh-cn/docs/system-configurations.html 文档描述如下: 进入java服务容器进入用户目录下的nacos&a…

csapp archlab part 1

part A [rootedb3963640a6 misc]#./yas sum.ys [rootedb3963640a6 misc]# ./yis sum.yo./yas 和 ./yis 是汇编语言编译器和模拟器的命令行工具。 ./yas 是一个汇编语言编译器,它将汇编语言代码转换为可执行的二进制文件。./yas sum.ys 将sum.ys文件编译成了sum.yo可…

C++电脑组装项目(涉及知识点:多态,虚析构,使用父类指针和new关键字实例化子类时无法调用子类的析构函数,类的头文件和类的cpp文件的使用,父类中调用子类的析构函数)

一.电脑组装项目各文件的关系和cpp文件目录 二.使用父类指针和new关键字实例化子类时无法调用子类的析构函数 即使用如下代码,不会调用IntelCpu的析构函数。导致无法释放子类申请的空间。 AbstractCpu* cpu new IntelCpu; delete cpu;完整代码如下: …
最新文章