本帖最后由 zjh20070904 于 2022-5-13 11:02 编辑
#技术资源#
(涉及到的截图、代码见附件) 主要记录了在APM32F103xE上移植coremark的过程。 1 coremark网址在这可以查到相关产品的coremark数值。
2 下载源码最近网址无法打开,附件提供了网上其它方式下载的代码。
3 主要工作过程通过STK定时器,计算指定算法的运行次数的时间,依据此计算出跑分。 需要初始化的硬件有:USART实现printf、STK初始化、栈设置合理、编写STK中断处理函数,移植、修改coremark源码;配置好编译环境,依据每个处理器的运行速度,调整运行算法的次数,确保总的运行时间大于10。 编译下载运行,即可获得测试结果。
4 移植代码、修改步骤4.1 添加coremark源代码至Keil工程中
添加至Keil工程中
4.2 配置Keil工程,设置好头文件包含路径(以个人定义的路径为准)
4.3 在main.c中添加头文件、编译4.3.1 包含的头文件如下
4.3.2 编译后报错及处理方案4.3.2.1 缺少定义
在core_portme.h中添加对ITERATIONS的定义,确保运行算法的总时间超过10s,刚开始时,可以设置该参数小点,然后逐步增大,如果一开始就设置很大的话,会等待较长的运行时间才会有运行结果。
4.3.2.2 重复定义main的错误因为在core_main.c中定义了main,会出现重复定义的错误。
为了方面将运行跑分的函数当做函数调用,处理方案如下:
同时在coremark.h中声明函数,调用时编译不报警告。
在mian.c中定义变量,方便调用函数CoreMark()
4.4 编写串口初始化代码,实现printf//重定向c库函数printf到串口,重定向后可使用printf函数 int fputc(int ch, FILE *f) { USART_TxData(USART1,(char) ch); while(USART_ReadStatusFlag(USART1,USART_FLAG_TXBE) == RESET); return(ch); }
//重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数 int fgetc(FILE *f) { while(USART_ReadStatusFlag(USART1, USART_FLAG_RXBNE) == RESET); return(int)USART_RxData(USART1); }
//重定向c库函数printf到串口,重定向后可使用printf函数 int fputc(int ch, FILE *f) { USART_TxData(USART1,(char) ch); while(USART_ReadStatusFlag(USART1,USART_FLAG_TXBE) == RESET);
if(ch=='\n') { USART_TxData(USART1,'\r'); while(USART_ReadStatusFlag(USART1,USART_FLAG_TXBE) == RESET); } return(ch); }
//重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数 int fgetc(FILE *f) { while(USART_ReadStatusFlag(USART1, USART_FLAG_RXBNE) == RESET); return(int)USART_RxData(USART1); }
int main(void) { intargc; char*argv[]={"1","2"};
GPIO_Config_T GPIO_ConfigStruct; USART_Config_TUSART_ConfigStruct;
RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA |RCM_APB2_PERIPH_USART1)); GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP; GPIO_ConfigStruct.pin = GPIO_PIN_9; GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz; GPIO_Config(GPIOA, &GPIO_ConfigStruct);
USART_ConfigStruct.baudRate = 115200; USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE; USART_ConfigStruct.mode = USART_MODE_TX; USART_ConfigStruct.parity = USART_PARITY_NONE; USART_ConfigStruct.stopBits = USART_STOP_BIT_1; USART_ConfigStruct.wordLength = USART_WORD_LEN_8B; USART_Config(USART1, &USART_ConfigStruct); USART_Enable(USART1);
CoreMark(argc,argv);
while(1); }
4.5 定义启动、停止、获取时间的变量、函数4.5.1 在core_portme.h文件添加配置STK所需的头文件,这里直接包含amp32f10x.h
4.5.2 定义全局变量gTick
4.5.3 重新定义start_time(),初始化STK,实现每ms产生一次中断
4.5.4 重新定义stop_time()、get_time()
4.5.5 添加 #define EE_TICKS_PER_SEC 1000gTick每1ms产生一次中断、计数,将EE_TICKS_PER_SEC定义为1000可将毫秒时间转为秒单位,注释掉部分代码
4.5.6 在core_portme.h中声明gTick变量
4.5.7 在apm32f10x_int.c中的SysTick_Handler中添加gTick++
4.6 增加一行代码,可通过串口显示已运行。
4.7 编译,下载运行,调试时会出现
解决方案是:增大栈空间,这里有些偷懒,理论占用多大空间可分析代码
4.8 再次编译运行,串口显示较乱,缺少回车符
4.8.1 解决方案一:通过软件增加’\r’
4.8.1.1 方法二:通过设置串口软件增加’\r’各家软件设置上存在差异,这里不作尝试了。
4.9 再次编译、运行结果如下
4.10 注意点算法运行的时间需要大于10s,如果小于10s会出现如下错误:
需要调整的参数如下:
5 问题同一颗芯片,MCU的运行状态、编译环境状态、代码运行位置都会影响coremark数值,后续会对比分析哪些参数会影响coremark数值。
coremark_source.zip
(465.97 KB)
|