简介

之前买的GD32F350G8U6在测试的时候发现超频性能不错,可以在8Mhz的晶振下PLL倍频43倍,超频到344Mhz(AHB不分频),遂尝试了一下移植跑分。由于这个型号没有CK_OUT引脚,所以可惜了。

CoreMark移植教程

eembc/coremark: CoreMark® is an industry-standard benchmark that measures the performance of central processing units (CPU) and embedded microcrontrollers (MCU). (github.com)

首先复制一份GD32的工程模板

然后加入coreMark的这几个文件:

coremark.h
core_util.c
core_state.c
core_matrix.c
core_main.c
core_list_join.c
simple/core_portme.c
simple/core_portme.h

同时把这两个路径都加入到包含路径中。

这其中core_main.c包含了main函数的入口,所以原来的main函数要去掉。

上面文件中,需要自己修改的就是simple文件夹下的两个文件。

Coremark的框架中,main函数内定义了一个函数用于初始化。

/* first call any initializations needed */
 portable_init(&(results[0].port), &argc, argv);

CoreMark默认使用栈内存实现数据的存储和计算,它会在main函数中定义一个2KB大小的数组。而在单片机的xxx_startup.s汇编启动文件中,对栈的容量限制为1KB,因此必须扩大栈容量,否则会进入HardFault。定到4K.

; <h> Stack Configuration
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>

;Stack_Size EQU 0x00000400
Stack_Size EQU 0x00001000

然后,配置输出方式。代码中默认定义ee_printf为printf。可以使用串口也可以使用其他方式比如SWO或者半主机模式semihosting,或者RTT。比如在embedded studio中,默认使用的printf是定向到了其专有的RTT,结果可以直接输出在终端,那这里就不用修改了。

如果是自己重定向,那么在core_portme.c中加入

/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    usart_data_transmit(USART1, (uint8_t)ch);
    while(RESET == usart_flag_get(USART1, USART_FLAG_TBE));
    return ch;
}

这里是使用了串口1,然后在portable_init()函数中加入串口1的配置函数即可。之前没看清对应的串口在这里卡了半天。。

适配SysTick

用于获取时间。

首先修改#define EE_TICKS_PER_SEC 1000 //每隔1ms中断一次,也就是1秒有1000个tick,当然这里1000是自己写的,只是一般这么干。

在中断服务函数的文件里面添加

//SysTick的中断函数
void SysTick_Handler(void)
{
    Tick++;
}

在SysTick.c添加(如果之前没复制这个文件就不需要,还是写到core_portme.c文件里面。

然后修改下面的启动计时和结束计时。

void start_time(void)
{
    //GETMYTIME(&start_time_val);
    Tick = 0;   //每次初始化时让tick数从0开始
    start_time_val = Tick;  //当前tick数保存到全局变量start_time_val 
    SysTick_Config(SystemCoreClock/1000); //配置并启动SysTick,这里配置Systick每隔1ms中断一次
}

//停止定时器并将stop_time_val设置为当前的定时器Tick数
void stop_time(void)
{
    //GETMYTIME(&stop_time_val);
    SysTick->CTRL = 0; //停止SysTick
    stop_time_val = Tick; //当前tick数保存到全局变量stop_time_val 
}

这里要注意SysTick_Config(SystemCoreClock/1000);中的SystemCoreClock要替换为自己的时钟频率,可以通过sysCK_freq = rcu_clock_freq_get(CK_SYS);来获取。之前一直没找到不同频率跑分都一样的原因。

配置

增加定义,用于定义运行迭代次数,需要让程序运行不低于10s。这里我开了344Mhz之后4500次得到的结果是10s多一点。

//#######################################
#define ITERATIONS 4500    /*定义迭代次数*/
//#######################################

main函数不带参数

#ifndef MAIN_HAS_NOARGC
#define MAIN_HAS_NOARGC 1  
#endif

修改编译器版本和编译参数

#define COMPILER_VERSION "Armcc v5.06"
#define COMPILER_FLAGS \
   "-O3 -Otime"

跑分结果

分别取了16Mhz、默认频率108Mhz,稳定最高频率320Mhz,我能超到的最高频率344Mhz

迭代次数依次为 19.273 、130.446 、386.631 、415.627

*********Working on 16 Mhz!*********
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 233492
Total time (secs): 233.492000
Iterations/Sec   : 19.272609
Iterations       : 4500
Compiler version : Armcc v5.06
Compiler flags   : -O3 -Otime
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 : 19.272609 / Armcc v5.06 -O3 -Otime / STACK


********Working on 108 Mhz!*********
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 34497
Total time (secs): 34.497000
Iterations/Sec   : 130.446126
Iterations       : 4500
Compiler version : Armcc v5.06
Compiler flags   : -O3 -Otime
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 : 130.446126 / Armcc v5.06 -O3 -Otime / STACK


*********Working on 320 Mhz!*********
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 11639
Total time (secs): 11.639000
Iterations/Sec   : 386.631154
Iterations       : 4500
Compiler version : Armcc v5.06
Compiler flags   : -O3 -Otime
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 : 386.631154 / Armcc v5.06 -O3 -Otime / STACK


*********Working on 344 Mhz!*********
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 10827
Total time (secs): 10.827000
Iterations/Sec   : 415.627598
Iterations       : 4500
Compiler version : Armcc v5.06
Compiler flags   : -O3 -Otime
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 : 415.627598 / Armcc v5.06 -O3 -Otime / STACK