大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是i.MXRT定时器PIT的多通道链接模式及其在coremark测试里的应用

  早在 2018 年 i.MXRT 系列跨界处理器刚推出的时候,痞子衡就写了一篇 《i.MXRT1052性能实测(CoreMark)》,文章详细介绍了在 i.MXRT 上如何一步一步地移植标准 coremark 程序,这篇文章阅读量还不错,据说很多人移植 coremark 都是看得这篇文章。

  当时痞子衡把移植好的 coremark 工程也一起开源了出来,并且这个仓库痞子衡也是在不断维护的(增加新 MCU 型号支持,以及除了 coremark 之外的一些其他经典程序)。最近有同事向痞子衡反映,这个 coremark 测试工程里关于计时部分有一些可以改进的地方,痞子衡看了一下,确实可以改进,这便是今天本文要聊的主题:

一、i.MXRT上的定时器简介

  工欲善其事,必先利其器。在改进 coremark 测试工程里计时功能之前,我们先来了解一下 i.MXRT 上都有哪些跟计时/计数相关的模块,分别是什么特点,下面是详细列表。单从计时功能角度考虑,SysTick、GPT、PIT、TMR 都是不错的选择。

定时器 基本特性 应用特色
SysTick 24bit 计数器 系统(内核)时钟节拍
GPT 32bit 计数器 计时,外部信号捕获,比较
PIT 32bit 计数器 x 4 ch(可级联) 系统生命周期计时,触发DMA
TMR 16bit 计数器 x 4 ch(可级联) 混合功能:计时,信号捕获,正交解码
eFlexPWM 16bit 计数器 x 6 ch PWM信号生成
QDC 16bit,32bit - 5 ch 连接位置/速度传感器,正交解码
WDOG 给定时间选项/16bit 系统复位

二、计时设计对coremark测试程序影响

  我们知道 coremark 标准的测试逻辑是在某配置参数组合下单位时间内跑了多少次 coremark 程序,一般情况下要求至少跑 10s 以上,因此计时部分的设计是很重要的。

  在早期 i.MXRT1050 coremark 工程里,痞子衡选用了 PIT(channel 0 - 32bit)负责计时,为 PIT 配置的时钟源是 24MHz 外部 OSC,定时器一次超时耗时约 178s,这种情况下,痞子衡也没有使能 PIT 中断,假定了一次 coremark 程序跑完不会碰到超时的情况,但显然这种设计是不完善的。

  此外我们知道定时器时钟源频率越高,计时粒度越细,计时时间也就越精确。大部分定时器时钟源都可以配到系统 IPG bus 总线频率(在 i.MXRT10xx 上可到 125MHz/150MHz,在 i.MXRT1170 上可到 240MHz),我们可以尝试将定时器设到最高频率的时钟源,这时候就不得不考虑定时器超时中断处理问题了。

  使能定时器超时中断,可以保证计时的严谨性,解决了 coremark 程序运行时间和次数的限制。但是频繁的定时器中断响应也会不断打断 coremark 程序的执行,对最终跑分结果产生不利影响,这个问题同样需要解决。

三、PIT定时器多通道链接模式

  前面说了 SysTick、GPT、PIT、TMR 都可以用作 coremark 测试工程定时器,但最终痞子衡还是选定了 PIT,因为 PIT 是最适合作为系统运行生命周期总计时器的,这主要得益于 PIT 内部有 4 个 32bit 计时器,并且可以链接使用(串连)。

  要是将 4 个 32bit 计数器串成一个 128bit 超强计数器(channel 0 计数溢出,channel 1 计数加 1...),即使系统运行到地老天荒都不会出现一次超时(这里指最后一链 channel 3 中断触发),所以也就根本不用管定时器中断处理的事。

  PIT 通道链接模式使能也很简单,主要在 PIT->CHANNEL[x].TCTRL[CHN] 位上,这个位开启后,channel x 就和 channel x-1 连了起来。下面是 channel 0 和 channel 1 串连组成 64bit 计数器的初始化代码:

