大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦i.MX RT1xxx系列MCU的性能

  在前面的文章 i.MXRT1xxx微控制器概览 里,痞子衡给大家简介过恩智浦半导体在2017年推出的新一代跨界微控制器i.MX RT1xxx系列,该系列第一款芯片i.MXRT105x性能完爆同时期市面上所有的微控制器,官方公布的CoreMark跑分高达3020,有人可能不明白这个数字意味着什么,作为对比,我们再来看看意法半导体最流行的芯片STM32F103RB,它的CoreMark是108(此处应该有类似My God的尖叫),真是没有对比就没有伤害,那么i.MXRT105x性能到底有没有这么强?今天痞子衡为大家实测一下。

  关于CoreMark标准的基本知识,痞子衡之前专门写过一篇文章 微控制器CPU性能测试基准(EEMBC-CoreMark) ,本篇就是基于了解CoreMark基本知识之后的一次实践。来,让我们开始吧。

一、准备工作

1.1 硬件平台NXP i.MX RT1050 EVK

  要开始实测i.MXRT105x的CoreMark,首先你得有一块开发板,恩智浦官网上有i.MXRT105x配套的评估板,如下图所示,痞子衡今天用的就是这块板子,板载主芯片型号为iMXRT1052DVL6。

1.2 集成开发环境IAR EWARM

  ARM Cortex-M微控制器的集成开发环境有很多,其中IAR EWARM凭借优良的特性备受广大工程师青睐,且痞子衡在CoreMark标准基本知识介绍文章的最后贴出了一张iMXRT1050与STM32H743性能对比图,其中CoreMark跑分就是在IAR下得到的,所以今天痞子衡也选用IAR作为软件环境,具体版本为IAR EWARM v8.20.2。

1.3 官方软件开发包NXP MCUXpresso SDK

  在开始移植CoreMark程序到i.MXRT1052上之前,我们需要先有一个i.MXRT1052的基本hello world的例程,当然我们可以对着数据手册自己从头写一个,但是这里痞子衡推荐使用官方软件开发包。

  注册并登录恩智浦官网,来到 MCUXpresso SDK Builder 页面,在"Select Development Board"里选择EVKB-IMXRT1050后点击Build MCUXpresso SDK后跳转到下一个页面,在"Developer Environment Settings"里选择IAR并点击Download SDK后便可得到SDK_2.3.1_EVKB-IMXRT1050.zip,下面是痞子衡下载的开发包具体版本信息:

二、开始实测

2.1 跑通hello world

  给i.MXRT1050 EVK板子供电(J2口接5V输出的电源),并且使用USB线连接电脑与板子的J28 USB口,此时在设备管理器应该可以看到USB虚拟的串口(EVK板载OpenSDA调试器内含USB转串口功能,如果看不到串口,请自行安装PE Micro驱动)。

  打开前一步下载的开发包里的\SDK_2.3.1_EVKB-IMXRT1050\boards\evkbimxrt1050\demo_apps\hello_world\iar\hello_world.eww工程,确认工程option里linker文件选择的是MIMXRT1052xxxxx_ram.icf,然后J21 JTAG口连接上Jlink Plus直接将工程下载进主芯片的RAM运行。

  如果工程运行正常,你在串口调试助手(115200,8N1)里应该能看到"hello world."打印输出。

2.2 移植CoreMark程序

  以hello_world工程为基础,将从EEMBC官网下载到的coremark_v1.0.tgz包解压,将\coremark_v1.0\以及\coremark_v1.0\barebones\路径下的如下所有源文件(.c或.h)全部拷贝到hello world工程目录下

\coremark_v1.0
\barebones --移植到裸机下需要修改的文件
\core_portme.h -- 移植平台工程具体配置信息
\core_portme.c -- 计时以及板级初始化实现
\cvt.c
\ee_printf.c -- 打印函数串口发送实现
core_main.c --主程序入口
core_state.c --状态机控制子程序
core_list_join.c --列表操作子程序
core_matrix.c --矩阵运算子程序
core_util.c --CRC计算子程序
coremark.h --工程配置与数据结构定义

  将上面的所有coremark源文件全部添加进hello_world工程,并从工程中移除原主函数入口文件hello_world.c,此时基本coremark工程就完成了。但注意此时工程无法编译,因为从\coremark_v1.0\barebones\下拷贝的源文件还需要进一步修改。

