FreeRTOS学习(十三)——队列与中断
上一节学习了xQueueSend()和xQueueReceive()实现了两个任务之间的数据传递。实际STM32程序中很多数据并不是由任务主动产生而是来自按键中断、串口接收中断、定时器中断等。中断发生后我们通常希望快速记录数据然后交给任务完成后续处理。这一节学习如何在中断服务函数中使用FreeRTOS队列。一、中断中为什么不能直接使用xQueueSend()任务中可以这样发送队列xQueueSend( DataQueue, data, pdMS_TO_TICKS(100) );但是在中断服务函数中不能直接这样使用。原因很简单xQueueSend()可能因为队列已满而让当前任务进入阻塞态。而中断服务函数不是任务没有运行态 → 阻塞态这样的任务状态转换也不能在中断里面等待100ms。因此FreeRTOS专门提供了中断版本xQueueSendFromISR();带有FromISR后缀的函数就是专门给中断服务函数使用的接口。二、xQueueSendFromISR()函数可以简单理解为BaseType_t xQueueSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t *pxHigherPriorityTaskWoken );第一个参数xQueue表示队列句柄。第二个参数pvItemToQueue表示需要发送的数据地址。第三个参数pxHigherPriorityTaskWoken用于判断发送数据以后是否唤醒了一个优先级更高的任务。这个参数是中断中使用队列时需要重点理解的地方。三、创建一个按键消息队列首先定义QueueHandle_t KeyQueue;然后创建队列KeyQueue xQueueCreate( 5, sizeof(uint8_t) );这里创建一个长度为5的队列每条消息都是uint8_t类型。之后创建按键处理任务xTaskCreate( KeyTask, KeyTask, 128, NULL, 2, NULL );这个任务专门负责等待按键中断发送过来的数据。四、编写按键中断假设STM32F407的某个按键通过外部中断触发。中断服务函数可以写成void EXTI0_IRQHandler(void) { BaseType_t xHigherPriorityTaskWoken pdFALSE; uint8_t KeyValue 1; if(EXTI_GetITStatus(EXTI_Line0) ! RESET) { xQueueSendFromISR( KeyQueue, KeyValue, xHigherPriorityTaskWoken ); EXTI_ClearITPendingBit(EXTI_Line0); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } }按键触发以后进入EXTI中断 ↓ KeyValue 1 ↓ 发送到KeyQueue ↓ 退出中断这样中断只负责产生按键消息不负责执行复杂的按键处理程序。五、pxHigherPriorityTaskWoken是什么中断开始时先定义BaseType_t xHigherPriorityTaskWoken pdFALSE;假设此时KeyTask正在xQueueReceive();中等待按键数据因此处于阻塞态。按键中断发生后执行xQueueSendFromISR();队列中出现数据等待这个队列的KeyTask就可能从阻塞态变成就绪态如果被唤醒的任务优先级高于当前被中断的任务FreeRTOS会把xHigherPriorityTaskWoken设置为pdTRUE这说明现在已经有一个更高优先级的任务可以运行了。六、portYIELD_FROM_ISR()有什么用中断最后执行portYIELD_FROM_ISR(xHigherPriorityTaskWoken);如果xHigherPriorityTaskWoken pdTRUE那么退出中断以后就可以立即切换到刚刚被唤醒的高优先级任务。过程可以理解为普通任务运行 ↓ 按键中断发生 ↓ 发送队列数据 ↓ KeyTask被唤醒 ↓ 发现KeyTask优先级更高 ↓ 退出中断 ↓ 立即运行KeyTask这样就提高了系统响应速度。如果没有更高优先级任务被唤醒xHigherPriorityTaskWoken pdFALSE则不会因为这次操作产生额外的任务切换。七、按键处理任务任务中继续使用普通的xQueueReceive();例如void KeyTask(void *pvParameters) { uint8_t KeyValue; while(1) { if(xQueueReceive( KeyQueue, KeyValue, portMAX_DELAY ) pdPASS) { if(KeyValue 1) { GPIO_ToggleBits( GPIOE, GPIO_Pin_3 ); printf(Key Press\r\n); } } } }没有按键时KeyQueue为空 ↓ KeyTask阻塞不会一直查询按键。按键中断发生EXTI中断 ↓ xQueueSendFromISR() ↓ KeyQueue收到数据 ↓ KeyTask被唤醒 ↓ 处理按键这就是非常典型的中断产生事件任务处理事件。八、为什么不直接在中断里处理例如按键中断后需要printf();控制LED处理数据发送通信数据。如果全部放在中断服务函数中中断执行时间就会很长。这可能影响其他中断以及系统实时性。更合理的方法是中断 ↓ 快速获取数据 ↓ 发送队列 ↓ 退出中断 ↓ 任务处理复杂工作因此实际FreeRTOS工程中一般要求中断尽量短复杂处理交给任务。九、中断中使用队列的注意事项首先中断中不能使用普通xQueueSend();应该使用xQueueSendFromISR();类似地中断中还有xQueueReceiveFromISR();等专门的ISR接口。其次中断中不能使用vTaskDelay();因为中断不是任务不能进入阻塞态。最后使用FreeRTOS的FromISR接口时还需要正确配置STM32的NVIC中断优先级。并不是任意中断优先级都可以调用FreeRTOS API。关于FreeRTOS中断优先级和ISR安全API的具体规则后面学习中断安全API时再详细介绍。十、总结这一节学习了FreeRTOS队列在中断中的基本使用方法。任务中发送队列使用xQueueSend();中断中则使用xQueueSendFromISR();通过xHigherPriorityTaskWoken和portYIELD_FROM_ISR()还可以在中断唤醒更高优先级任务后及时进行任务切换。实际工程中推荐采用中断快速获取数据 ↓ 队列 ↓ 任务完成复杂处理这种方式既能够发挥中断响应速度快的特点又能避免在中断服务函数中执行大量耗时操作。

