RISCV下的调试个人总结———(上)
那些年我们一起踩过的坑…
Riscv的调试模块重点,如何去看
[0] 神图来
这张图非常清楚的,描述了riscv调试模块和外部调试器通讯的框图。
咋一看,没咋懂,啥玩意
分割大法:
//从用户端深入进去
(1)gdb
(2)openocd
(3)Jtag
(3-1) JTAG主机工具
(3-2) JTAG从机模块[DTM]
(4)DM模块
[1]GDB
用户发送指令的地方,什么打断点(break),继续执行 ( c) 等指令,如果你在集成环境里,就是那些按钮发出的指令。
如何查看集成环境到底发了啥玩意可以在gbd的链接前,添加命令:
set logging file C:/MounRiver/MounRiver_Studio/toolchain/RISC-V Embedded GCC/bin/debug.log
set logging on
至于GDB怎么用?命令行怎么使用,这个网上一大堆,不是本章的重点。
下面是我调试时候的命令记录下:
C:\MounRiver\MounRiver_Studio\toolchain\RISC-V Embedded GCC\bin>riscv-none-embed-gdb Z:/Proj/_12_PFRV/_03_FPGA/_03_Driver_Stdio_backup/Examples/Riscv_Example/_20_CoreCut/_20_5_Riscv_HelloRiscv_U0_0x00100000/Projects/obj/_20_5_Riscv_HelloRiscv_U0_0x00100000.elf -x gdbinit
gdbinit是在gdb同一目录下的文档,内容为:
set architecture riscv:rv32
set remotetimeout unlimited
target extended-remote localhost:3333
set remote hardware-watchpoint-limit 2
mon reset halt 重启
flushregs 更新寄存器
thb main 设置中断
[2]Openocd
这是啥?gdb链接的服务器,简单的说他负责起了与gdb交互以及封装了riscv下dm模块的软件API接口,(比如riscv-013.c这个文件里就封装了DM模块所涉及道的寄存器)
我也想用一张神图,表示Openocd
这些洞悉就构成了Openocd
想知道如何去创建自己的Openocd我会在后面文档中编写,怎么支持自己的芯片flash,我会在后面的文档中描述。
(1)OpenOcd中与riscv DM寄存器相关的代码:
static void decode_dmi(char *text, unsigned address, unsigned data)
{
static const struct {
unsigned address;
uint64_t mask;
const char *name;
} description[] = {
{
DM_DMCONTROL, DM_DMCONTROL_HALTREQ, "haltreq" },
{
DM_DMCONTROL, DM_DMCONTROL_RESUMEREQ, "resumereq" },
{
DM_DMCONTROL, DM_DMCONTROL_HARTRESET, "hartreset" },
{
DM_DMCONTROL, DM_DMCONTROL_HASEL, "hasel" },
{
DM_DMCONTROL, DM_DMCONTROL_HARTSELHI, "hartselhi" },
{
DM_DMCONTROL, DM_DMCONTROL_HARTSELLO, "hartsello" },
{
DM_DMCONTROL, DM_DMCONTROL_NDMRESET, "ndmreset" },
{
DM_DMCONTROL, DM_DMCONTROL_DMACTIVE, "dmactive" },
{
DM_DMCONTROL, DM_DMCONTROL_ACKHAVERESET, "ackhavereset" },
{
DM_DMSTATUS, DM_DMSTATUS_IMPEBREAK, "impebreak" },
{
DM_DMSTATUS, DM_DMSTATUS_ALLHAVERESET, "allhavereset" },
{
DM_DMSTATUS, DM_DMSTATUS_ANYHAVERESET, "anyhavereset" },
{
DM_DMSTATUS, DM_DMSTATUS_ALLRESUMEACK, "allresumeack" },
{
DM_DMSTATUS, DM_DMSTATUS_ANYRESUMEACK, "anyresumeack" },
{
DM_DMSTATUS, DM_DMSTATUS_ALLNONEXISTENT, "allnonexistent" },
{
DM_DMSTATUS, DM_DMSTATUS_ANYNONEXISTENT, "anynonexistent" },
{
DM_DMSTATUS, DM_DMSTATUS_ALLUNAVAIL, "allunavail" },
{
DM_DMSTATUS, DM_DMSTATUS_ANYUNAVAIL, "anyunavail" },
{
DM_DMSTATUS, DM_DMSTATUS_ALLRUNNING, "allrunning" },
{
DM_DMSTATUS, DM_DMSTATUS_ANYRUNNING, "anyrunning" },
{
DM_DMSTATUS, DM_DMSTATUS_ALLHALTED, "allhalted" },
{
DM_DMSTATUS, DM_DMSTATUS_ANYHALTED, "anyhalted" },
{
DM_DMSTATUS, DM_DMSTATUS_AUTHENTICATED, "authenticated" },
{
DM_DMSTATUS, DM_DMSTATUS_AUTHBUSY, "authbusy" },
{
DM_DMSTATUS, DM_DMSTATUS_HASRESETHALTREQ, "hasresethaltreq" },
{
DM_DMSTATUS, DM_DMSTATUS_CONFSTRPTRVALID, "confstrptrvalid" },
{
DM_DMSTATUS, DM_DMSTATUS_VERSION, "version" },
{
DM_ABSTRACTCS, DM_ABSTRACTCS_PROGBUFSIZE, "progbufsize" },
{
DM_ABSTRACTCS, DM_ABSTRACTCS_BUSY, "busy" },
{
DM_ABSTRACTCS, DM_ABSTRACTCS_CMDERR, "cmderr" },
{
DM_ABSTRACTCS, DM_ABSTRACTCS_DATACOUNT, "datacount" },
{
DM_COMMAND, DM_COMMAND_CMDTYPE, "cmdtype" },
{
DM_SBCS, DM_SBCS_SBVERSION, "sbversion" },
{
DM_SBCS, DM_SBCS_SBBUSYERROR, "sbbusyerror" },
{
DM_SBCS, DM_SBCS_SBBUSY, "sbbusy" },
{
DM_SBCS, DM_SBCS_SBREADONADDR, "sbreadonaddr" },
{
DM_SBCS, DM_SBCS_SBACCESS, "sbaccess" },
{
DM_SBCS, DM_SBCS_SBAUTOINCREMENT, "sbautoincrement" },
{
DM_SBCS, DM_SBCS_SBREADONDATA, "sbreadondata" },
{
DM_SBCS, DM_SBCS_SBERROR, "sberror" },
{
DM_SBCS, DM_SBCS_SBASIZE, "sbasize" },
{
DM_SBCS, DM_SBCS_SBACCESS128, "sbaccess128" },
{
DM_SBCS, DM_SBCS_SBACCESS64, "sbaccess64" },
{
DM_SBCS, DM_SBCS_SBACCESS32, "sbaccess32" },
{
DM_SBCS, DM_SBCS_SBACCESS16, "sbaccess16" },
{
DM_SBCS, DM_SBCS_SBACCESS8, "sbaccess8" },
};
(2)API:这里面就包括什么单步啊,恢复啊,等等,用来操作DM模块的
static int riscv013_on_step_or_resume(struct target *target, bool step);
static int riscv013_step_or_resume_current_hart(struct target *target,
bool step, bool use_hasel);
static void riscv013_clear_abstract_error(struct target *target);
/* Implementations of the functions in riscv_info_t. */
static int riscv013_get_register(struct target *target,
riscv_reg_t *value, int hid, int rid);
static int riscv013_set_register(struct target *target, int hartid, int regid, uint64_t value);
static int riscv013_select_current_hart(struct target *target);
static int riscv013_halt_prep(struct target *target);
static int riscv013_halt_go(struct target *target);
static int riscv013_resume_go(struct target *target);
static int riscv013_step_current_hart(struct target *target);
static int riscv013_on_halt(struct target *target);
static int riscv013_on_step(struct target *target);
static int riscv013_resume_prep(struct target *target);
static bool riscv013_is_halted(struct target *target);
static enum riscv_halt_reason riscv013_halt_reason(struct target *target);
static int riscv013_write_debug_buffer(struct target *target, unsigned index,
riscv_insn_t d);
static riscv_insn_t riscv013_read_debug_buffer(struct target *target, unsigned
index);
static int riscv013_execute_debug_buffer(struct target *target);
static void riscv013_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t d);
static void riscv013_fill_dmi_read_u64(struct target *target, char *buf,
原文地址:https://blog.csdn.net/mhj258258/article/details/143743197
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!