【学习日记】FreeRTOS+STM32Cubemx 移植正点原子外部中断问题总结
前言
在使用 STM32Cubemx 创建工程,使用正点原子的外部中断历程使出现程序卡死的问题,这里对这一问题进行总结。
STM32Cubemx 配置
首先对 STM32 进行一系类配置,包括时钟源、时钟树、debug、HAL 时基 (不要选择滴答定时器,滴答定时器留给FreeRTOS作为系统时钟) 等,配置完成后根据原理图对 GPIO 以及外部中断触发进行配置。
根据原理图,将 PB5、PE5 设置成推挽输出,不使用上下拉电阻,将 PE3、PE4 配置成 GPIO 中断,下降沿触发,上拉电阻,将 PA0 配置成上升沿触发、下拉电阻
接着在 NVIC 进行中断分组、优先级设置
移植驱动
这里我们添加正点原子的 EXTI 外部中断驱动,LED,KEY。
由于我们没有使用官方的 SYSTEM 文件,所以需要对程序以及头文件进行修改。
删除 SYSTEM 的头文件包含
引入 FreeRTOS 的相关头文件,将驱动文件里的所有延时换成 FreeRTOS 的延时 vTaskdelay
写代码测试移植是否成功。
开始任务中
c
1 | void StartDefaultTask(void *argument) |
烧录后出现问题,开始任务的LED灯运行,当中断触发时,程序发生卡死。
问题的原因
使用 debug 进行调试,在中断回调函数打断点
接着单步运行,最终发现程序卡在这

这个函数是关中断,但是没有返回值,也就是不管当前中断的状态,因此这个函数是不能在中断中调用的。
问题的解决
这个问题其实在韦东山老师的课程中说到过:
ISR 是在内核中被调用的,ISR 执行过程中,用户的任务无法执行。ISR 要尽量快,否则:
- 其他低优先级的中断无法被处理:实时性无法保证
- 用户任务无法被执行:系统显得很卡顿
对于这类非常耗时的中断处理就要分为 2 部分:
- ISR:尽快做些清理、记录工作,然后触发某个任务
- 任务:更复杂的事情放在任务中处理
这种处理方式叫” 中断的延迟处理”(Deferring interrupt processing)
- t1:任务 1 运行,任务 2 阻塞
- t2:发生中断
- 该中断的 ISR 函数被执行,任务 1 被打断
- ISR 函数要尽快能快速地运行,它做一些必要的操作 (比如清除中断),然后唤醒任务 2
- t3:在创建任务时设置任务 2 的优先级比任务 1 高 (这取决于设计者),所以 ISR 返回后,运行的是任务 2,它要完成中断的处理。任务 2 就被称为”deferred processing task”,中断的延迟处理任务。
- t4:任务 2 处理完中断后,进入阻塞态以等待下一个中断,任务 1 重新运行
- 解决方法 1:使用死延时
- 解决方法 2:不用延时
- 解决方法 3:在中断里设置事件组,通过事件组标志位唤醒任务
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 VAEF!
评论














