关于Gpt测不准问题
-
Gpt有两个通道:
TRM0-CH0: 无限循环,自由计数
TRM0-Ch1; 设置为50ms一次中断。测试方案:
用通道0检测通道1中断的准确性。软件平台:
threadx做os,官方例程修改// 点灯线程 void App_Led2(ULONG thread_input) { while (1){ Dio_FlipChannel(DioConf_DioChannel_D18_PTA20); /* toggle D18 */ tx_thread_sleep(100); } } // 通道1中断通知 void Gpt_Tmr1Ch1Notification(void) { debug_time[2] = Gpt_GetTimeElapsed(0)/50; // 读计数值转为us Gpt_StopTimer(0); Gpt_StartTimer(0, 0xffffffff); // 重启定时器 } // 定时器初始化 // 通道0:通用计数,不产生中断 Gpt_StartTimer(0, 0xffffffff); // 通道1:50ms定时 Gpt_StartTimer(1, 50*50000U); // 定时周期=50ms(定时器时钟=50M) Gpt_EnableNotification(1); // 使能定时器中断
问题描述:
如果线程中的tx_thread_sleep(100)改为10即10ms时,测时很准就是50ms周期与设计相符;
但如果设为100ms,则显示的测量值会在35ms-65ms之间波动,但平均值应该还是50ms。这种现象肉眼可见,不知道咋回事。卡了一下午无果。 -
补充一点:通道0测线程周期是很稳定的没有异常。
感觉就好像不能在Gpt的一个通道中断函数中访问另一个通道一样。
通道1的实际中断周期似乎是准的,因为拿线程粗略评估过;但用通道0测不准 -
基本实锤,就是通道1定时器中断不准造成的。
同样计数方法:
线程1测试调度周期500ms很稳;
线程2堵塞,接收中断通知进行计数保证计数的实时性,结果还是周期忽上忽下。
所以现在怀疑是官方Gpt驱动有问题。 -
不是您说的这样。
1-线程1只是参考计时,500ms调度周期,测下来也是500ms,说明gpt通道0自由计数方法是对的,不存在理解上的偏差。
2-线程2消息堵塞,目的只是保证计数的实时性,不至于受限于线程调度周期(1ms)。这个消息是gpt通道2的中断触发的。 -
实测下来,50ms的中断周期,表现为35-65ms不等。所以让人很困惑。
而反测竞品的gpt驱动(基于EB的),没有这种现象。所以让人比较忧虑 -
问题终于锁定了!可喜可贺,复盘一下:
1 - 关闭OS,裸机跑(Mcal初始化后死循环),定时器中断周期是准的;但也发现复位后居然没有自动开狗。
2 - 开启OS,定时器中断周期不准,标准50ms,实测会在35ms-65ms浮动。
3 - 开OS后,某些情况下中断周期也是准的,比如改改app调度周期。原因分析:
1 - platform模块修改定时器中断优先级,从0开始测试,一路测试到14,问题都不存在了,也就是优先级不能为15;
2 - 把例程中已开启的其它外设的中断都关闭,Gpt模块中未使用的外设也关闭,只保留这一路定时器中断;同样满足步骤1现象,不能为15.
3 - 据此分析,想不通原因,希望官方还是核时一下吧。 -
之前用的nxp的rt1021配的,也是个M7
-
Gpt模块采用的tmr,ptmr,lptmr,rtc实现的,从外设的工作机制上来讲建议优先选择ptrm和lptmr来作为Gpt的硬件模块。OS的tick值可采用core带的system tick来实现,只是需要手写代码
-
yxydoctor 将工程压缩后,直接论坛里面回帖附件上传或者发到我邮箱enwei.hu@ytmicro.com
-
yxydoctor 收到你的工程后,我这边复现debug这个问题,root cause如下:
你工程中使用的ThreadX OS这个操作系统初始化时没有创建任何空闲任务(idle task),导致用户任务通过调用tx_thread_sleep()睡眠后,内核的PendSV_Handler中不清除自己的中断标志(因为没有ready的task需要执行),从而CPU长期执行任务切换检查的代码而不主动退出(仅在SysTick 1ms中断和APP1和APP2两个用户任务睡眠时间tineout后才退出)。如果这时候外设中断,比如本例中的pTMR_CH0的50ms定时中断的优先级与PendSV设置相同(都是15),那么跟PendSV相同优先级的外设中断ISR将很难被执行(仅退出PendSV_Handler时才可能)。
用户任务睡眠时间越长,这种现象越严重,这也与你反馈的,10ms睡眠时正常(我这边测试5ms,1ms, 50ms,甚至APP2 task中不睡眠都是OK的,因为pTMR_CH0的定时周期为50ms),而100ms不正常(测试500ms睡眠的话,测量的时间周期偏差更大)。
因此,解决方案有如下两种:
-
非常非常感谢,这是真正的专家。您看这样是否可行:
threadx本身并没有空闲任务这个不烦了。我这边保证所有需要中断的mcal外设中断优先级<15,即PendSV,这样可以么?
3/20
发帖前请查看
帮助没办法联网的电脑使用YCT
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...