riscv代码调试遇到过的问题及坑

本文详细记录了在RISC-V架构下遇到的编译、链接和调试过程中的一系列问题,包括`riscv32-unknown-elf-gcc`的错误、`riscv64-unknown-elf-ld`的链接问题、GDB的调试问题以及QEMU在模式切换时的异常。针对这些问题,提供了相应的解决方案,如修改编译选项、使用特定版本的工具链以及调整QEMU设置。文章还展示了源码级别的问题分析和修复方法。
摘要由CSDN通过智能技术生成
编译篇
riscv32-unknown-elf-gcc -march=rv32ima -mabi=ilp32 遇到这个问题
Error: unrecognized opcode `csrr a5,mhartid'

解决方案:
https://lkml.org/lkml/2022/2/10/879
https://blog.csdn.net/u011011827/article/details/121371305
riscv32-unknown-elf-gcc -march=rv32ima_zicsr -mabi=ilp32

//-march=rv32ima_zicsr_zifencei 
原因:
> +# Newer binutils versions default to ISA spec version 20191213 which moves some
> +# instructions from the I extension to the Zicsr and Zifencei extensions.

链接篇
riscv64-unknown-elf-ld 链接遇到如下问题
target emulation `elf32-littleriscv' does not match `elf64-littleriscv'

原因
应该是 riscv64-unknown-elf-ld 不支持 将32-elf 链接为 32-elf


1.用 riscv 编译链 中的 gcc 链接试试
riscv64-unknown-elf-gcc  -T arch/rv32/linker.lds -nostdlib -nostartfiles -Wl,-Map=baremetal.map -Wl,--whole-archive arch/rv32/built-in.a init/built-in.a modules/built-in.a  -Wl,--no-whole-archive -o baremetal.elf

2.用 riscv32 工具链试试
undefined reference to `__clzdi2' // https://github.com/riscv-collab/riscv-gnu-toolchain/issues/588
	我用的 是 x-tools 8.3.0 , riscv64-unknown-elf/lib/gcc/riscv64-unknown-elf/8.3.0/ 下的 .a 是 32bit的 
	直接链接 riscv64-unknown-elf/lib/gcc/riscv64-unknown-elf/8.3.0/rv64imac/lp64 下的 libgcc.a 会报其他的错
	/home/pop/x-tools/riscv64-unknown-elf/lib/gcc/riscv64-unknown-elf/8.3.0/rv64imac/lp64/libgcc.a(_clzsi2.o): in function `__clzdi2':
	/home/pop/work/freertos-riscv/crosstool-ng-crosstool-ng-1.24.0/.build/riscv64-unknown-elf/src/gcc/libgcc/libgcc2.c:710:(.text+0x1c): relocation truncated to fit: R_RISCV_HI20 against symbol `__clz_tab' defined in .rodata section in /home/pop/x-tools/riscv64-unknown-elf/lib/gcc/riscv64-unknown-elf/8.3.0/rv64imac/lp64/libgcc.a(_clz.o)
---

	riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14 编译 , 也是 这个问题 : undefined reference to `__clzdi2'
	riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/lib/gcc/riscv64-unknown-elf/10.2.0/ 下的 .a 是 64bit的 

---	
	目前观察到 10.2.1 的 adnes toolchain 没有这个问题,这个是rv64 only 的 , 可以正常链接 __clzdi2
---
	https://github.com/riscv-collab/riscv-gnu-toolchain/issues/457
	增加
	CT_LIBC_NEWLIB_TARGET_CFLAGS="-mcmodel=medany"
	没有解决

解决方案:
	直接把 crosstool-ng 中的  
		./.build/src/gcc-12.1.0/libgcc/config/nds32/lib2csrc-mculib/_clzsi2.c 
		./.build/src/gcc-12.1.0/libgcc/config/nds32/lib2csrc-mculib/_clzdi2.c 
	这两个文件放到 工程 中编译链接
	
	
gdb 篇
Could not fetch register "scause"; remote failure reply 'E14'

