本帖最后由 skylove1233 于 2023-3-21 00:38 编辑
#申请原创# @21小跑堂
本帖介绍了APM32F107 coremark的移植过程.
CoreMark是衡量嵌入式系统中微控制器性能的基准。通过包含列表处理(查找和排序)、矩阵处理(常见的矩阵操作)、状态机(确定输入流是否包含有效数字)和CRC(循环冗余校验)等算法的测试给出性能评价。很多MCU的数据手册中都会给出官方的coremark数值。
1.coremark下载
下载地址:https://github.com/eembc/coremark
下载解压后目录结构如下所示:
我们移植coremark只需要1和2部分的文件,其他文件不需要。
2.移植过程
coremark移植需要满足两个条件:
(1)定时器打开-->用于计时
(2)串口重定向打开-->用于查看结果
因此,在移植前我们先建立好工程,由于demo中已有串口相关的工程,我们直接打开工程:APM32F10x_SDK_V1.8\Examples\USART\USART_Interrupt\Project\MDK\
直接在此demo的基础上做修改:
demo目录结构如下:
(1)串口初始化并重定向
我们需要做的第1件事:串口初始化并重定向,直接在main.c中修改:
串口初始化:
void UsartInit()
{
USART_Config_T USART_ConfigStruct;
/*USART2*/
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_USART2);
USART_ConfigStruct.baudRate = 115200;
USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
USART_ConfigStruct.mode = USART_MODE_TX_RX;
USART_ConfigStruct.parity = USART_PARITY_NONE;
USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
APM_MINI_COMInit(COM2, &USART_ConfigStruct);
}
LED初始化:
void LEDInit()
{
APM_MINI_LEDInit(LED2);
APM_MINI_LEDInit(LED3);
}
串口重定向:
int fputc(int ch, FILE *f)
{
/* send a byte of data to the serial port */
USART_TxData(DEBUG_USART, (uint8_t)ch);
/* wait for the data to be send */
while (USART_ReadStatusFlag(DEBUG_USART, USART_FLAG_TXBE) == RESET);
return (ch);
}
新建函数后,要将声明在main.h中添加,并包含stdio.h:
void UsartInit();
void LEDInit();
(2)添加coremark代码
此处,主函数的部分操作完毕,接下来将coremark添加到项目中,将如下文件复制到project中的source目录:
并按如下操作,新建一个项目目录,coremark用于存除了simple目录下文件外其他的源文件,simple目录下的文件需要修改,放于application目录:
最终操作后结果如下图:
除此之外,还要做一些配置操作,如下图所示:
将新增的目录头文件包含进来,如下所示:
由于coreportme.c中有main函数,因此需要将main.c中的main注释掉,然后将usartinit,ledinit写到coreportme.c的main函数的portable_init函数中,如下所示:
void
portable_init(core_portable *p, int *argc, char *argv[])
{
(void)argc; // prevent unused warning
(void)argv; // prevent unused warning
/*init */
UsartInit();
LEDInit();
printf("coremark begin\n");
(3)解决编译报错
给此文件加上main.h,然后编译,会报两个错误:
错误1:
../../Source/cmk/simple\core_portme.h(80): note: expanded from macro 'COMPILER_FLAGS'
../../Source/cmk/core_main.c(413): error: use of undeclared identifier 'FLAGS_STR'
点击错误1,可看到此处代码:
由代码可知,此处要修改FLAGS_STR为编译选项,此处我们使用-ofast,修改为:
#ifndef COMPILER_FLAGS
#define COMPILER_FLAGS "-Ofast" \
//FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */
#endif
同时,编译选项中也做以下修改:
错误2:
../../Source/cmk/simple/core_portme.c(39): error: use of undeclared identifier 'ITERATIONS'
此处的ITERATIONS为算法迭代次数,由用户修改,此处我们做出定义:#define ITERATIONS 1000
再次编译,就不报错了。
(4)代码修改
除了上述修改外,还有注释掉一些不用的宏定义,如下所示:
(5)修改时钟的起始、停止、时间获取的三个函数
接着在main.h中引用tick全局变量:extern volatile unsigned int tick;
在apm32f10x_int.c的SysTick_Handler函数中,增加tick++
<div>void SysTick_Handler(void)</div><div>{</div><div>tick++;</div><div>}</div>
最后,再修改下堆栈大小:
(6)实际效果
代码down到板子上,连接到串口调试助手,结果如图所示:
从报错中可以看出,要求程序最少跑10s,我们迭代次数为1000时明显不满足条件,因此,调大迭代次数为3000,再跑一次,最终结果如下:
coremark分数为167.326677。
完整代码见附件:
|