短笛君 发表于 2026-7-26 22:29:52

【瑞萨RA-eco-RA6M4评测】Uart串口外设使用&& CoreMark移植

本帖最后由 短笛君 于 2026-7-26 22:31 编辑

# RA6M4 CoreMark移植

## 1. CoreMark基准信息

| 项目         | 规格                                             |
| -------------- | -------------------------------------------------- |
| MCU          | Renesas R7FA6M4AF                              |
| 内核         | Arm Cortex-M33,单核                           |
| 最高主频   | 200 MHz                                          |
| Flash / SRAM | 1 MB / 256 KB                                    |
| FPU          | fpv5-sp-d16,hard-float ABI                      |
| 开发板       |RA6M4                                       |
| 工具链       | Renesas LLVM/Clang 21.1.1 (ATfE-21.1.1),Windows |
| FSP          | 6.5.0,e2studio 2026-04.2                        |

## 2. 时钟树

```
HOCO (片内)20 MHz
→ PLL ÷2 ×20 → 200 MHz
                  ├── ICLK÷1 → 200 MHz(CPU / DWT)
                  ├── PCLKA ÷2 → 100 MHz
                  ├── PCLKB ÷4 →50 MHz(SCI)
                  └── PCLKD ÷2 → 100 MHz
```

时钟源使用HOXC内部时钟

## 3. 串口外设 (SCI9)

### 3.1 硬件

| 参数   | 值                           |
| -------- | ------------------------------ |
| 模块   | SCI9,使用 r\_sci\_uart 驱动 |
| 数据位 | 8                            |
| 校验   | 无                           |
| 停止位 | 1                            |
| 流控   | 无                           |
| 中断   | TX 完成中断 + RX 字符中断    |

### 3.2 初始化

FSP 配置器生成 g\_uart9\_ctrl 和 g\_uart9\_cfg,hal\_entry() 调用:

```c
void init_uart(void)
{
    R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
}
```