void timer_pit_init(void)
{
// Turn on PIT: MDIS = 0, FRZ = 0
PIT->MCR = 0x00; // Set up timer 1 to max value
PIT->CHANNEL[1].LDVAL = 0xFFFFFFFF; // setup timer 1 for maximum counting period
PIT->CHANNEL[1].TCTRL = 0; // Disable timer 1 interrupts
PIT->CHANNEL[1].TFLG = 1; // clear the timer 1 flag
PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_CHN_MASK; // chain timer 1 to timer 0
PIT->CHANNEL[1].TCTRL |= PIT_TCTRL_TEN_MASK; // start timer 1 // Set up timer 0 to max value
PIT->CHANNEL[0].LDVAL = 0xFFFFFFFF; // setup timer 0 for maximum counting period
PIT->CHANNEL[0].TFLG = 1; // clear the timer 0 flag
PIT->CHANNEL[0].TCTRL = PIT_TCTRL_TEN_MASK; // start timer 0
}

  实际上我们也根本不需要 128bit 计数器,64bit 计数器就完全够用了,就以 150MHz 时钟源来说,超时一次需要约 3899 年,谁需要操心 3899 年后的事情呢?此外,在 channel 0 和 channel 1 串联的情况下,PIT 还提供了一个 64bit lifetime 计数器,直接读这个计数器就能获取当前 channel 0,1 串连的计数值,不用考虑手动读 channel 0,1 计数值可能会发生的潜在翻转问题(rollover)。

  你看,使能了 PIT 通道链接用法后就完美地解决了 coremark 测试程序计时设计问题。

uint64_t timer_pit_get_ticks() {
uint64_t valueH;
volatile uint32_t valueL; #if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && (FSL_FEATURE_PIT_HAS_LIFETIME_TIMER == 1)
valueH = PIT->LTMR64H;
valueL = PIT->LTMR64L;
#else
do
{
valueL = PIT->CHANNEL[0].CVAL;
valueH = PIT->CHANNEL[1].CVAL;
} while (valueL < PIT->CHANNEL[0].CVAL);
#endif // FSL_FEATURE_PIT_HAS_LIFETIME_TIMER return ~((valueH << 32) | valueL);
}

四、关于coremark上计时的其他改进点

  最后再提两个 coremark 测试程序设计小改进点,一是在一些双核型号上(比如 i.MXRT1170, CM7 和 CM4),如果两个核同时跑 coremark 程序要用到不同 PIT 的话,需要检查它们是不是共用一个时钟开关,防止出现 CM7 上跑完了 coremark 之后关掉 PIT,影响 CM4 那边 coremark 程序对 PIT 寄存器的访问。

  第二个改进点是 core_main.c 里的 main() 函数在打印 Total ticks 时会将 u64 型的 total_time 变量强制转为 u32 型,以便于 %lu 格式化输出(32位无符号整数),这里最好还是保留原来 u64 精度,痞子衡尝试了 %llu 格式化输出(64位无符号整数),结果在 ee_printf() 下不生效,所以做了个如下手动转换版:

