本篇测评目的是移植coremark,进行AT32F437跑分。
背景:在论坛看到有一位大佬,跑分有400多,另外一个其他论坛大佬,跑分700多,怎么相差这么多,同时本人也学习如何移植coremark跑分工具。
一、准备
1、AT32F437开发板一块;
2、下载好的coramark文件;可在下面链接下载
二、移植coremark
1、在project文件夹下,新建coremark文件夹;
2、打开下载好的coremark-main文件夹,复制如下文件到coremark文件夹下。
打开coremark-main
复制后的文件
3、在main.c里面添加定时器配置,主要用于产生1ms中断,为coremark提供时基,用于计算运行时间。
void tmr2_init(void) {
crm_clocks_freq_get(&crm_clocks_freq_struct);
/* tmr clock enable */
crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);
tmr_base_init(TMR2, 999, 287); //设置定时器1ms中断一次
tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
/* overflow interrupt enable */
tmr_interrupt_enable(TMR2, TMR_OVF_INT, TRUE);
/* tmr2 hall interrupt nvic init */
nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
nvic_irq_enable(TMR2_GLOBAL_IRQn, 1, 0);
/* tmr2 enable counter */
tmr_counter_enable(TMR2, TRUE);
}
void TMR2_GLOBAL_IRQHandler(void) {
if (tmr_flag_get(TMR2, TMR_OVF_FLAG) == SET) {
g_msTick++;
//printf("TMR2");
tmr_flag_clear(TMR2, TMR_OVF_FLAG);
}
}
4、修改core_portme.c文件
1)注释一些宏定义,并修改EE_TICKS_PER_SEC
// #define NSECS_PER_SEC CLOCKS_PER_SEC
// #define CORETIMETYPE clock_t
// #define GETMYTIME(_t) (*_t = clock())
// #define MYTIMEDIFF(fin, ini) ((fin) - (ini))
// #define TIMER_RES_DIVIDER 1
// #define SAMPLE_TIME_IMPLEMENTATION 1
// #define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER)
// /** Define Host specific (POSIX), or target specific global time variables. */
// static CORETIMETYPE start_time_val, stop_time_val;
#define EE_TICKS_PER_SEC 1000 //1s所代表的定时器计数累加值
2)重新计算时间的函数,主要便于coremark根据定时器的ms计数值计算当前程序运行时间
-void
-start_time(void)
+volatile uint32_t startTick = 0;
+volatile uint32_t endTick = 0;
+
+void start_time(void)
{
- GETMYTIME(&start_time_val);
+ startTick = g_msTick;
}
/* Function : stop_time
This function will be called right after ending the timed portion of the
@@ -83,31 +91,31 @@ start_time(void)
example code) or other system parameters - e.g. reading the current value of
cpu cycles counter.
*/
-void
-stop_time(void)
+void stop_time(void)
{
- GETMYTIME(&stop_time_val);
+ endTick = g_msTick;
}
+
/* Function : get_time
Return an abstract "ticks" number that signifies time on the system.
Actual value returned may be cpu cycles, milliseconds or any other
value, as long as it can be converted to seconds by <time_in_secs>. This
- methodology is taken to accomodate any hardware or simulated platform. The
+ methodology is taken to accommodate any hardware or simulated platform. The
sample implementation returns millisecs by default, and the resolution is
controlled by <TIMER_RES_DIVIDER>
*/
CORE_TICKS
get_time(void)
{
- CORE_TICKS elapsed
- = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
+ CORE_TICKS elapsed = (CORE_TICKS)(g_msTick - startTick);
return elapsed;
}
3)添加相关头文件和添加迭代次数宏
#include "at32f435_437_board.h"
#include "at32f435_437_clock.h"
#define ITERATIONS 10000 //定义宏 迭代次数 10s
4)添加系统时钟频率打印,用于显示时钟频率
extern crm_clocks_freq_type crm_clocks_freq_struct;
省略一些代码
ee_printf("CoreMark run on AT32F437ZMT7 @ %luHz\r\n", crm_clocks_freq_struct.sclk_freq);
5、修改core_portme.h文件
添加优化等级,修改为O3;这是系统要求定义优化等级
#ifndef COMPILER_FLAGS
#define COMPILER_FLAGS "-o3"/* "Please put compiler flags here (e.g. -o3)" */
#endif
6、修改core_main.c文化
因为coremark有自己的实现主函数,需要将main函数名修改为其他名字,避免冲突,同时在main函数里面调用coremark主函数。
@@ -110,9 +110,10 @@ main(void)
{
int argc = 0;
char *argv[1];
+}
#else
MAIN_RETURN_TYPE
-main(int argc, char *argv[])
+coremark_main(int argc, char *argv[]) //main修改为coremark_main
6、主函数里面添加测试代码
system_clock_config();
at32_board_init();
button_exint_init();
uart_print_init(115200);
tmr2_init();
printf("at32f437 VsCode demo!\r\n");
while(1)
{
coremark_main(0,0);
printf("\r\n\r\n");
at32_led_toggle(LED4);
delay_ms(1000);
}
7、将coremark的头文件和c文文件路径添加到Makefile和c_cpp_properties.json文件中,相应的文件能够编译到程序里面
C_SOURCES = \
./project/coremark/core_list_join.c \
./project/coremark/core_main.c \
./project/coremark/core_matrix.c \
./project/coremark/core_portme.c \
./project/coremark/core_state.c \
./project/coremark/core_util.c \
C_INCLUDES = \
-I./project/inc \
-I./project/coremark \
-I./project/board \
-I./libraries/cmsis/cm4/core_support \
-I./libraries/cmsis/cm4/device_support \
-I./libraries/drivers/inc
8、添加支持打印浮点数
由于gcc默认不支持打印float数,因此需要修改Makefile,支持float打印
# libraries
LIBS = -lc -lm -lnosys
LIBDIR =
LDFLAGS = $(MCU) -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections
LDFLAGS += -lc -lrdimon -u _printf_float //添加这一行支持浮点打印
三、跑分测试
1、使用Makefile默认优化等级
######################################
# building variables
######################################
# debug build?
DEBUG = 1
# optimization
OPT = -Og //默认优化等级
跑分结果为454分,和700多分有差距如下:
2、修改Makefile的优化等级为O3,跑分结果为715分
3、STM32跑分数据如下:
可以看出715分位于STM32U5与STM32H5系列之间。
4、总结
综上,可以看出,优化等级对于跑分有很大的影响,查询网络上的跑分优化等级,基本上是O3;
不过,可以看出,STM32跑分的分数是基于ARMClang V6.16以及使用IAR软件工具跑的,而IAR工具的优化等级有更高的等级,因此这也是跑分数据差异所在。
参考链接:
https://bbs.eeworld.com.cn/thread-1248436-1-1.html
https://www.21ic.com/evm/evaluate/MCU/933200.htm
(下载次数: 7, 2024-2-23 13:11 上传)