野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 9325|回复: 4

求助!中断事件已发生但中断程序没有修改信号量

[复制链接]
发表于 2022-4-12 20:26:23 | 显示全部楼层 |阅读模式
板卡:野火stm32f103zet6核心板
场景一:利用uint64_t变量【sys_tick】+【微秒级TIM】获取一个64位微秒级时间戳
实现:TIM的时钟频率为1MHz,ARR为999,向上计数,每1ms触发一次中断,在中断里将【sys_tick】自加1000。每次获取当前时间戳时,返回【uint64_t变量 + TIM当前CNT值】
问题:出现过CNT已重新从0开始计数,但是【uint64_t变量】还没自加1000
复现手段:在main()创建一个static uint64_t变量【last_tick】,while(1)循环里,判断【last_tick】是否小于【sys_tick】,然后将【sys_tick】赋值给【last_tick】。debug会发现,会出现【sys_tick】小于【last_tick】的情况,且差值不超过ARR。推测是CNT重置但是中断还没修改【sys_tick】
可能的原因:CM3中断最快的响应时间也需要12个周期
可能的解决方法及结果:利用volatile修饰时间戳,问题依然复现;利用存储器屏障指令__DMB()与__DSB(),问题依然复现

场景二:利用循环接收DMA+翻页信号量【new_page_flag】实现数据帧的接收和解析,DMA的CNDTR寄存器提供接收的数据量
实现
  • 设置数据缓冲区data_buf[500],uart接收到的数据全部通过DMA放到这个缓冲区中,DMA每接收500byte产生一次中断
  • 在中断中对【new_page_flag】处理:if(0 == new_page_flag) {new_page_flag = 1}; else if (1 == new_page_flag) {new_page_flag = 2}
  • 数据处理任务以给定周期访问数据缓冲区,若new_page_flag为0则直接根据DMA的CNDTR判断接收的数据量,然后进行处理,若为1或2则读取没有被覆盖的数据
问题:CNDTR已重置但是new_page_flag没有改变
可能的原因:同上
可能的解决方法:同上

求助:似乎外设的寄存器+中断这种组合,会降低程序的稳定性,有没有大佬能提供下解决思路?谢谢了

回复

使用道具 举报

发表于 2022-4-13 09:49:57 | 显示全部楼层
截图具体程序部分看看
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-13 12:59:19 | 显示全部楼层
WishWish 发表于 2022-4-13 09:49
截图具体程序部分看看

我写了个简单的程序可以复现问题。全都在main函数里,只有几行代码,断点处也标明了。板子是野火stm32f103zet6核心板,直接用调试器debug就能看到问题

stm32f103zet6_template.zip

22.36 MB, 下载次数: 7

回复 支持 反对

使用道具 举报

发表于 2022-4-13 14:08:31 | 显示全部楼层
玮-QKYtpK 发表于 2022-4-13 12:59
我写了个简单的程序可以复现问题。全都在main函数里,只有几行代码,断点处也标明了。板子是野火stm32f10 ...

还是不明白什么意思 程序里面也没有sys_tick  
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-13 14:48:26 | 显示全部楼层
WishWish 发表于 2022-4-13 14:08
还是不明白什么意思 程序里面也没有sys_tick

就是now_tick。按参考手册的说法,TIM6的CNT从ARR变为0时会产生一个中断,在这个中断里我将now_tick+1000。但是实际上我遇到了CNT已经为0但是now_tick还没有加1000的情况
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 03:57 , Processed in 0.033392 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表