MAIN_RETURN_TYPE main(void) {
// 代码省略...
uint64_t total_time; total_time=get_time(); //ee_printf("Total ticks : %lu\n",(ee_u32)total_time);
if (total_time & (~(uint64_t)0xFFFFFFFF))
{
ee_printf("Total ticks : ");
ee_printf("%lu", (ee_u32)(total_time / 1000000000));
ee_printf("%lu\n",(ee_u32)(total_time % 1000000000));
}
else
{
ee_printf("Total ticks : %lu\n",(ee_u32)total_time);
} // 代码省略...
}

  至此,i.MXRT定时器PIT的多通道链接模式及其在coremark测试里的应用痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页知乎主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:介绍i.MXRT定时器PIT的多通道链接模式及其在coremark测试工程里的应用的更多相关文章

  1. 痞子衡嵌入式:i.MXRT中FlexSPI外设对AHB Burst Read特性的支持

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是FlexSPI外设对AHB Burst Read特性的支持. 痞子衡之前写过一篇关于FlexSPI LUT的文章 <从头开始认识i ...

  2. 痞子衡嵌入式:串行NOR Flash的Continuous read模式下软复位后i.MXRT无法启动问题解决方案之RESET#

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT上使能NOR Flash的Continuous read模式在软复位后无法正常启动问题的解决经验. 前一篇文章 <在i ...

  3. 痞子衡嵌入式:i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中不支持DQS的FlexSPI引脚组连接Flash下载与启动注意事项. 最近痞子衡在支持一个印度客户,这个客户项目主芯片选择 ...

  4. 痞子衡嵌入式:i.MXRT全系列下FlexSPI外设AHB Master ID定义与AHB RX Buffer指定的异同

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT全系列下FlexSPI外设AHB Master ID定义与AHB RX Buffer指定的异同. 因为 i.MXRT 全系列 ...

  5. 痞子衡嵌入式:i.MXRT连接特殊Octal Flash时(OPI DTR模式下反转字节序)下载与启动注意事项(以MX25UM51245为例)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是OPI DTR模式下反转字节序的Octal Flash在i.MXRT下载与启动注意事项. 在恩智浦官方参考设计板 MIMXRT595-E ...

  6. 痞子衡嵌入式:i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT中FlexSPI外设不常用的读选通采样时钟源 - loopbackFromSckPad. 最近碰到一个客户,他们在 i.MX ...

  7. 痞子衡嵌入式:串行NOR Flash的页编程模式对于量产时间的影响

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是串行NOR Flash的页编程模式对于量产时间的影响. 任何嵌入式产品最终都绕不开量产效率话题,尤其是对于主控是非内置 Flash 型 ...

  8. 痞子衡嵌入式:IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link / CMSIS-DAP)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致. 做Cortex-M内核MCU嵌入式软件开发,可用的集成开发环境( ...

  9. 痞子衡嵌入式:Keil在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致(J-Link/DAPLink)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是Keil在线调试时设不同复位类型可能会导致i.MXRT下调试现象不一致. 本篇是 <IAR EWARM复位类型>.<M ...

随机推荐

  1. 包装类integer的常用方法

    三种类型互转 (一): String 转换成 int 类型  调用 八大封装类 parseInt方法 结果可见 输出了223 成功转型 (二): int 转换成 String:  调用String类的 ...

  2. springboot启动过程中常用的回调

    1.介绍 springboot提供非常丰富回调接口,利用这些接口可以做非常多的事情,对于一些常用的回调接口进行介绍 2.常用的拓展接口 1.ApplicationContextInitializer ...

  3. 灵雀云入选Gartner 2020中国ICT技术成熟度曲线报告,容器技术处于顶峰

    近日,全球权威咨询分析机构Gartner发布了"2020中国ICT技术成熟度曲线(Hype Cycle for ICT in China, 2020 )"报告,灵雀云作为国内容器和 ...

  4. 带你自定义实现Spring事件驱动模型

    Spring 事件驱动模型概念 Spring 事件驱动模型就是观察者模式很经典的一个应用,我们可以通过Spring 事件驱动模型来完成代码的解耦. 三角色 Spring 事件驱动模型或者说观察者模式需 ...

  5. ELF文件格式学习总结

    ELF文件格式学习总结 ELF文件格式学习总结1. 概述2. 目标文件结构3. ELF文件头3.1 魔数3.2 文件类型3.3 机器类型4. ELF文件内容4.1段表4.2字符串表(.**strtab ...

  6. seq2seq+torch7聊天机器人bug处理

    [C]: in function 'error' ...root1/torch/install/share/lua/5.2/rnn/recursiveUtils.lua:44: in function ...

  7. 第57篇-profile实例

    之前已经介绍过回边计数和ProfileData与Layout,下面举个具体的例子看下MethodData是怎么利用ProfileData等记录详细的运行时信息的.实例如下: package com.t ...

  8. 从SQL Server数据库导出SQL语句

    不同于直接 备份/恢复 或者 导入/导出 数据库操作. 新版本SQL Server客户端中还可以生成相对应的SQL语句. 非常方便与查看和与其他人共享. 连接上数据库后, 右击数据库, 选择 Gene ...

  9. c#操作符详解

    操作符概览 操作符(Operator)也译为"运算符" 操作符是用来操作数据的,被操作符操作的数据称为操作数(Operand) 操作符的本质 操作符的本质是函数(即算法)的&quo ...

  10. golang反射reflect机制用法

    package main import ( "fmt" "reflect" ) type User struct { Id int Name string Ag ...