You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何TIM2中断会导致STM32L4上的ARM CMSIS DSP函数执行异常?

问题描述

我写了一个做数据数学运算的简单函数,原本运行完全正常,但启用TIM2中断后,这个函数始终执行不完,程序卡在某个ARM CMSIS DSP函数里。用调试器暂停时,光标停在中断服务程序(ISR)中,而且Keil调试器没法在部分位置设置断点。

  • TIM2中断频率10000Hz
  • 目标函数预计耗时约5ms
  • 使用的MCU是STM32L431RCT6

如果在执行函数前关闭中断,一切正常,但重新开启中断时会触发HardFault。相关函数代码如下:

void FFTW(void)
{
    float32_t windowed[SAMPLES]= {0};
    arm_mult_f32 (signal_input, (float32_t*)WINDOW_PARAMS, windowed, SAMPLES);
    memcpy(signal_input, windowed, 4 * SAMPLES);

    arm_rfft_fast_init_f32(&fft_handler, SAMPLES);
    arm_rfft_fast_f32(&fft_handler, (float32_t*)signal_input, Output, 0);
    arm_cmplx_mag_f32(Output, Output, FFT_SIZE);
}

想请教:ARM官方CMSIS DSP库的函数是不是不能被中断?还是问题出在别的地方?

分析与解决建议

CMSIS-DSP库的函数本身支持被中断打断,问题不在于库函数本身,而是你的使用方式和中断配置存在以下几个问题:

  • 中断频率与函数执行时间的冲突:TIM2每100μs触发一次中断,而你的FFTW函数要跑5ms,期间会被中断抢占50次。如果ISR里的操作耗时较长,会频繁打断主程序的FFTW执行,导致函数看起来“卡住”——实际上是一直在处理中断,调试器暂停时自然停在ISR中。同时频繁的上下文切换也会额外消耗CPU时间,进一步拖慢主程序。

  • 重复调用FFT初始化函数:arm_rfft_fast_init_f32是用来初始化FFT上下文结构体fft_handler的,这个函数只需要在程序启动时执行一次即可。你每次调用FFTW都重复执行初始化,不仅浪费时间,还可能在被中断打断时导致fft_handler的数据被破坏,引发异常。

  • 关中断后开中断触发HardFault的原因:关中断期间,10kHz的TIM2中断会积累大量未处理的请求,重新开中断时会瞬间触发大量中断,导致栈溢出或者上下文切换错误,进而触发HardFault。另外如果关中断的方式不正确(比如只关闭了TIM2中断,没处理全局中断的状态,或者恢复时寄存器操作有误)也会引发问题。

  • 断点无法设置的问题:Keil中部分位置不能设断点,大概率是编译器优化导致的(比如O2优化等级下,部分代码被内联、删减),或者中断上下文里的代码无法设置硬件断点。可以尝试把编译优化等级调低到O0,再进行调试。

针对这些问题,给出以下解决步骤:

  1. 将FFT初始化移到全局初始化代码中:把arm_rfft_fast_init_f32(&fft_handler, SAMPLES);放到main函数的初始化阶段,只执行一次,不要放在FFTW函数内。
  2. 优化TIM2的ISR:ISR里只做最必要的操作,比如设置一个标志位,主程序中轮询标志位再处理具体任务,尽量缩短ISR的执行时间。
  3. 合理控制中断优先级,而非直接关闭全局中断:如果需要FFTW执行时不被打断,不要直接关闭全局中断,而是用__set_BASEPRI()函数暂时屏蔽低于某个优先级的中断,执行完FFTW后再恢复BASEPRI寄存器的值。这样既保证FFTW的执行不被打断,又不会屏蔽所有高优先级中断。
  4. 检查栈空间大小:FFTW中的局部数组windowed[SAMPLES]会占用栈空间,如果SAMPLES数值较大(比如超过1024),加上频繁中断的栈开销,很容易导致栈溢出。需要在Keil工程配置中适当增大栈空间。
  5. 调试时关闭编译器优化:将编译优化等级设为O0,确保所有代码都能被调试器识别,方便设置断点定位问题。

内容的提问来源于stack exchange,提问作者ALOHA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:41:20