2.2.1 板级初始化

  程序移植的第一步是实现板载初始化,编译上一步建好的coremark工程会报这样的错误error "Call board initialization routines in portable init (if needed), in particular initialize UART!\n"。其实这是coremark作者故意在core_portme.c里的portable_init()函数里留下的提示,我们需要用i.MXRT1052的板级初始化函数替代这个#error,打开之前移除的hello_world.c文件,将其中板级初始化函数调用拷贝到portable_init函数中:

void portable_init(core_portable *p, int *argc, char *argv[])
{
// 删除#error提示
//#error "Call board initialization routines in portable init (if needed), in particular initialize UART!\n" // 添加板级初始化调用
/* Init board hardware. */
BOARD_InitHardware();
//...
}

  原hello_world里的BOARD_InitHardware已经包含了系统时钟以及UART初始化,所以这里的移植工作就算结束了。

2.2.2 计时功能

  程序移植的第二步是实现计时功能,由于CoreMark得分其实是单位时间内跑了多少次CoreMark程序,所以CoreMark工程必须要有计时功能。编译coremark工程会报这样的错误error "You must implement a method to measure time in barebones_clock()! This function should return current time.\n",这也是coremark作者故意在core_portme.barebones_clock()函数里留下的提示。

  关于计时器,第一个想到的自然是Cortex-M内核里的SysTick,不过考虑到coremark程序是要跑在600MHz的主频下,而SysTick计时器只有24bit,也就是说即使SysTick->LOAD设最大的reload值0xFFFFFF,也将每隔0.02796s(0x1000000/600MHz)产生一次SysTick中断,而CoreMark程序至少要跑10s以上,在coremark运行的10s内会产生357次(10/0.02796)SysTick中断,这无疑会降低coremark得分,所以SysTick直接被pass。(备注:SysTick->CTRL[2]用于选择SysTick的时钟源,默认1'b0为Core Clock,1'b1为外部clock,暂未研究这里的外部clock在i.MXRT105x上是否能用)。

  翻看i.MXRT1052的参考手册,其支持的计时器种类很多,有GPT、PIT、TMR、WDOG,就选择比较常用的32bit计时器PIT吧。

  之前下载的软件包里也有PIT的例程\SDK_2.3.1_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\pit,打开pit.c文件将其中PIT初始化相关代码放入新定义的timer_pit_init()函数中并在portable_init()中调用timer_pit_init()一次以完成PIT初始化。

  barebones_clock()函数中的#error也需要被PIT_GetCurrentTimerCount()函数替换,此外还需要添加定义#define CLOCKS_PER_SEC (24000000),因为我们会在clock_config.c文件里的BOARD_BootClockRUN()函数最后添加如下语句以选择OSC作为PIT计时时钟,而EVK板载外部XTALOSC晶振是24MHz。

    /* Configure PIT divider */
CLOCK_SetMux(kCLOCK_PerclkMux, 1U); /* Set PERCLK_CLK source to OSC_CLK*/
CLOCK_SetDiv(kCLOCK_PerclkDiv, 0U); /* Set PERCLK_CLK divider to 1 */

  有朋友可能会好奇,我们似乎没有使能和实现PIT中断,其实在当前coremark工程下没有必要,因为PIT中断每隔178s(0x100000000/24MHz)才会触发一次,而我们只需要执行几十秒就够了,所以即使使能和实现PIT中断也用不到,当然如果能实现PIT中断更好,万一我们让coremark程序执行超过178s,不实现PIT中断就会导致计时出错。

#define CLOCKS_PER_SEC (24000000)

void timer_pit_init(void)
{
/* Structure of initialize PIT */
pit_config_t pitConfig;
PIT_GetDefaultConfig(&pitConfig);
/* Init pit module */
PIT_Init(PIT, &pitConfig);
/* Set max timer period for channel 0 */
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, (uint32_t)~0);
/* Start channel 0 */
PIT_StartTimer(PIT, kPIT_Chnl_0);
} CORETIMETYPE barebones_clock() {
// 删除#error提示
#error "You must implement a method to measure time in barebones_clock()! This function should return current time.\n" // 添加PIT计数值返回语句
return (~PIT_GetCurrentTimerCount(PIT, kPIT_Chnl_0));
} void portable_init(core_portable *p, int *argc, char *argv[])
{
// 删除#error提示
//#error "Call board initialization routines in portable init (if needed), in particular initialize UART!\n" // 添加板级初始化调用
/* Init board hardware. */
BOARD_InitHardware(); // 添加PIT计时器初始化调用
/* Init timer for microsecond function. */
timer_pit_init();
//...
}
2.2.3 串口打印功能

  程序移植的第三步是实现串口打印功能,由于hello_world工程已经包含串口打印功能,所以这里的修改比较简单。