相关新闻

AI 处理本地文件,为什么不能只靠上传附件?

AI 处理本地文件,为什么不能只靠上传附件?

很多人已经习惯把文档上传给 AI,再让它总结内容。 处理一两个文件时,这种方式足够方便。但当任务涉及整个项目目录、多份表格或持续修改的资料时,反复上传附件很快就会变成新的负担。 上传附件适合一次性问答 例如: 总结这份 …

2026/10/15 6:20:42 阅读更多 →
基于QT与C++的中国象棋游戏开发实战:从MVC架构到AI算法

基于QT与C++的中国象棋游戏开发实战:从MVC架构到AI算法

1. 项目概述:为什么选择QT与C来复刻中国象棋?如果你对桌面应用开发感兴趣,或者想找一个能串联起C面向对象编程、图形界面设计和游戏逻辑的实战项目,那么用QT和C来开发一个中国象棋游戏,绝对是一个“黄金级”的练手选择…

2026/10/11 22:20:55 阅读更多 →
Unity InputSystem 从入门到精通:告别旧版输入系统,掌握现代化输入处理

Unity InputSystem 从入门到精通:告别旧版输入系统,掌握现代化输入处理

1. 项目概述:为什么是时候拥抱InputSystem了?如果你还在Unity项目里用着那个老旧的InputManager,每次处理复杂输入组合(比如“冲刺跳跃切换武器”)时,都得写一堆Input.GetKeyDown和状态管理代码&#xff0c…

2026/10/16 1:04:31 阅读更多 →

最新新闻

酉空间核心解析:内积、埃尔米特矩阵与酉对角化

酉空间核心解析:内积、埃尔米特矩阵与酉对角化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:46:24 阅读更多 →
基于MP2642与PIC18F4620的2S电池主动均衡模块设计

基于MP2642与PIC18F4620的2S电池主动均衡模块设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:46:24 阅读更多 →
PC化安灯系统:从异常触发到看板报警的完整实现

PC化安灯系统:从异常触发到看板报警的完整实现

在产线上待过的人都懂,安灯系统看着简单,真正用起来却有不少门道。传统的安灯靠拉绳、按按钮盒触发,工位一多,线缆布线就是一笔不小的开销,改一下工位布局更是牵一发动全身。很多工厂在精益改造中提出了新需求&#xf…

2026/10/16 4:46:24 阅读更多 →
React表单开发实战:从受控组件到状态管理、校验与性能优化

React表单开发实战:从受控组件到状态管理、校验与性能优化

1. 从HTML表单到React表单&#xff1a;核心思维转变React里的表单&#xff0c;表面上看就是把<input>、<textarea>、<select>这些标签搬进组件里&#xff0c;但真正写起来才发现&#xff0c;它和传统的HTML表单完全是两套逻辑。你在原生HTML里习惯的那套“用…

2026/10/16 4:46:24 阅读更多 →
Python图片网格化分割:从原理到批量处理实战

Python图片网格化分割:从原理到批量处理实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 4:46:24 阅读更多 →
海南商业航天发射场:填补空白,撬动高频发射产业链

海南商业航天发射场:填补空白,撬动高频发射产业链

这两年搞商业航天的团队越来越多&#xff0c;但不少火箭造出来了&#xff0c;真正卡住他们的往往不是技术&#xff0c;而是一个很现实的问题——去哪儿发射。海南商业航天发射场就是冲着这个空白去的&#xff1a;它是国内第一个专门为商业火箭搭建的发射阵地&#xff0c;定位就…

2026/10/16 4:45:24 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课&#xff0c;其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置&#xff0c;通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测&#xff0c;本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章&#xff0c;跟着敲完了投票应用&#xff0c;大概会有一种"我好像会了&#xff0c;又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型&#xff0c;下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介&#xff1a;基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码&#xff0c;面向计算机相关专业课程设计与期末大作业学生&#xff0c;以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程&#xff0c;…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程&#xff1a;键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化&#xff0c;十个新手有八个栽在"往输入框里填东西"这件事上&#xff1a;要么填不进去&#xff0c;要么填了一半&#xff0c;要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程&#xff1a;阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀&#xff1a;什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面&#xff0c;跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →