docs(jtag-debugging): add semihosting chapter

Co-authored-by: Shen Mengjing <shenmengjing@espressif.com>
Co-authored-by: Zhang Shu Xian <zhangshuxian@espressif.com>
This commit is contained in:
Samuel Obuch
2026-06-22 12:55:06 +02:00
parent fb14a3e7f4
commit 71e057cfca
5 changed files with 174 additions and 3 deletions

View File

@@ -29,6 +29,8 @@ The document is structured as follows:
If you are not familiar with GDB, check this section for debugging examples provided from :ref:`jtag-debugging-examples-eclipse` as well as from :ref:`jtag-debugging-examples-command-line`.
:ref:`jtag-debugging-building-openocd`
Reference for OpenOCD build workflow when building from sources.
:ref:`jtag-debugging-semihosting`
Introduction to semihosting feature.
:ref:`jtag-debugging-tips-and-quirks`
This section provides collection of tips and quirks related to JTAG debugging of {IDF_TARGET_NAME} with OpenOCD and GDB.
@@ -315,6 +317,18 @@ The examples in this document use the pre-built OpenOCD binary distribution desc
If you need to build OpenOCD from sources for custom requirements, please refer to the `OpenOCD build workflow <https://github.com/espressif/openocd-esp32/blob/master/.github/workflows/build_openocd.yml>`_, which demonstrates how OpenOCD is built for different platforms (Windows, Linux, macOS).
.. _jtag-debugging-semihosting:
Semihosting
-----------
Semihosting is a mechanism that allows code running on the target {IDF_TARGET_NAME} to communicate with the host PC through the debugger connection, e.g., for printing debug messages or reading/writing files.
.. toctree::
:maxdepth: 1
semihosting
.. _jtag-debugging-tips-and-quirks:
Tips and Quirks
@@ -327,7 +341,6 @@ This section provides collection of links to all tips and quirks referred to fro
tips-and-quirks
Related Documents
-----------------
@@ -338,11 +351,13 @@ Related Documents
using-debugger
debugging-examples
semihosting
tips-and-quirks
../app_trace
- :doc:`using-debugger`
- :doc:`debugging-examples`
- :doc:`semihosting`
- :doc:`tips-and-quirks`
- :doc:`../app_trace`
- `Introduction to ESP-Prog Board <https://docs.espressif.com/projects/espressif-esp-iot-solution/en/latest/hw-reference/ESP-Prog_guide.html>`__

View File

@@ -0,0 +1,71 @@
Semihosting Feature
-------------------
Semihosting is a mechanism that lets a program running on the target use I/O facilities on the host machine where the debugger runs. It is useful for debugging and testing embedded applications without having to implement hardware-specific I/O on the target side.
OpenOCD implements an extended semihosting protocol for Espressif targets that goes beyond the standard ARM Semihosting specification. This allows embedded applications to interact with the host system for file operations, directory management, and other system calls.
.. warning::
Each semihosting call is implemented as a sequence containing a software breakpoint instruction. If a build that contains semihosting calls runs **without** a debugger attached, an exception will be triggered instead.
.. note::
Each semihosting call halts the CPU until the host returns a result, so semihosting is not suitable for latency-sensitive or real-time code paths.
.. _jtag-debugging-semihosting-available-operations:
Available Operations
^^^^^^^^^^^^^^^^^^^^
Header :idf_file:`components/vfs/openocd_semihosting.h` declares the full set of available semihosting operations. Common ones include:
* **File Operations**: ``open``, ``close``, ``read``, ``write``, ``lseek``, ``fsync``, ``link``, ``unlink``
* **Directory Operations**: ``opendir``, ``readdir``, ``seekdir``, ``telldir``, ``closedir``, ``mkdir``, ``rmdir``
* **File Attribute Operations**: ``rename``, ``truncate``, ``fstat``, ``stat``, ``utime``, ``access``
In addition, the target can use debugging hooks to trigger events that OpenOCD processes directly:
* ``panic_reason``: notify user about detailed panic information directly in the debugger console.
.. only:: CONFIG_IDF_TARGET_ARCH_RISCV
* ``breakpoint_set``, ``watchpoint_set``: allow configuring breakpoints and watchpoints from the target side, without user interaction.
.. _jtag-debugging-semihosting-using-from-app:
Using Semihosting From an Application
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The most convenient way to use semihosting from application code is through the Virtual File System (VFS) driver. Calling :cpp:func:`esp_vfs_semihost_register` mounts a host directory as a regular VFS path, so that ``fopen``, ``read``, ``write``, and similar standard calls work transparently:
.. code-block:: c
#include "esp_vfs_semihost.h"
esp_vfs_semihost_register("/host");
FILE *f = fopen("/host/log.txt", "w");
See the :doc:`Virtual File System Component API Reference <../../api-reference/storage/vfs>` and the :example:`storage/semihost_vfs` example for the full flow.
See also `OpenOCD semihosting test application <https://github.com/espressif/openocd-esp32/blob/master/testing/esp/test_apps/gen_ut_app/main/semihost_tests.c>`_.
.. _jtag-debugging-semihosting-configuration:
Configuration
^^^^^^^^^^^^^
By default, semihosting file operations use the current directory (where OpenOCD is started) as the base directory. To specify a different base directory, add an extra argument ``-c 'set ESP_SEMIHOST_BASEDIR /path/to/semihost/root'`` to the start of the OpenOCD command line. See :ref:`jtag-debugging-tip-openocd-config-vars`.
.. _jtag-debugging-semihosting-gdb-semihosting:
GDB Semihosting
^^^^^^^^^^^^^^^
GDB also provides built-in support for semihosting, which complements OpenOCD's implementation. This is especially useful when GDB is connected to OpenOCD remotely and runs on a different machine — semihosting file operations then resolve against the GDB host rather than the OpenOCD host.
To redirect semihosting requests to GDB, enter ``mon arm semihosting_fileio enable`` in GDB. For multi-core targets, this only enables semihosting for the current core; use ``mon <target name> arm semihosting_fileio enable`` per core if needed (targets can be listed with ``mon targets``).
With file I/O enabled, OpenOCD does not process the system operation itself after intercepting a semihosting call. Instead, it sends a file I/O request packet to GDB and keeps the target halted until GDB responds with the result. This process is fully transparent to the code running on the target.