void uart_send_char(char c) {
// 删除#error提示
//#error "You must implement the method uart_send_char to use this file!\n"; // 添加UART发送函数调用
if (c == '\n')
{
char tmp = '\r';
LPUART_WriteBlocking((LPUART_Type *)BOARD_DEBUG_UART_BASEADDR, (const uint8_t *)&tmp, 1);
}
LPUART_WriteBlocking((LPUART_Type *)BOARD_DEBUG_UART_BASEADDR, (const uint8_t *)&c, 1); //...
}

2.3 CoreMark参数配置

  2.2里只是将基本CoreMark功能移植完成,但此时coremark工程还是无法编译,因为还有一些CoreMark配置没有确定,都在coremark_portme.h里,需要重定义下面三个宏,并且IAR的优化选项也要设置如下图所示:

#define ITERATIONS (40000)
#define COMPILER_VERSION "IAR EWARM v8.20.2"
#define COMPILER_FLAGS "High - Speed - No size constraints"

2.4 输出CoreMark结果

  到这里CoreMark的移植工作就完全结束了,此时coremark工程也应该能正常编译了。为得到最高的CoreMark得分,最后需要再确定两件事:一、Core Clock是否确定配置为600MHz;二、工程代码段/数据段是否放在了ITCM/DTCM RAM。

  打开clock_config.c文件,查看BOARD_BootClockRUN()函数,ARM Core/AHB时钟确实都为600MHz。

void BOARD_BootClockRUN(void)
{
/* Boot ROM did initialize the XTAL, here we only sets external XTAL OSC freq */
CLOCK_SetXtalFreq(24000000U);
CLOCK_SetRtcXtalFreq(32768U); CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0x1); /* Set PERIPH_CLK2 MUX to OSC */
CLOCK_SetMux(kCLOCK_PeriphMux, 0x1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */ /* Setting the VDD_SOC to 1.5V. It is necessary to config AHB to 600Mhz */
DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x12); CLOCK_InitArmPll(&armPllConfig); /* Configure ARM PLL to 1200M */
CLOCK_SetDiv(kCLOCK_ArmDiv, 0x1); /* Set ARM PODF to 1, divide by 2 */
CLOCK_SetDiv(kCLOCK_AhbDiv, 0x0); /* Set AHB PODF to 0, divide by 1 */
CLOCK_SetDiv(kCLOCK_IpgDiv, 0x3); /* Set IPG PODF to 3, divede by 4 */ // ...
}

  再打开MIMXRT1052xxxxx_ram.icf文件,查看text段确实放在了ITCM里(0x0 - 0x7FFFF),data段确实放在了DTCM里(0x20000000 - 0x2007FFFF)。

define symbol m_interrupts_start       = 0x00000000;
define symbol m_interrupts_end = 0x000003FF; define symbol m_text_start = 0x00000400;
define symbol m_text_end = 0x0001FFFF; define symbol m_data_start = 0x20000000;
define symbol m_data_end = 0x2001FFFF;

  还等什么?将coremark工程赶紧下载进芯片并打开串口调试助手看CoreMark得分啊。痞子衡实测的CoreMark得分为2952,这与官方标称的3020有一点差距。

  对于coremark得分没上3000,痞子衡感到不服啊,那怎么提高coremark得分?痞子衡试尽方法(改编译器选项、调coremark配置)均无功而返,后来无意中看到EEMBC上跑出3036得分的IDE(编译器)是IAR 7.80,于是死马当活马医吧,痞子衡也在IAR 7.80.4上运行了一次,得到了3017分,原来这微小差异取决于编译器版本,真相大白。

  想偷懒的朋友直接移步痞子衡的github https://github.com/JayHeng/Cortex-M-Apps 去下载移植好的工程,工程在\Cortex-M-Apps\apps\coremark_imxrt1052\bsp\下面,build8202和build7804分别对应不同的IAR版本。

  至此,恩智浦i.MX RT1xxx系列MCU的CoreMark性能与实测痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

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

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

痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU特性那些事(2)- RT1052DVL6性能实测(CoreMark)的更多相关文章

  1. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU特性那些事(5)- 划时代新品RT1170

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的划时代新品i.MXRT1170. 自2017年开始,每年的6月25日恩智浦都会在北京举行微控制 ...

  2. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU特性那些事(1)- 概览

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的基本特性. ARM Cortex-M微控制器芯片厂商向来竞争激烈,具体可参看我的另一篇文章&l ...

  3. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性那些事(1)- 概览

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的基本特性. 恩智浦半导体于2017年开始推出的i.MX RT系列重新定义了MCU,其第一款芯片i. ...

  4. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(4)- OTP及其烧写方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的OTP. 在i.MXRTxxx启动系列第二篇文章 Boot配置(ISP Pin, OTP) 里痞子 ...

  5. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(1)- Boot简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的BootROM功能简介. 截止目前为止i.MX RTxxx系列已公布的芯片仅有一款i.MXRT60 ...

  6. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(2)- Boot配置(ISP_Pin, OTP)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的Boot配置. 在上一篇文章 Boot简介 里痞子衡为大家介绍了Boot基本原理以及i.MXRTx ...

  7. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU硬件那些事(1)- 官方EVK简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的配套EVK板. 半导体设计厂商发布任何一块MCU芯片新品,一般都会同步推出基于这款MCU的配套 ...

  8. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU启动那些事(1)- Boot简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的BootROM功能简介. 截止目前为止i.MX RTyyyy系列已公布的芯片有三款i.MXRT ...

  9. 痞子衡嵌入式:飞思卡尔i.MX RTyyyy系列MCU启动那些事(2)- Boot配置(BOOT Pin/eFUSE)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔i.MX RTyyyy系列MCU的Boot配置. 在上一篇文章 Boot简介 里痞子衡为大家介绍了Boot基本原理以及i.MXR ...

随机推荐

  1. [修仙之路]React-Redux 金丹篇

    作者:水涛追求技术,但又不失生活的乐趣,过自己想要的生活 React-Redux简介 React-Redux可以使你的React项目拥有全局数据,可以使多个React组件读取到全局数据并且组件中也可修 ...

  2. C# 使用自带Microsoft.Office.Interop.Excel简单操作Excel文件

    项目添加应用 Microsoft.Office.Interop.Excel.dll 文件 引用命名空间: using Excel = Microsoft.Office.Interop.Excel; 简 ...

  3. 五分钟了解ES6对数值的扩展

    文章目录 数值的扩展(ES6) 1. 二进制八进制表示法 2. Number对象 3. Math对象 4. 指数运算符 5. Integer 数据类型 5.1 简介 5.2 运算 数值的扩展(ES6) ...

  4. 解决苹果mac远程桌面无VDI客户端

    解决苹果mac远程桌面云aDesk无VDI客户端 因集团办公工作需要使用桌面云aDesk 在深信服官网并未有mac 的VDI Client客户端 mac电脑可通过Google浏览器访问VDI的服务器地 ...

  5. dotnetcore执行shell脚本

    我们可以使有dotnetcore跨平台的特性,优雅的实现在dotnetcore执行shell (bash).  代码如下: using System; using System.Collections ...

  6. BOM对象——Location

    BOM对象--location <!DOCTYPE html> <html> <head> <meta charset="utf-8"&g ...

  7. Xshell 连接 VirtualBox

    VirtualBox设置端口转发 Xshell 新建会话 连接成功

  8. 【linux命令】软连接和硬链接的区别(ln命令)

    Linux 文件系统把硬盘分为三个部分:超级块.inode 列表.数据区 inode 指示:该文件的数据存放在数据区的哪些块内.因为这个“映射”关系不能变更,因此,inode 相当于代表着文件本身.( ...

  9. 【zabbix监控】zabbix监控tomcat服务

    服务器配置(zabbix_server) 1. 安装jdk 版本需要1.7以上,我这边安装的是1.8的,可以参考我jdk安装的文章 # 上传到zabbix_server服务端.安装(jdk-8u171 ...

  10. 5分钟搞定Jenkis

    目录 什么是持续集成 Jenkins简介 Jenkins安装与启动 Jenkins插件安装 全局工具配置 自动安装 本地安装 代码上传至Git服务器 任务的创建与执行 Go项目 JAVA项目 @ 什么 ...