!(//m.qjumbo.com/forum/data/attachment/forum/202607/26/223013jbnz3tl66g1xkr9n.png)

### 3.3 回调

```c
volatile bool uart9_send_complete_flag = false;

void g_uart9_callback(uart_callback_args_t *p_args)
{
    switch (p_args->event) {
    case UART_EVENT_RX_CHAR:
      R_SCI_UART_Write(&g_uart9_ctrl,
            (uint8_t *)&(p_args->data), 1);
      break;
    case UART_EVENT_TX_COMPLETE:
      uart9_send_complete_flag = true;
      break;
    default:
      break;
    }
}
```

### 3.4 stdout 重定向

picolibc (tinystdio) 在裸机上不提供 stdout 定义,printf → puts 引用 stdout 会导致链接错误 "undefined symbol: stdout"。

用 FDEV\_SETUP\_STREAM 构造 FILE 对象并赋值给 stdout/stdin/stderr:

```c
static int uart_putchar(char c, FILE *f)
{
    (void)f;
    R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&c, 1);
    while (!uart9_send_complete_flag);
    uart9_send_complete_flag = false;
    return (unsigned char)c;
}

static FILE __stdio = FDEV_SETUP_STREAM(
    uart_putchar, NULL, NULL, _FDEV_SETUP_WRITE);

FILE *const stdout = &__stdio;
FILE *const stdin= &__stdio;
FILE *const stderr = &__stdio;
```

## 4. CoreMark 配置

源码: CoreMark 1.0

| 参数   | 值                                       |
| -------- | -------------------------------------------- |
| 模式   | PERFORMANCE\_RUN,TOTAL\_DATA\_SIZE = 2000 |
| 迭代   | 0(自动校准,目标 ≥10 秒)                |
| 内存   | MEM\_STATIC(BSS 段,避免栈溢出)          |
| 种子   | SEED\_VOLATILE                           |
| 定时器 | Arm DWT CYCCNT,5 ns @ 200 MHz             |

## 5. 移植实现

### 5.1 入口链路

```
Reset_Handler
→ main()          (ra_gen/main.c)
    → hal_entry()   (src/hal_entry.c)
      → init_uart()
      → R_BSP_SoftwareDelay(3000ms)
      → coremark_run()(src/coremark/core_main.c)
      → portable_init()
      → 校准迭代次数
      → start_time()
      → [迭代 × (list + matrix + state)]
      → stop_time()
      → 输出分数
```

### 5.2 main 冲突

RA 工程和 CoreMark 各有一个 main()。通过 COREMARK\_NO\_MAIN 宏 在 core\_main.c 中将 main 重命名为 coremark\_run:

```c
// core_portme.h
#define ITERATIONS          0
#define COREMARK_NO_MAIN    1
#define PERFORMANCE_RUN   1
```

```c
// core_main.c —— 条件编译分支
#if defined(COREMARK_NO_MAIN)
int coremark_run(void)
{
    int   argc = 0;
    char *argv = { "" };
#elif MAIN_HAS_NOARGC
MAIN_RETURN_TYPE main(void)
{
    ...
```

### 5.3 DWT 周期计数器

不占用外设定时器,直接操作 Cortex-M33 调试寄存器:

```c
#define DWT_CTRL       (*(volatile uint32_t *)0xE0001000U)
#define DWT_CYCCNT   (*(volatile uint32_t *)0xE0001004U)
#define DEMCR          (*(volatile uint32_t *)0xE000EDFCU)

void portable_init(core_portable *p, int *argc, char *argv[])
{
    DEMCR    |= (1UL << 24);   // TRCENA
    DWT_CYCCNT = 0;
    DWT_CTRL |= (1UL << 0);   // CYCCNTENA

    p->portable_id = 1;
    ee_printf("CoreMark running on RA6M4 @ 200 MHz (DWT CYCCNT)\r\n");
}
```

计时接口——直接读取 CYCCNT 并算差值:

```c
static CORE_TICKS start_time_val, stop_time_val;

static inline ee_u32 read_cyccnt(void)    { return DWT_CYCCNT; }
void start_time(void)                     { start_time_val = read_cyccnt(); }
void stop_time(void)                      { stop_time_val= read_cyccnt(); }
CORE_TICKS get_time(void)               { return stop_time_val - start_time_val; }
secs_ret time_in_secs(CORE_TICKS ticks)   { return (secs_ret)ticks / 200000000.0; }
```

### 5.4 内存

MEM\_STATIC 将 2000 字节 benchmark 数据放入 BSS 段——RA6M4 的 256 KB SRAM 绰绰有余,同时避免 MEM\_STACK 在函数栈帧上分配约 4800 字节导致栈溢出。

## 6. 编译优化

e2studio 生成工程时会重写 subdir.mk,需要生成后手动替换编译选项。

编译选项 (Debug/src/coremark/subdir.mk):

```
-O3 -funroll-loops -flto
```

链接选项 (Debug/makefile):

```makefile
$(file > UART.elf.in, ... -Wl,--icf=none -flto -I"...")
```

| 选项         | 作用                                 |
| ---------------- | ---------------------------------------- |
| -O3            | 激进内联、循环向量化、指令调度         |
| -funroll-loops | 完全展开小循环,直接加速 matrix / list |
| -flto          | 跨编译单元内联 + 死代码消除            |

仅 CoreMark 源文件使用以上选项;FSP 栈其余代码沿用默认的 -Os。

## 7. 基准分项

### List (core\_list\_join.c)

200 节点双向链表。每轮迭代根据 hash 值选择:查找、反转、插入、删除+撤销。

```c
typedef struct list_data_s { ee_s16 data16; ee_s16 idx; } list_data;
typedef struct list_head_s {
    struct list_head_s *next;
    struct list_data_s*info;
} list_head;
```

### Matrix (core\_matrix.c)

16×16 矩阵 (ee\_s16),含加法、乘法、向量乘、转置。矩阵乘法 O(N³) 是 计算密度最高的子项。

```c
typedef ee_s16 MATDAT;
typedef ee_s32 MATRES;
```

### State (core\_state.c)

8 状态有限状态机,每轮 128 次转移,混合位运算和 CRC16 更新。

```c
typedef enum CORE_STATE {
    CORE_START=0, CORE_INVALID, CORE_S1, CORE_S2,
    CORE_INT, CORE_FLOAT, CORE_EXPONENT, CORE_SCIENTIFIC
} core_state_e;```
```

## 8. 使用

```
直接在eestudio中debug烧录 使用串口工具观察log
```

打开枚举的 COM 口,波特率与 UART9 一致。上电 3 秒后自动输出:
!(//m.qjumbo.com/forum/data/attachment/forum/202607/26/222635f2kxoi8msfs12f2g.png)

```
Starting in 3 seconds...

CoreMark running on RA6M4 @ 200 MHz (DWT CYCCNT)

2K performance run parameters for coremark.

CoreMark Size    : 666

Total ticks      : 3559881938

Total time (secs): 17.799410

Iterations/Sec   : 337.089831

Iterations       : 6000

Compiler version : Clang/LLVM 21.1.1

Compiler flags   : -mcpu=cortex-m33 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -O2

Memory location: STATIC

seedcrc          : 0xe9f5

crclist       : 0xe714

crcmatrix   : 0x1fd7

crcstate      : 0x8e3a

crcfinal      : 0xa14c

Correct operation validated. See README.md for run and reporting rules.

CoreMark 1.0 : 337.089831 / Clang/LLVM 21.1.1 -mcpu=cortex-m33 -mthumb -mfloat-abi=hard -mfpu=fpv5-sp-d16 -O2 / STATIC
```

CoreMark性能基准约为337.089831这算Mhz为1.685/Mhz 性能属于中规中矩的一档

结尾附上工程代码

短笛君 发表于 2026-7-26 22:31:32

测试工程代码 使用EEStudio导入
页: [1]
查看完整版本: 【瑞萨RA-eco-RA6M4评测】Uart串口外设使用&& CoreMark移植

Baidu
map