原因
该版本的gdb中不支持该 csr

1.更新到一个高版本的gdb 解决问题
Cannot find bounds of current function

原因
abi的问题

2.在gdb命令行中输入 set  architecture riscv:rv32 解决问题
qemu 篇
qemu-6.1.0 build from source /ubuntu 22.04 6.2.0 have questions
mode 切换时 
切换后的pc 执行第一条指令后会进入异常(不是中断)
	原因(mcause)"Instruction access fault"
	mdcause 为 "Reserved"

原因
未知

1.换一个 qemu-system-riscv 解决了该问题 
	// ubuntu 20.04 qemu V4.2.1 is ok 
	// v5.2.0 build from source by gcc 9 is ok , and it can load kernel from opensbi
	// v6.0.0-rc0 is not ok , but it can load kernel from opensbi

// 这个 大概意思已经明了了,只是把 mcause 改了
$ git show 4c48aad122b9dd4d96184828d7172cc62dae01c5
commit 4c48aad122b9dd4d96184828d7172cc62dae01c5
Author: Bin Meng <bmeng@tinylab.org>
Date:   Mon Dec 5 14:53:03 2022 +0800

    target/riscv: Fix mret exception cause when no pmp rule is configured
    
    The priv spec v1.12 says:
    
      If no PMP entry matches an M-mode access, the access succeeds. If
      no PMP entry matches an S-mode or U-mode access, but at least one
      PMP entry is implemented, the access fails. Failed accesses generate
      an instruction, load, or store access-fault exception.
    
    At present the exception cause is set to 'illegal instruction' but
    should have been 'instruction access fault'.
    
    Fixes: d102f19a2085 ("target/riscv/pmp: Raise exception if no PMP entry is configured")
    Signed-off-by: Bin Meng <bmeng@tinylab.org>
    Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
    Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
    Message-Id: <20221205065303.204095-1-bmeng@tinylab.org>
    Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 09f1f5185d..d7af7f056b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -202,7 +202,7 @@ target_ulong helper_mret(CPURISCVState *env)
 
     if (riscv_feature(env, RISCV_FEATURE_PMP) &&
         !pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
-        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+        riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
     }
 
     target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
// 解决方案,在 切换Mode 前 调用此函数
/*************************************************************************
  > File Name: pmp.c
  > Author: SuWeishuai
  > Mail: suwsl@foxmail.com
  > Created Time: 2023年06月10日 星期六 18时09分05秒
 ************************************************************************/

#include "pmp.h"
#include "stdint.h"

void pmp_setup(void)
{
  unsigned long int pmpc = PMP_A_NAPOT | PMP_R | PMP_W | PMP_X;
  asm volatile (
                "csrw pmpaddr0, %1\n\t"
                "csrw pmpcfg0, %0\n\t"
                :
                : "r" (pmpc), "r" (-1UL)
                :
                );
}
/*************************************************************************
  > File Name: pmp.h
  > Author: SuWeishuai
  > Mail: suwsl@foxmail.com
  > Created Time: 2023年06月10日 星期六 18时12分12秒
 ************************************************************************/
#ifndef PMP_H
#define PMP_H

#define PMP_R                           0x01UL
#define PMP_W                           0x02UL
#define PMP_X                           0x04UL
#define PMP_A                           0x18UL
#define PMP_A_TOR                       0x08UL
#define PMP_A_NA4                       0x10UL
#define PMP_A_NAPOT                     0x18UL
#define PMP_L                           0x80UL


#endif

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: FT3267是一种支持RISC-V架构的触摸屏控制芯片。RISC-V是一种开放指令集架构(ISA),具有可扩展性、灵活性和可定制性等优点。FT3267作为一款触摸屏控制芯片,可以与主机处理器通信,接收和处理触摸输入,并将处理后的数据传输给主机系统进行进一步处理。 FT3267的RISC-V代码用于控制和管理芯片的各个功能和模块,包括触摸传感器、控制器、存储器、通信接口等。代码中可能包含以下功能的实现: 1. 初始化和配置:通过特定的代码指令初始化触摸屏控制芯片,包括设置触摸传感器、控制模块、通信接口的参数和配置。 2. 数据采集和处理:RISC-V代码用于控制数据采集过程,包括获取触摸传感器的原始数据、滤除噪声、进行坐标转换和校准等处理,以得到准确的触摸点坐标。 3. 通信接口:通过代码控制芯片与主机系统之间的通信接口,例如I2C或SPI接口,以传输触摸数据和控制命令。 4. 中断处理:代码可能包含中断处理程序,以便在触摸事件发生时及时地通知主机系统,并启动相应的处理程序。 5. 功耗管理:根据需求,代码可能实现针对节能和延长电池寿命的功耗管理功能,例如休眠模式、时钟和电压的动态调节等。 通过编写FT3267的RISC-V代码,可以实现对触摸屏控制芯片的全面控制和管理。这种代码的编写需要对RISC-V架构和FT3267芯片的功能和特性有深入了解,同时需要考虑到性能、可靠性和稳定性等因素,以确保触摸屏的正常运行和用户体验。 ### 回答2: ft3267是一种触摸屏控制芯片,RISC-V则是一种开放且自由的指令集架构。当我们提到ft3267触摸屏RISC-V代码时,可以理解为在ft3267芯片上运行的RISC-V指令集的代码。 触摸屏是一种输入设备,用于接收用户通过手指或触控笔在屏幕上的触摸输入,并将其转换为计算机可以理解的信息。而ft3267则是一种集成了触摸屏控制器的芯片,它可以连接到主机系统,接收并处理来自触摸屏的输入信号,并将其转化为数字信号传输给主机系统。 RISC-V则是一种开放且自由的指令集架构,其指令集精简而高效。在ft3267芯片中,如果使用RISC-V指令集架构来编写代码,可以利用RISC-V架构的优势,实现对触摸屏控制芯片的控制、数据处理、结果传输等操作。 在ft3267触摸屏RISC-V代码中,可以使用RISC-V指令集提供的指令和功能,通过读取和写入寄存器、配置触摸屏参数、接收和处理触摸屏输入信号、进行数据计算和处理、控制触摸屏输出信号等操作来实现对触摸屏的控制和操作。 这种组合可以为使用ft3267芯片的设备提供更加灵活和高效的触摸屏控制功能。通过编写ft3267触摸屏RISC-V代码,我们能够更好地利用RISC-V指令集的优势,为触摸屏控制芯片带来更加高效和灵活的控制方法,实现更好的用户体验。 ### 回答3: FT3267是一款触摸屏芯片,它采用了RISC-V架构的处理器进行代码运行。RISC-V是一种开放源代码的指令集架构,具有简洁、灵活和可扩展的特点。 触摸屏的工作原理是通过感应用户手指触摸位置的变化来实现交互功能。FT3267芯片内部的RISC-V处理器负责处理触摸屏的相关代码,并控制触摸信号的采集和分析。 FT3267芯片上的RISC-V代码可以实现多种触摸屏的功能,如单点触控、多点触控、手势识别等。代码中会包含对触摸信号的处理流程,如采样率的控制、滤波算法的设计、触摸事件的识别和分析等。 RISC-V指令集架构的代码具有高效的执行性能和良好的可移植性,可以通过编译器将高级语言如C、C++等转换为RISC-V指令进行执行。开发人员可以根据具体需求编写或调整代码,以适配不同触摸屏的硬件规格和交互逻辑。 为了提高代码的可靠性和稳定性,开发人员可以使用调试工具对RISC-V代码进行调试和优化。调试工具可以监控代码的执行过程,帮助发现并修复潜在的错误。 总之,FT3267触摸屏芯片使用RISC-V代码来控制触摸信号的采集和处理,实现触摸屏的各种交互功能。RISC-V代码具有高效、灵活和可移植的特点,可以通过编写、调试和优化来满足不同触摸屏的需求。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值