View File

@@ -29,6 +29,8 @@ JTAG 调试
如果你不熟悉 GDB请查看此小节以获取 :ref:`Eclipse 集成开发环境 <jtag-debugging-examples-eclipse>` 以及 :ref:`命令行终端 <jtag-debugging-examples-command-line>` 提供的调试示例。
:ref:`jtag-debugging-building-openocd`
OpenOCD 源码构建流程参考。
:ref:`jtag-debugging-semihosting`
介绍 semihosting 功能。
:ref:`jtag-debugging-tips-and-quirks`
介绍使用 OpenOCD 和 GDB 通过 JTAG 接口调试 {IDF_TARGET_NAME} 时的注意事项和补充内容。
@@ -315,6 +317,18 @@ OpenOCD 烧录命令 ``program_esp_bins`` 格式如下:
如需根据特定需求从源码构建 OpenOCD请参考 `OpenOCD 构建工作流程 <https://github.com/espressif/openocd-esp32/blob/master/.github/workflows/build_openocd.yml>`_。该工作流演示了如何在不同平台 (Windows, Linux, macOS) 上构建 OpenOCD。
.. _jtag-debugging-semihosting:
semihosting
-----------
借助 semihosting 机制,运行在 {IDF_TARGET_NAME} 上的代码能够通过调试器与主机 PC 进行通信,例如打印调试信息或读写文件等。
.. toctree::
:maxdepth: 1
semihosting
.. _jtag-debugging-tips-and-quirks:
注意事项和补充内容
@@ -338,11 +352,13 @@ OpenOCD 烧录命令 ``program_esp_bins`` 格式如下:
using-debugger
debugging-examples
semihosting
tips-and-quirks
../app_trace
- :doc:`using-debugger`
- :doc:`debugging-examples`
- :doc:`semihosting`
- :doc:`tips-and-quirks`
- :doc:`../app_trace`
- `ESP-Prog 调试板介绍 <https://docs.espressif.com/projects/espressif-esp-iot-solution/zh_CN/latest/hw-reference/ESP-Prog_guide.html>`__

View File

