[Bug] bsp/cvitek 大核无法支持 float 指令
unicornx opened this issue · 14 comments
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
走读代码时发现 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?
@BernardXiong 搜索 libcpu/risc-v/t-head/c906/
代码,还发现有不少 ifdef ENABLE_FPU
的逻辑,但是 Kconfig 中并没有 ENABLE_FPU 的配置开关。
请问当时移植 libcpu/risc-v/t-head/c906/
的代码历史是什么?感觉需要再整理一下?
- 保留
libcpu/risc-v/t-head/c906/startup_gcc.S
中 diable FPU 的操作 (即保持目前仓库中代码不变)。 - 强制在
rtconfig.h
中手动定义ENABLE_FPU
。 - 修改
bsp/cvitek/cv18xx_risc-v/rtconfig.py
, 将-mabi=lp64
改成-mabi=lp64d
编译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 可以,这个还没有深入研究。
rt_kprintf是不支持float打印的
目前这个 issue 实际上可以分成两个问题
- 问题 1:基于 newlib gcc 的 FPU 没有 enable 导致 float 指令异常
- 问题 2:将
-mabi=lp64
改成-mabi=lp64d
后换成 musl gcc 链接报错。
从长远看,如果大核要上 smart,以及为了解决 #8943,则要用 musl gcc,但是由于 问题 2 ,可能要从 toolchain 角度再看看,这个应该要用另外一个 issue 跟踪。
如果单纯为了解决问题 1,不换 newlib gcc,那么我认为可以采用修改 Kconfig,增加 ENABLE_FPU
选项方式。但 @flyingcys 建议采用 ARCH_RISCV_FPU_D
更好。
走读代码时发现
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 指令的执行,但注释掉这四行语句后,运行依然报非法指令错误。
启动时关闭 FPU VPU 是因为它们是按需自动开启的 😂 否则会拖垮大部分常规任务的整体性能
目前这个 issue 实际上可以分成两个问题
- 问题 1:基于 newlib gcc 的 FPU 没有 enable 导致 float 指令异常
- 问题 2:将
-mabi=lp64
改成-mabi=lp64d
后换成 musl gcc 链接报错。从长远看,如果大核要上 smart,以及为了解决 #8943,则要用 musl gcc,但是由于 问题 2 ,可能要从 toolchain 角度再看看,这个应该要用另外一个 issue 跟踪。
针对问题 2 新提了一个 issue:#9094。本 issue 仅用于跟踪 问题 1。
问题 2 应该不是问题,保留 -mabi=lp64
即可。#9094 已经关闭。
参考 https://github.com/RT-Thread/rt-thread/blob/master/bsp/qemu-virt64-riscv/README_ch.md
- 如果
-march
包含v
, 选择Using RISC-V Vector Extension
, 反之关闭- 如果
-march
包含f/d
, 选择Enable FPU
, 反之关闭
所以 rootcause 就是 bsp/cvitek 的 大核 配置没有 enable FPU,需要补上。
#9290 这个要合并吗?
solved: #9290