学习内容

中断概念

中断是计算机系统中一种重要的事件驱动机制,用于在特定条件下打断正在执行的程序,并跳转到预定义的中断处理程序中执行特定的操作。当发生中断时,处理器会立即中止当前正在执行的指令,保存当前的执行状态,并执行相应的中断处理程序。

中断可以由多种事件触发,例如硬件设备的状态改变、定时器溢出、外部信号等。常见的中断事件包括键盘输入、鼠标移动、网络数据到达等。

中断的作用是实现对实时事件的及时响应。通过中断,计算机系统能够在发生特定事件时立即中断当前任务,执行与该事件相关的处理程序,以确保及时处理和响应事件。中断能够提高系统的实时性、可靠性和可处理性。

中断的处理过程包括以下步骤:

  1. 中断触发:某个事件触发中断,如硬件设备发出中断请求信号。
  2. 中断响应:处理器检测到中断请求,并立即中止当前执行的指令。
  3. 保存现场:处理器保存当前的执行状态(如程序计数器、寄存器等),以便在中断处理完成后能够恢复执行。
  4. 中断服务程序执行:处理器跳转到预定义的中断服务程序(ISR),执行与中断相关的操作。
  5. 中断处理完成:中断服务程序执行完成后,处理器恢复之前保存的执行状态,并继续执行原来的程序。

通过合理使用中断,可以实现并发处理、异步事件处理和实时响应,提高系统的性能和可靠性。中断在各种计算机系统中广泛应用,包括嵌入式系统、操作系统和实时系统等。

 

ARM中的中断优先级

ARM Cortex-M 使用了 4 位宽的寄存器来配置中断的优先等级,这个寄存器就是中断优先级配置寄存器。

GD32中,分为抢占优先级和子优先级。(数值越小,优先级越高)

分组

抢占优先级

响应优先级

分组0

0(可取值为0)

4(可取值为0到15)

分组1

1(可取值为0到1)

3(可取值为0到7)

分组2

2(可取值为0到3)

2(可取值为0到3)

分组3

3(可取值为0到7)

1(可取值为0到1)

分组4

4(可取值为0到15)

0(可取值为0)

通常我们在代码中来进行配置:

nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);

全局中断的意思是,把全局的中断优先级大概定义到一个区间,具体到哪种类型的中断,自行去配置合适的优先级。因此,我们对于一些中断源可以通过以下代码来配置优先级:

nvic_irq_enable(xxx_irqn, 6, 0); // >= 5

上面中的全局中断配置,配置为抢占优先级为4,响应优先级为0,那么就把具体中断源的区间给框定了。抢占优先级取值介于0到15,响应优先级只能为0。因此,上面配置具体中断源优先级为5和0,在全局中断源的范畴内。当然你设置一个范围不在范畴内,是不生效,或者会出现其他问题。

通常在FreeRTOS配置外设的中断优先级都在5及以上 (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)

FreeRTOS的中断优先级

FreeRTOSConfig.h中,configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY配置了中断优先级:

#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5

默认位置为5。

在GD32中,优先级的数值越小,优先级越高。通过优先级分组可以知道,优先级分为0到15个等级。那么FreeRTOS中的这个优先级是什么含义呢?

开启中断和关闭中断:

portENABLE_INTERRUPTS();
portDISABLE_INTERRUPTS();

优先级配置注意

低于或等于configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 优先级的中断函数(数值越大,优先级越低),FreeRTOS的API函数才能对其生效。例如configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY为5,则中断函数配置的参数必须为[5, 15]的任意值。(所有优先级均为抢占优先级时)

 

中断优先级和任务优先级

示例

  1. 创建timer中断,每秒打印数据
  2. 创建任务,扫描按键事件
  3. 当按键按下,关闭所有中断,当按键再次按下,开启中断
  4. 观察效果

注意:vTaskDelay和delay_1ms的有区别

