RT-Thread / rt-thread

RT-Thread is an open source IoT real-time operating system (RTOS).
https://www.rt-thread.io
Apache License 2.0
10.02k stars 4.9k forks source link

[Bug] bsp/cvitek 大核无法支持 float 指令 #9075

Open unicornx opened 2 weeks ago

unicornx commented 2 weeks ago

RT-Thread Version

master

Hardware Type/Architectures

bsp/cvitek

Develop Toolchain

GCC

Describe the bug

bsp/cvitek/cv18xx_risc-v/applications/main.c 的 main 中加入如下代码:

flaot f = 100;

编译正常,但是运行会 crash,报 Unhandled Exception 2:Illegal Instruction

同样的代码加在 bsp/cvitek/c906_little/applications/main.c 中就正常

简单分析后发现大小核的编译选项有区别: 大核:-mabi=lp64

小核:-mabi=lp64d

统一成 -mabi=lp64d, 大核仍然 crash

后继续将大核的 gcc 换成 musl 的,即 https://download-redirect.rt-thread.org/download/rt-smart/toolchains/riscv64gc-linux-musleabi_for_x86_64-pc-linux-gnu_latest.tar.bz2

发现链接时报错:can't link soft-float modules with double-float modules

Other additional context

No response

unicornx commented 1 week ago

走读代码时发现 libcpu/risc-v/t-head/c906/startup_gcc.S 存在如下逻辑:

    /* set to disable FPU */
    li t0, SSTATUS_FS
    csrc sstatus, t0
    li t0, SSTATUS_SUM
    csrs sstatus, t0

怀疑这会影响 float 指令的执行,但注释掉这四行语句后,运行依然报非法指令错误。

所以想问一下,@BernardXiong 当时为啥要 diable FPU?

unicornx commented 1 week ago

@BernardXiong 搜索 libcpu/risc-v/t-head/c906/ 代码,还发现有不少 ifdef ENABLE_FPU 的逻辑,但是 Kconfig 中并没有 ENABLE_FPU 的配置开关。

请问当时移植 libcpu/risc-v/t-head/c906/ 的代码历史是什么?感觉需要再整理一下?

unicornx commented 1 week ago

编译ok,运行也正常,但是发现 rt_kprintf 无法打印 %f, 换成 printf 可以打印。

备注,没有使用 musl gcc,还是和小核一样用的 newlib 的 gcc

int main(void)
{
    int i= 100;
    float f = 100;

    float x = f / 2;
    i = x;

    rt_kprintf("rt_kprintf x = %f\n", x);
    rt_kprintf("Hello RTT test!, x = %d\n", i);
    printf("printf x = %f\n", x);

    return 0;
}

运行显示:

rt_kprintf x = %f
Hello RTT test!, x = 50
printf x = 50.000000

难道 rt_kprintf 自身不支持 float 打印?还不太清楚,网上搜到一篇文章:https://github.com/mysterywolf/rt_vsnprintf_full

但搜索 rtt 源码树,也看到有对 rt_kprintf 调用 %f 的例子,譬如 components/drivers/sensor/v2/sensor_cmd.c 中,所以目前猜测打印的问题可能和使用了 newlib gcc 有关系,尝试了在小核上也是一样的效果。

至于为啥 printf 可以,这个还没有深入研究。

flyingcys commented 1 week ago

rt_kprintf是不支持float打印的

unicornx commented 1 week ago

目前这个 issue 实际上可以分成两个问题

从长远看,如果大核要上 smart,以及为了解决 #8943,则要用 musl gcc,但是由于 问题 2 ,可能要从 toolchain 角度再看看,这个应该要用另外一个 issue 跟踪。

如果单纯为了解决问题 1,不换 newlib gcc,那么我认为可以采用修改 Kconfig,增加 ENABLE_FPU 选项方式。但 @flyingcys 建议采用 ARCH_RISCV_FPU_D 更好。

image

unicornx commented 1 week ago

目前这个 issue 实际上可以分成两个问题

  • 问题 1:基于 newlib gcc 的 FPU 没有 enable 导致 float 指令异常
  • 问题 2:将 -mabi=lp64 改成 -mabi=lp64d 后换成 musl gcc 链接报错。

从长远看,如果大核要上 smart,以及为了解决 #8943,则要用 musl gcc,但是由于 问题 2 ,可能要从 toolchain 角度再看看,这个应该要用另外一个 issue 跟踪。

针对问题 2 新提了一个 issue:https://github.com/RT-Thread/rt-thread/issues/9094。本 issue 仅用于跟踪 问题 1。