@@ -0,0 +1,71 @@
semihosting 功能
----------------
借助 semihosting 机制,在目标设备上运行的程序可以使用调试器所在主机上的 I/O 功能。该机制适用于嵌入式应用的调试与测试,而无需在目标端实现特定硬件相关的 I/O 功能。
OpenOCD 为乐鑫目标芯片实现了扩展的 semihosting 协议,其功能超出了标准 ARM semihosting 规范。这使嵌入式应用能够与主机系统进行交互,以执行文件操作、目录管理以及其他系统调用。
.. warning::
每个 semihosting 调用都通过包含软件断点指令的序列实现。如果包含 semihosting 调用的程序在 **未连接调试器** 的情况下运行,则会触发异常。
.. note::
每个 semihosting 调用都会暂停 CPU直到主机返回结果。因此semihosting 不适用于对延迟敏感或对实时性要求较高的代码路径。
.. _jtag-debugging-semihosting-available-operations:
支持的操作
^^^^^^^^^^
头文件 :idf_file:`components/vfs/openocd_semihosting.h` 声明了所有可用的 semihosting 操作。常见操作包括:
* **文件操作**``open````close````read````write````lseek````fsync````link````unlink``
* **目录操作**``opendir````readdir````seekdir````telldir````closedir````mkdir````rmdir``
* **文件属性操作**``rename````truncate````fstat````stat````utime````access``
此外,目标端还可以使用调试钩子触发由 OpenOCD 直接处理的事件:
* ``panic_reason``:直接在调试器控制台中向用户输出详细的 panic 信息。
.. only:: CONFIG_IDF_TARGET_ARCH_RISCV
* ``breakpoint_set````watchpoint_set``:允许在目标端配置断点和观察点,而无需用户手动操作。
.. _jtag-debugging-semihosting-using-from-app:
在应用中使用 semihosting
^^^^^^^^^^^^^^^^^^^^^^^^
在应用代码中使用 semihosting 最便捷的方法是通过虚拟文件系统 (VFS) 驱动。调用 :cpp:func:`esp_vfs_semihost_register` 可将主机目录挂载为普通 VFS 路径,从而无需额外适配即可使用 ``fopen````read````write`` 等标准接口:
.. code-block:: c
#include "esp_vfs_semihost.h"
esp_vfs_semihost_register("/host");
FILE *f = fopen("/host/log.txt", "w");
完整使用流程请参考 :doc:`虚拟文件系统组件 API 参考 <../../api-reference/storage/vfs>` 以及 :example:`storage/semihost_vfs` 示例。
也可以参阅 `OpenOCD semihosting 测试应用 <https://github.com/espressif/openocd-esp32/blob/master/testing/esp/test_apps/gen_ut_app/main/semihost_tests.c>`_
.. _jtag-debugging-semihosting-configuration:
配置
^^^^
默认情况下semihosting 文件操作会使用当前目录(即启动 OpenOCD 时所在的目录)作为基础目录。若需指定其他基础目录,请在 OpenOCD 启动命令开头添加额外参数 ``-c 'set ESP_SEMIHOST_BASEDIR /path/to/semihost/root'``,详见 :ref:`jtag-debugging-tip-openocd-config-vars`
.. _jtag-debugging-semihosting-gdb-semihosting:
GDB semihosting
^^^^^^^^^^^^^^^
GDB 也提供了内置的 semihosting 支持,可作为 OpenOCD 实现的补充。当 GDB 以远程方式连接 OpenOCD并运行在另一台主机上时这一功能尤其有用。因为此时 semihosting 文件操作会基于 GDB 所在主机,而不是 OpenOCD 所在主机进行解析。
若要将 semihosting 请求重定向到 GDB请在 GDB 中输入 ``mon arm semihosting_fileio enable``。对于多核目标,该命令仅会为当前核心启用 semihosting如有需要可针对每个核心分别执行 ``mon <target name> arm semihosting_fileio enable`` (可通过 ``mon targets`` 查看目标列表)。
启用文件 I/O 功能后OpenOCD 在截获系统调用后不会自行处理该操作,而是向 GDB 发送文件 I/O 请求数据包,并保持目标暂停状态,直到 GDB 返回结果。对于运行在目标端的代码而言,这一过程是完全透明的。

View File

@@ -73,8 +73,6 @@ openocd -c "set ESP_SEMIHOST_BASEDIR %IDF_PATH%/examples/storage/semihost_vfs/da
The above command will set `ESP_SEMIHOST_BASEDIR` variable to `examples/storage/semihost_vfs/data` subdirectory of ESP-IDF. With that, it is not necessary to run OpenOCD from that specific directory.
> Note: This feature is not available for RISC-V based SoCs (ESP32-C3, ESP32-H2). To set the semihosting base directory, change into the required directory before running `openocd` command.
## Example output
There are two outputs produced by example: