F413中断重入错误【已解决】
本帖最后由 muyichuan2012 于 2020-8-31 09:11 编辑调试F413定时器遇到问题,程序只开了溢出中断,最开始每次溢出产生两次中断。
后来在中断函数退出前加 __DSB()指令可以恢复正常,或者在清中断标志后插入10条NOP指令也可以。
错误现象虽然消失,但问题的根源不清楚。 是CPU有BUG还是原本就是这样,这个解决办法是否可靠。
代码:
#define APP_TIM TMR4
#define app_timer_isrTMR4_GLOBAL_IRQHandler
#define APP_TIM_IRQn TMR4_GLOBAL_IRQn
/**
* @briefapp timer init
* @paramNone
* @retval None
*/
void app_timer_init(char pos)
{
RCC_ClockType RCC_Clocks;
RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_TMR4, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1PERIPH_TMR4, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1PERIPH_TMR4, DISABLE);
APP_TIM->CTRL1 = TMR_CTRL1_UVERS;
APP_TIM->CTRL2 = 0;
APP_TIM->DIE = TMR_DIE_UEVIE;
APP_TIM->STS = 0;
/*1ms 中断*/
RCC_GetClocksFreq(&RCC_Clocks);
APP_TIM->DIV = RCC_Clocks.APB1CLK_Freq / 1000000-1;
APP_TIM->AR = 2000-1;
NVIC_SetPriority(APP_TIM_IRQn, 0x01);
NVIC_ClearPendingIRQ(APP_TIM_IRQn);
NVIC_EnableIRQ(APP_TIM_IRQn);
APP_TIM->CTRL1 |= TMR_CTRL1_CNTEN;
}
OBJ_INIT_APP_EXPORT(app_timer_init);
/**
* @briefapp timer isr
* @paramNone
* @retval None
*/
void app_timer_isr(void)
{
if(APP_TIM->STS & TMR_STS_UEVIF)
{
sys_st.u_tick++;
}
else
{
sys_st.app_timer_err++;
}
APP_TIM->STS = 0;
__DSB();
}
应该是代码的问题,请再检查一下代码;或者可以用 BSP 所提供的库函数来操作,先单独验证一下你说的这个问题。 ArterySW 发表于 2020-8-26 16:55
应该是代码的问题,请再检查一下代码;或者可以用 BSP 所提供的库函数来操作,先单独验证一下你说的这个问 ...
上面贴的代码是完整的,这个问题已经反复验证了,不是偶尔出现,是必然出现。去掉_DSB,可以看到中断里面的两个计数值是相同的。 aple0807 发表于 2020-8-26 19:06
上面贴的代码是完整的,这个问题已经反复验证了,不是偶尔出现,是必然出现。去掉_DSB,可以看到中断里面 ...
我试了下你的代码,你是不是把TMR的时钟搞错了?TMR的时钟是挂在APB1上面,但是如果APB1有分频的话,那么 TMR_CLK = APB1_CLK * 2
RCC章节时钟树框图有具体描述:
所以,修改下面的代码:
APP_TIM->DIV = RCC_Clocks.APB1CLK_Freq / 1000000-1;为
APP_TIM->DIV = (RCC_Clocks.APB1CLK_Freq*2) / 1000000-1;即可。
感谢aple0807的反馈,目前我们已经复现了该问题,不过STM32F103也有该现象。
Anyway,等我们研发彻底理清后会给您一个满意的回复。 ArterySW 发表于 2020-8-27 10:00
我试了下你的代码,你是不是把TMR的时钟搞错了?TMR的时钟是挂在APB1上面,但是如果APB1有分频的话,那么 ...
我的重载值是2000, 上面就不需要乘2了 我可能知道答案。应该就是芯片BUG。
产生原因也清楚,也有解决方案, AT32没玩过。
APP_TIM->STS = 0;
这句是清除中断标志吧。
这句话并不能保证中断真正清除了,内核速度高于外设,不稍微延时一下,外设可能没反应过来,内核又检测到中断了。就出现了重复中断的现象
进入中断就立刻清标志位可以缓解。 muyichuan2012 发表于 2020-8-27 11:41
感谢aple0807的反馈,目前我们已经复现了该问题,不过STM32F103也有该现象。
Anyway,等我们研发彻底理清后 ...
不用等了,我猜对了记得发红包{:titter:} 七颗咖啡豆 发表于 2020-8-27 14:31
不用等了,我猜对了记得发红包
厉害,请问您是在什么芯片上发现的该问题? 七颗咖啡豆 发表于 2020-8-27 14:31
AT32没玩过。
APP_TIM->STS = 0;
这句是清除中断标志吧。
我这个中断里原本只有两行,就是TST=0;u_ticks++;是先清的的中断,因为出了问题才加了这么多程序来判定问题的。不过你说的有道理,我也怀疑是流水线的问题,才试了试_DSB(); muyichuan2012 发表于 2020-8-27 15:34
厉害,请问您是在什么芯片上发现的该问题?
STM32咯, 这个问题实际上是由于外设与内核之间指令传递和执行所导致的,具体的原因可以参考下面keil所提供的资料,以及提供的三种解决方法:
https://www.keil.com/support/docs/3928.htm 本帖最后由 muyichuan2012 于 2020-8-28 09:17 编辑
正如楼上所讲,ARM Keil也是确认到M3、 M4内核有该问题(如下图)。我们也实测了STM32F1xx,STM32F4xx的确存在该问题,看来的确是ARM内核的问题,芯片是没有问题的。
再次感谢aple0807提出该问题,以及七颗咖啡豆的精彩回答。
多谢各位答疑解惑,找到原因就放心了 ArterySW 发表于 2020-8-27 17:58
这个问题实际上是由于外设与内核之间指令传递和执行所导致的,具体的原因可以参考下面keil所提供的资料,以 ...
确实这样 这篇**学习到了很多知识,谢谢楼主的推荐
页:
[1]