【前言】
在ST的论坛上看到许大佬给STM32H7S78用CoreMark测了个分,他用的是GCC的编译器给测的分,我今天使用mdk也给测试一下。
【软件环境】
1、stm32CubeMX 6.12。
2、MDK 3.59
3、CoreMark 1.0
【配置基础工程】
1、打开STM32CubeMAX,创建一个基于STM32H7S78-DK的基础工程,根据原理图,打开UART4,做为串口打印的输出。【注】在默认生成的配置中,需要修改PD1为UART4_RX,其他的为默认配置即可。
2、使能boot的sys的sysTick,
3、修改主频时钟为600M,选择HSE为主时种输入。
4、修改堆栈大小的0x2000,同时按文件生成工程:
生成工程后使用mdk打开工程。
5、往uart.c中添加stdio.h以及printf重定向的代码:
/* USER CODE BEGIN 1 */ /* ------------------????????printf???????????1??-------------------*/ #if !defined(__MICROLIB) //#pragma import(__use_no_semihosting) __asm (".global __use_no_semihostingnt"); void _sys_exit(int x) //??????e??????? { x = x; } //__use_no_semihosting was requested, but _ttywrch was void _ttywrch(int ch) { ch = ch; } //struct __FILE //{ // int handle; //}; FILE __stdout; #endif #if defined ( __GNUC__ ) && !defined (__clang__) #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif PUTCHAR_PROTOTYPE { /* ??????????????????????? */ //serial_write(&serial1, (uint8_t)ch); //????????????????????? HAL_UART_Transmit(&huart4, (uint8_t *)&ch, 1, 1000); return ch; } /* USER CODE END 1 */
【移植coremark】
1、下载CoreMark源码,链接为:CoreMark代码仓:https://github.com/eembc/coremark.git
2、下载后,把如下文件拷贝到工程目录下:
2、在mdk中添以上添加的文件,以及simple里所有.c添加进工程中,并添加头文件路径。
3、修改 core_portme.c 文件
core_portme.c文件中,需要修改的是计时的几个宏定义,具体如下:
// 注释(或者删除)原来的这三个宏定义 //#define CORETIMETYPE clock_t //#define GETMYTIME(_t) (*_t = clock()) //#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER) // 添加以下代码: #include "stm32h7rsxx_hal.h" #define CORETIMETYPE uint32_t #define GETMYTIME(_t) (*_t = HAL_GetTick()) #define EE_TICKS_PER_SEC (1000)
4、修改 core_portme.h 文件
core_portme.h文件,开头部分需要新增如下代码:
#define ITERATIONS 6400*5 // 这个值需要保证能够运行至少10秒,可以先写一个值,运行不足10秒会报错,再回来修改 #define FLAGS_STR "-Ofast" // 这个值根据实际的编译优化选项进行填写,在最终输出种原样输出,根据实际用的编译选项修改 #define MAIN_HAS_NOARGC 1 // coremark main不使用参数 #define MAIN_HAS_NORETURN 1 // coremark main不使用返回值
5、修改 core_main.c 文件
coremark源码的core_main.c中定义了main函数,CubeMX生成的main.c中也有main函数,直接编译会产生冲突,因此需要修改core_main.c文件,重命名其中的main函数,并在main.c中调用它。
在core_main.c中,找到main函数,并将其修改为core_main:
#if MAIN_HAS_NOARGC MAIN_RETURN_TYPE core_main(void) { int argc = 0; char *argv[1]; #else MAIN_RETURN_TYPE core_main(int argc, char *argv[]) { #endif
6、修改 main.c 文件
接下来,修改 main.c 文件,开头出添加:
/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "stdio.h" #include "coremark.h" /* USER CODE END Includes */
然后再添加开始跑分的代码:
/* USER CODE BEGIN 2 */ printf("working...rn"); core_main(); /* USER CODE END 2 */
【跑分结果】
[10:59:37.440]收←◆2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 71433 Total time (secs): 71.433000 Iterations/Sec : 447.972226 Iterations : 32000 Compiler version : GCCClang 16.0.0 Compiler flags : -Ofast Memory location : STACK seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0x988c Correct operation validated. See README.md for run and reporting rules. CoreMark 1.0 : 447.972226 / GCCClang 16.0.0 -Ofast / STACK coremask end
黙认跑分为447.分。
2、修改mdk的编译选项为-Ofast
测得结束如下:
[11:24:22.706]收←◆2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 11701 Total time (secs): 11.701000 Iterations/Sec : 2734.808991 Iterations : 32000 Compiler version : GCCClang 16.0.0 Compiler flags : -Ofast Memory location : STACK seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0x988c Correct operation validated. See README.md for run and reporting rules. CoreMark 1.0 : 2734.808991 / GCCClang 16.0.0 -Ofast / STACK coremask end
分值为2734.8091与官方的结束非常接近
【测试注意避坑】
1、堆栈不能太小,我设置为0x400都是报错。
2、如果时间太短,会提示ERROR! Must execute for at least 10 secs for a valid result!