//main.c
#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"
#include "usart0.h"TaskHandle_t            start_handler;
TaskHandle_t            task_key_handler;void task_key(void *pvParameters) {uint32_t flag = 0;FlagStatus pre_state = RESET;while(1) {FlagStatus state = gpio_input_bit_get(GPIOA, GPIO_PIN_0);if(SET == state && pre_state == RESET) {// 当前高电平, 上一次为低电平,按下pre_state = state;if(flag == 0) {printf("disable \r\n");// 关闭中断portDISABLE_INTERRUPTS();} else if(flag == 1) {// 开启中断printf("enable \r\n");portENABLE_INTERRUPTS();}flag++;if(flag > 1) flag = 0;} else if(RESET == state && pre_state == SET) {// 当前高电平, 上一次为低电平,抬起pre_state = state;}delay_1ms(20);}
}void Usart0_recv(uint8_t *data, uint32_t len) {printf("recv: %s\r\n", data);
}static void GPIO_config() {// 时钟初始化rcu_periph_clock_enable(RCU_GPIOA);// 配置GPIO模式gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_0);
}#define PRESCALER	10000
#define FREQ	    1static void TIMER_config() {// 时钟配置rcu_periph_clock_enable(RCU_TIMER5);// 复位定时器timer_deinit(TIMER5);rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);timer_parameter_struct tps;timer_struct_para_init(&tps);tps.prescaler = PRESCALER - 1; // 分频系数  240 000 000tps.period = SystemCoreClock / PRESCALER / FREQ - 1; // 周期计数值 1Hztimer_init(TIMER5, &tps);nvic_irq_enable(TIMER5_DAC_IRQn, 5, 0);timer_interrupt_enable(TIMER5, TIMER_INT_UP);timer_enable(TIMER5);
}void TIMER5_DAC_IRQHandler(void) {if(SET == timer_interrupt_flag_get(TIMER5, TIMER_INT_UP)) {printf("timer\r\n");}//清除中断标志位timer_interrupt_flag_clear(TIMER5,TIMER_INT_FLAG_UP);
}void start_task(void *pvParameters) {GPIO_config();Usart0_init();TIMER_config();printf("start\r\n");taskENTER_CRITICAL();xTaskCreate(task_key, "task_key", 64, NULL, 2, &task_key_handler);vTaskDelete(start_handler);taskEXIT_CRITICAL();
}int main(void)
{nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);xTaskCreate(start_task, "start_task", 128, NULL, 1, &start_handler);vTaskStartScheduler();while(1) {}
}

 

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

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

相关文章

图像梯度处理与边缘检测

在图像处理的世界里&#xff0c;我们常常需要从复杂的像素矩阵中提取有意义的信息 —— 比如一张照片中物体的轮廓、医学影像中病灶的边界、自动驾驶视野里的道路边缘。这些 “边界” 或 “轮廓” 在专业术语中被称为 “边缘”&#xff0c;而捕捉边缘的核心技术&#xff0c;离不…

GPU服务器与PC 集群(PC农场):科技算力双子星

在数字经济高速发展的今天&#xff0c;算力已成为驱动科技创新与产业变革的核心引擎。GPU服务器凭借其强大的并行计算能力&#xff0c;在图形渲染、人工智能训练等领域展现出不可替代的优势&#xff1b;而PC集群则通过分布式架构&#xff0c;以高性价比和灵活扩展特性&#xff…

秋招Day19 - 分布式 - 分布式锁

单体时代&#xff0c;可以直接用本地锁来实现对竞争资源的加锁&#xff0c;分布式环境下就要用到分布式锁了有哪些分布式锁的实现方案&#xff1f;MySQL分布式锁、Zookeeper分布式锁、Redis分布式锁MySQL分布式锁如何实现&#xff1f;创建一张锁表&#xff0c;对字段定义唯一性…

AIStarter平台亮点解析:从ComfyUI项目上架到一键运行的完整指南

大家好&#xff01;今天分享一个AIStarter平台的深度体验&#xff0c;带你了解如何通过这个平台轻松上架和运行AI项目&#xff01;视频中&#xff0c;博主在凌晨分享了AIStarter的强大功能&#xff0c;重点展示了ComfyUI 4.0和5.0整合包的上架过程&#xff0c;以及如何简化AI项…

电脑录屏软件推荐:如何使用oCam录制游戏、教程视频

在工作、学习或游戏过程中&#xff0c;我们经常需要录制电脑屏幕&#xff0c;比如制作教程视频、记录游戏操作、分享软件使用过程等。oCam 是一款功能强大且操作简单的屏幕录制工具&#xff0c;支持 Windows 系统&#xff0c;深受用户喜爱。今天简鹿办公就来手把手教你如何使用…

安装cuml报错

安装命令 &#xff08;注意cuda的版本&#xff09; pip install --no-cache-dir --extra-index-urlhttps://pypi.nvidia.com cuml-cu11 报错&#xff1a; 找了很多网上的教程 1.版本问题 没解决 pip install --upgrade pip pip install --upgrade setuptools 2.参考下面博…

【ECharts✨】解决Vue 中 v-show 导致组件 ECharts 样式异常问题

解决Vue 中 v-show 导致组件 ECharts 样式异常问题 问题概述 在使用 Vue 的 v-show 指令实现 <PageOne/>、<PageTwo/>、<PageThree/> 三个视图的定时切换时&#xff0c;<PageTwo/> 显示时出现了异常&#xff0c;具体表现为 ECharts 图表渲染图表尺寸异…

旅游管理虚拟仿真实训室:重构实践教学新生态

在旅游产业数字化转型与教育信息化深度融合的背景下&#xff0c;旅游管理虚拟仿真实训室成为连接理论教学与行业实践的关键纽带。它通过沉浸式技术还原旅游场景&#xff0c;解决传统实训中资源受限、风险较高、时空局限等问题&#xff0c;为旅游管理专业人才培养提供全新路径。…

