OpenOCD笔记

OpenOCD

register commands

int openocd_main(int argc, char *argv[])

&workaround_for_jimtcl_expr,		// 解析JIM-TCL脚本
&openocd_register_commands,			// openocd 基本命令version, init
&server_register_commands,			// server.c telnet监听端口4444
&gdb_register_commands,				// gdb_server.c gdb监听端口3333
&log_register_commands,				// set debug_level
&rtt_server_register_commands,		// RTT server
&transport_register_commands,		// transport select jtag...
&interface_register_commands,		// interface hs2_jtag7...
&target_register_commands,			// target create bk3_32IMC_UPTpid riscv -chain-position bk3_32IMC_UPTpid.cpu
&flash_register_commands,			// flash
&nand_register_commands,			// nand flash
&pld_register_commands,				// PLD
/*The CoreSight Cross Trigger Interface (CTI) is a hardware device that 
takes individual input and output hardware signals known as triggers to and from devices 
and interconnects them via the Cross Trigger Matrix (CTM) to other devices via numbered channels, 
in order to propagate events between devices*/
&cti_register_commands,
&dap_register_commands,				// arm CMSIS-DAP
&arm_tpiu_swo_register_commands,	// arm TPIO SWO

server_host_os_entry() // 打开网络库/启动网络库,启动了这个库,这个库里的函数/功能才能使用。

openocd_thread

 1. parse_cmdline_args	// 解析openocd参数,-v,-c,-f-h...
 2. parse_config_file	//解析并执行config配置文件
 3. server_init			//启动socket,监听telnet port
 4. 首次启动执行 init,执行noinit,清楚init_at_startup标志位
 5. server_loop
 /*在这个函数的大循环中,接收来自GDB的命令,对每个命令字串,调用相应的函数进行特定的处理.
 比如设置断点,单步运行等等. 通过一层层的call stack,最终将命令发送给MCU的Debug Module模块中. 
 当然在处理完成后会通过socket将response的消息反馈给GDB*/ 

service->input

gdb_input()
-->gdb_input_inner();
	-->gdb_get_packet();
		-->gdb_get_packet_inner();
	-->gdb_thread_packet();
	-->gdb_get_registers_packet();
	-->gdb_set_registers_packet();

设置软件断点逻辑

下图是设置软件断点的处理逻辑: 其中 "Z0,100310,4"是来自GDB发送过来的命令字符串,其中"Z0"表示设置软断点,"0"表示软断点,"1"表示硬断点;"100310"为16进制值,表示断点设置的地址,"4"表示该地址处的机器码长度为4个字节. "$OK#9a"表示OpenOCD处理完该命令后要反馈给GDB的消息. 本文章是基于RISCV的平台,通过如下图的调用栈可以看到,对于软断点的设置,OpenOCD会做两个步骤,首先将要设置的断点处的地址的机器码指令读取到OpenOCD中保存起来,然后将软断点的机器码写入到目标系统的内存中去,在RISCV系统中是将ebreak(4字节)和c.ebreak(2字节)的机器码来写入到目标内存中去的. 当MCU运行代码的时候,读取到断点处的break指令,就会触发MCU的halt,这个时候就表示软断点触发了,MCU就停止下来. OpenOCD在完成来自GDB的命令的处理,一般都会调用gdb_put_packet()函数将处理结果反馈给GDB,反馈的字符串也需要满足GDB对于命令格式的要求
在这里插入图片描述

删除软件断点

删除软件断点的处理逻辑: 如下截图是删除软件断点的调用栈逻辑,OpenOCD收到来自GDB的命令"z0,100310,4".其中"z0"表示要删除软件断点.删除软件断点的处理与添加软件断点的处理逻辑相反.需要将保存在OpenOCD中的原地址处的机器码写回到MCU的原位置.
在这里插入图片描述

单步

这是单步step走的命令处理逻辑.读者可以根据该调用栈自行分析其代码结构.有一点需要注意的是,在处理代码的最底层,实际调用的是dmi_write()或dmi_read()函数.该函数涉及到的是OpenOCD对MCU中Debug Module的内部寄存器的访问.
在这里插入图片描述

读取riscv的寄存器

读取riscv的Vector寄存器的值,通过构造两条汇编指令的机器码的方式,将结果暂时读取到CPU的s0寄存器中,最终通过DATAn寄存器将数据获取出来。
在这里插入图片描述
转载:OpenOCD代码结构浅析(基于RISCV)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值