GD32L233C-START评测——03_1.CoreMark测试、RT-Thread-Nano移植
[复制链接]
本帖最后由 wadeRen 于 2022-1-21 11:15 编辑
前言
- 02_1、02_2两篇展示了搭建环境,还有简单的调试介绍。
GD32L233C- START评测——02_1.搭建开发环境、简单调试
GD32L233C- STARTI评测——02_2.搭建开发环境、简单调试
- 这篇主要进行CoreMark测试还有移植RT-Thread-Nano系统到开发板上。(前者是为了和STM32相近型号做简单对比,后者是为后续实践项目做准备工作)
本篇的产生实属不易,我给自己点个赞。
1. 建立基于开发板的精简工程
(官方例程的工程结构我不太喜欢,其实是个人习惯,本部分不影响后续的跑分还有操作系统移植)
(若有朋友需要建自己的工程,可以参考我的工程结构;或者我后续再加一篇建工程的贴)
工程模板文件夹结构如下:
名称
|
作用 |
bsp_base |
用来存放MCU的内核文件等(如:startup_gd32l23x.s、system_gd32l23x.c) |
bsp_drv |
用来存放MCU的usb驱动(暂时为空) |
bsp_lib |
用来存放MCU的外设库文件(如:gd32l23x_usart.c、gd32l23x_usart.h等) |
Listing |
用来存放编译通过后的存储占用映射的.map文件 |
Objects |
用来存放编译器编译时产生的C/汇编/链接的列表清单,以及.hex文件 |
user_app |
用来存放main.c文件 |
user_doc |
用来存放程序的说明 |
工程文件结构如下:
2. CoreMark简介
CoreMark是一个行业标准的基准测试,用于测量中央处理器(CPU)和入式微控制(MCU)的性能。(此句摘抄自官方介绍)
简单来说,就是一个MCU的跑分测试工具,类似于电脑端的鲁大师、手机端的安兔兔。
不过它是一套开源的源码,需要像移植操作系统一样,需将其移植到你自己的MCU工程里,并给其提供一些基本功能的函数接口它才可正常工作。
下面贴上STM32各个系列MCU参考测试分,后续我们自己跑分完了以后,回来对照一下。图片来源:[Coremark跑分评测] STM32 跑分系列初步小结
3. CoreMark下载
1. 官网地址: http://www.eembc.org/coremark/index.php
2. GitHub地址:
3. gitee地址:
4. EEWORLD地址:(上传审核通过后我会附到下方)
4. CoreMark测试步骤
1. 下载CoreMark源码;
2. 准备已实现 printf() 函数重定向的工程;
3. 移植CoreMark到工程;
4. 修改部分配置;
5. 测试跑分成功。
(上述“3”和“4”很重要,也很简单 别人说很简单,我没觉得 )
5. CoreMark测试
(下述小标题步骤对应上方标题“4. Coremark测试步骤”的内容)
本测试的硬件平台为GD32L23X-START开发板。
5.1 下载CoreMark源码
根据上述地址下载CoreMark源码,文件夹内容如下,红色框中为要移植的源文件;
5.2 准备已实现 printf() 函数重定向的工程
C语言中的 printf() 函数默认的输出设备是显示,如果实现在串口或LCD上显示,则需要重新定义标准库函数里调用的输出设备定义的相关函数。
我们使用 printf() 函数输出到串口上,就需要将标准库函数的 fputc() 函数里面的输出指向串口,这个过程就是重定向。(引用自:printf重定向)
要实现该功能也不复杂,需要如下三步:
5.2.1 打开微库
1. 点击“魔术棒”;
2. 在“Use Micro LIB”前勾选;
5.2.2 初始化一个串口(这里选择串口0)
串口0初始化的代码如下:
//gd32l233c_start.c文件
void usart0_init(void)
{
/* enable USART0 GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART0);
/* connect port to USARTx_Tx */
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9);
/* connect port to USARTx_Rx */
gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_10);
/* configure USART Tx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_9);
/* configure USART Rx as alternate function push-pull */
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_10);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_10);
/* USART configure */
usart_deinit(USART0);
usart_baudrate_set(USART0, 115200U);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_enable(USART0);
}
串口0初始化函数声明如下:
//gd32l233_start.h 文件
void usart0_init(void);
5.2.3 重定向
贴上代码如下:
//main.c
#include "stdio.h" //需调用此头文件
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART0, (uint8_t) ch ); //发送字符
while (usart_flag_get(USART0,USART_FLAG_TC) == RESET); //检查是否发送完毕
return (ch);
}
5.3 移植CoreMark到工程
1. 在工程下创建一个“user_coremark”文件夹,将下载的CoreMark文件夹路径下的如下文件复制到“user_coremark”文件夹下;
2. 在“步骤4”完成的工程中工程中创建“user_coremark”文件夹;
3. 将复制的所有.c 文件添加到文件夹;
4. 添加 .h文件路径;
5.4 修改部分配置
(此部分非常重要,直接关系移植是否成功,以及是否能跑分,请重视!笔者就在这里反复拉扯了好久)
(本部分参考自:CoreMark移植过程记录)
1. main() 函数已在移植过来的 core_main.c 文件中实现,所以需要将原工程中 main.c 文件中的 main() 函数注释掉。
2. 在 core_portme.c 文件中声明"gd32l233c_start.h"头文件;在第134行, portable_init() 函数中加入串口0初始化;在下方添加打印“测试开始,请等待---”;
//core_portme.c
//添加声明头文件
#include "gd32l233c_start.h"
//第128行的void protable_init(core_portable *p, int *argc, char *argv[])函数中插入下列代码
usart0_init(); //串口0初始化
printf("测试开始,请等待----"); //不是必须的,可以不加;但是建议加
本步骤示意如下:
3. 在 core_portme.h 文件里添加表示迭代次数的宏定义;
// core_portme.h 文件
//插入下列代码
#define ITERATIONS 2000
本步骤示意如下:
4. "core_portme.h"文件中修改优化等级;
//core_portme.h 文件
#ifndef COMPILER_FLAGS
#define COMPILER_FLAGS \
"-O3" /* "Please put compiler flags here (e.g. -o3)" */
#endif
本步骤示意如下:
5. 设置中修改代码优化等级;(此步骤很重要,直接关系到跑分分数!)
6. 检查"core_portme.h"文件中打印函数;
因为我们在前面已经实现了 printf() 函数重定向,所以此处如下图就可以。
7. 在 gd32l23x_it.c 文件中定义个全局变量 gTick,在系统滴答中断中自加,用来计时;
// gd32l23x.h 文件
uint32_t gTick = 0; //定义全局变量,用来保存自加值
void SysTick_Handler(void)
{
gTick++;
delay_decrement();
}
本步骤示意如下:
8. 修改 core_portme.c 文件中的 start_time() 、stop_time() 、 get_time() 函数;
// core_protme.c 文件
#include "systick.h" //声明头文件,因下方需要调用此文件中的函数
extern uint32_t gTick; //引用全局变量,该变量定义在 gd32l23x_it.c 文件中
void start_time(void)
{
gTick = 0;
systick_config(); //开启滴答定时器中断
//GETMYTIME(&start_time_val);
}
void stop_time(void)
{
SysTick->CTRL &= 0xFFFFFFFE; //关闭滴答定时器中断
//GETMYTIME(&stop_time_val);
}
CORE_TICKS get_time(void)
{
return (CORE_TICKS)gTick; //返回计数值
// CORE_TICKS elapsed
// = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
// return elapsed;
}
本步骤示意如下:
9. 修改 core_portme.c 文件中的宏定义 EE_TICKS_PER_SEC 为1000,表示每秒1000个Tick;
// core_portme.c 文件
#define EE_TICKS_PER_SEC 1000//(NSECS_PER_SEC / TIMER_RES_DIVIDER)
本步骤示意如下:
10. 修改启动文件中的堆栈大小为1Kb;(此步骤很重要,影响能不能正常跑分测试!)
// starup_gd32l23x.s 文件
Stack_Size EQU 0x00001000
Heap_Size EQU 0x00001000
本步骤示意如下:
11. 编译通过;
5.5 测试跑分成功
1. 打开串口助手,选择开发板的串口;
2. 把编译通过的代码下载到单片机中;
3. 自动开始测试----
4. 测试跑分成功!!!
上述4个步骤示意如下:
测试跑分完成,贴上分数:
6. 小结
我们可以看到,此次跑分结果为105.546。与STM32的超低功耗系列对比,要高于其M3内核、M0+内核的MCU的,甚至与其主流型的M0内核的MCU分数差不多。
厉害了我的兆易创新!!!
我愿称你为国产之光!!!
(篇幅又长了,再次分为两部分)
|