【在线五子棋对战】十、对战玩家匹配管理模块

文章目录前言Ⅰ. 匹配队列实现Ⅱ. 匹配队列管理类实现完整代码前言 五子棋对战的玩家匹配是根据自己的天梯分数进行匹配的&#xff0c;而服务器中将玩家天梯分数分为三个档次&#xff1a; 青铜&#xff1a;天梯分数小于 2000 分白银&#xff1a;天梯分数介于 2000~3000 分之间…

k8s之ingress定义https访问方式

接上文&#xff1a;https://blog.csdn.net/soso678/article/details/149607069?spm1001.2014.3001.5502定义后端应用与service [rootmaster ingress]# cat my-nginx.yml apiVersion: apps/v1 kind: Deployment metadata:name: my-nginx spec:selector:matchLabels:run: my-n…

《C++ vector 完全指南:vector的模拟实现》

《C vector 完全指南&#xff1a;vector的模拟实现》 文章目录《C vector 完全指南&#xff1a;vector的模拟实现》一、定义vector的成员变量二、用vector实现动态二维数组三、vector的接口实现1.vector的默认成员函数&#xff08;1&#xff09;构造函数实现&#xff08;2&…

腾讯云代码助手使用指南

腾讯云代码助手使用指南什么是腾讯云代码助手功能区展示功能介绍功能演示一、创建新项目1.先用Chat 把口语化的需求转换成AI更容易接受的结构化提示词2.再用Craft 模式进行代码生成3.成果展示二、老项目探索1.使用Codebase 帮理解项目代码三、代码补全1.只需输入标准的函数名&a…

【vue3+vue-pdf-embed】实现PDF+图片预览

【vue3vue-pdf-embed】实现PDF图片预览项目背景项目代码分析代码项目背景 技术栈&#xff1a;vue3Tselementplus 需要实现PDF和图片预览 图片预览很好解决了&#xff0c;可以用elementplus 自带的组件el-image 可实现 PDF预览可以用搜了一圈&#xff0c;有两个方案&#xff0c…

Leetcode力扣解题记录--第21题(合并链表)

题目链接&#xff1a;21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09; 题目描述 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&…

基于单片机的楼宇门禁系统的设计与实现

2、系统总体设计 2.1硬件的总体设计 为了使门禁系统智能化&#xff0c;需要一个主控芯片对整个门禁系统进行管理控制。接着还需要对应的模块完成包括数字密码验证和IC卡识别验证的功能。当出现非法闯入、验证失败等情况时还需要对操作人员进行警告。最后需要一个人机交互界面方…

全天候自动化数字型智能驱鸟装置,电网防鸟高科技

鸟类在输电线路铁塔、电线杆上筑巢、栖息和排泄是个大问题&#xff0c;很容易引发线路故障导致停电。为了保障电网安全稳定运行&#xff0c;会用到各种智能驱鸟装置来驱赶鸟类&#xff0c;避免涉鸟故障发生。例如全天候自动化数字型智能驱鸟装置&#xff0c;其厉害的地方在于它…

技术、生态与商业:从PC到移动的平台之争

在科技发展的漫长历史中&#xff0c;我们常常惊叹于那些改变世界的伟大技术。然而&#xff0c;深入探究会发现&#xff0c;单纯的技术领先并不能保证最终的胜利。从 PC 操作系统到移动终端&#xff0c;乃至服务器软件&#xff0c;那些最终笑傲江湖的巨头们都遵循着一个共同的法…

android JXL 导出Excel(.xls/xlsx)

前面使用过 POI 导出xlsx但是它体量比较大&#xff0c;功能较丰富&#xff0c;在一些对包size比较敏感并且导出需求相对简单的项目中就不太适合。 poi链接&#xff1a;Android 导入导出excel xls、xlsx_android excel导入导出-CSDN博客 jxl 包体积小&#xff0c;使用简单、AP…

mysql 的主从机制是怎么实现的?

MySQL 作为当前最流行的开源关系型数据库之一&#xff0c;为了满足数据的高可用、负载均衡和容灾备份等需求&#xff0c;广泛应用主从复制&#xff08;Replication&#xff09;机制。其核心思想是&#xff1a;在一台主库&#xff08;Master&#xff09;上发生的所有数据变更都会…

【PHP 函数从入门到精通】

&#x1f9e0; PHP 函数从入门到精通 PHP 函数是编程中最基础、也是最强大的工具之一。它不仅可以简化代码、提高复用性&#xff0c;还能通过各种高级用法&#xff0c;让你写出更灵活、更现代的代码。 下面我们从函数的基础讲起&#xff0c;逐步深入&#xff0c;带你掌握函数的…