OpenOCD 代码学习(5)继续 openocd_thread()

前言

  • 1)前面几节我们学习了 ① ~ ③ 中的解析命令行参数与解析配置文件,接下来我们来看一下剩余的 ④ ~ ⑥ 部分:server_init() 函数、init 命令和 server_loop() 函数:

1 server_init()

  • 1)server_init() 的执行逻辑如下:

  • 2)总的来说,添加了两个 service 到 struct service *services; 链表中:

    • (1)tcl_service:应该是与 tcl 语法相关的 tcp 连接,暂时未用到
    • (2)telnet_service:创建 telnet 相关的 tcp 连接,主要作用是让我们可以通过 telnet 连接到 OpenOCD 服务端,OpenOCD 支持的所有命令均可以在 telnet 连接后执行,也是我编写芯片烧录驱动的主要测试方式。

2 执行 init 命令

  • 1)OpenOCD 通过 command_run_line(ctx, "init") 执行 init 命令的逻辑如下:

这可能就是所谓的冰山一角吧:看着是一条 init 命令,其实内部执行一系列的初始化操作。

2.1 target init

  • 1)target init 命令的大概执行逻辑如下:

  • 2)init_targets、init_target_events、init_board 三个命令是定义在 src/target/startup.tcl 文件中三个调用过程 proc。可以让用户在初始化过程中的进行功能补充。

  • 3)接下来在 target_init() 函数中,主要有以下内容:

    • (1)根据全局变量 struct target *all_targets; 遍历所有 target,并通过 target->type->init_target() 函数指针进行 target_type 的初始化,最后对 target_type 进行其它属性填充。关于 target_type,上一节中创建 target 时,我们提到:

    • (2)通过 target_register_user_commands() 函数注册 target 相关命令,如 target_request debugmsgs,trace history, reg/poll/halt/resume/reset/mdd[w/h/b]/mwd[w/h/b]/verify_image 等等

    • (3)通过将 handle_target() 函数指针注册给 target_timer_callbacks,获得处理 srst 与 power 事件的能力。

  • 4)关于 target_type->init_target() 的初始化,以 cortexm_target 为例:

    • 百度上说,Semihosting 技术是将目标板的输入/输出请求从应用程序代码传递到远程运行调试器的主机的一种机制。

2.2 adapter_init()

  • 1)adapter 初始化的逻辑如下(右侧还是以 cmsis-dap 为例):

  • 2)首先进行 adapter_driver 的初始化(这里为 cmsis-dap),都是 cmsis-dap 相关的细节,有时间我们再通过 DAPLink 项目深入学习。

  • 3)然后是设置 adapter 的速度。这里首先设置速度,然后会再读取 adapter 的实际速度。

2.3 其它命令

剩余的命令就不再一一分析了,这里仅列出命令的执行函数入口以供有兴趣者研究。

command handler function entry location 概要说明
transport init handle_transport_init() src/transport/transport.c 对命令 'transport select <transport>' 中的 <transport> 进行初始化,包括 swd、jtag 等
dap init handle_dap_init() src/target/arm_dap.c 对 DAP(Debug Access Port)进行初始化。
flash init handle_flash_init_command() src/flash/nor/tcl.c 注册了许多 flash 开头的命令,如检测命令 flash probe、擦除扇区命令 flash erase_check 等
nand init handle_nand_init_command() src/flash/nand/tcl.c 注册了许多 nand 开头的命令,可能是操作 nand 类存储设备的命令
pld init handle_pld_init_command() src/pld/pld.c pld,Programmable Logic Device,不太明白,不敢妄言
tpiu init handle_arm_tpiu_swo_init() src/target/arm_tpiu_swo.c 完全不懂

以上命令不再作解析,因为有些内容我实在搞不明白,这里仅做逻辑记录,待日后有机会再深入了解。

3 server_loop()

  • 1)该函数遍历 service,并以 select 的方式对其内部的 socket 进行轮询。

  • 2)从前面几章我们知道,OpenOCD 中一共有以下几种 service:

名称 端口 简述
gdb service 3333 用于 gdb 调试
telnet service 4444 执行擦除、烧录、读取等命令
jtag vpi 5555 没用到过,不了解
tcl service 6666 猜测是用来执行 tcl 文件中命令的
jsp service 7777 没用到过,不了解
rtt service xxxx Real Time Transfer,类比 SEGGER 的 RTT,通过 rtt start [message] 指定

通过 telnet ip:port 连接到 OpenOCD 后,根据连接的端口,由对应的 Service 进行命令处理。我们已经了解通过 4444 端口的烧录等命令处理。
下一次,我们将了解通过 RTT service 来打印 DAPLINK 日志的方式。

posted @ 2024-09-30 11:19  送南阳马生序  阅读(0)  评论(0编辑  收藏  举报