当前位置: 首页 > ops >正文

FreeRTOS-中断管理

学习内容

中断概念

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

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

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

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

  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.xdnf.cn/news/16226.html

相关文章:

  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘streamlit’问题
  • 与 TRON (波场) 区块链进行交互的命令行工具 (CLI): tstroncli
  • ISAAC ROS 在Jetson Orin NX上的部署
  • Mkdocs相关插件推荐(原创+合作)
  • 目标导向的强化学习:问题定义与 HER 算法详解—强化学习(19)
  • 双非上岸985!专业课140分经验!信号与系统考研专业课140+上岸中南大学,通信考研小马哥
  • Zookeeper 3.6.3【详细技术讲解】整
  • Day 3: 机器学习进阶算法与集成学习
  • GPU服务器与PC 集群(PC农场):科技算力双子星
  • IPv6网络排障详细步骤指南(附工具命令+配置检查点+典型案例)
  • Jenkins中HTML文件显示样式问题解决方案
  • linux修改用户名和主目录及权限-linux029
  • 初识JVM--从Java文件到机器指令
  • 百度蜘蛛池解析机制:原创
  • 视频质量检测效率提升28%!陌讯多模态融合方案在流媒体场景的技术实践
  • Python之--集合
  • C#(数据类型)
  • 冠捷科技 | 内生外化,精准触达,实现数字化转型精准赋能
  • Matlab中的 for 与while是有区别的
  • geomtry空间索引sql查询慢优化
  • Android 的16 KB内存页设备需要硬件支持吗,还是只需要手机升级到Android15系统就可以
  • [python][基础]Flask 技术栈
  • 软件工程之可行性研究:从理论到实践的全面解析
  • JAVA知识点(四):SpringBoot与分布式、微服务架构
  • 腾讯云CodeBuddy+微信小程序:5分钟开发番茄小闹钟
  • ClickHouse 高性能实时分析数据库-物化视图篇
  • 【lucene】如何给StandardAnalyzer添加charfilter
  • P1106 删数问题 - 洛谷
  • Multiscale Structure Guided Diffusion for Image Deblurring 论文阅读
  • 用友ERP 反射xss漏洞复现(CVE-2025-2709)