From b772127dad2c728d48bfed2ec7f254e3a88e00e9 Mon Sep 17 00:00:00 2001 From: shenmengjing Date: Fri, 20 Dec 2024 14:52:00 +0800 Subject: [PATCH] docs: Provide CN translation for debugproject.rst --- docs_espressif/en/debugproject.rst | 212 ++++++++++++------------- docs_espressif/en/monitoroutput.rst | 2 +- docs_espressif/zh_CN/debugproject.rst | 216 +++++++++++++++++++++++++- 3 files changed, 313 insertions(+), 117 deletions(-) diff --git a/docs_espressif/en/debugproject.rst b/docs_espressif/en/debugproject.rst index 0f2bf1b3d..37253fc83 100644 --- a/docs_espressif/en/debugproject.rst +++ b/docs_espressif/en/debugproject.rst @@ -1,233 +1,215 @@ Debug Your Project -=============================== +================== -Table of Content (ToC) --------------------------------- - -1. :ref:`Start a debug session` - -2. :ref:`What happens in the background?` - -3. :ref:`Setting a custom application image offset` - -4. :ref:`Navigating Through the Code, Call Stack and Threads` +:link_to_translation:`zh_CN:[中文]` -5. :ref:`Setting and Clearing Breakpoints` +Table of Contents +================== -6. :ref:`Halting the Target Manually` +.. contents:: + :depth: 2 + :local: -7. :ref:`Stepping Through the Code` -8. :ref:`Watching and Setting Program Variables` +Starting a Debug Session +------------------------ -9. :ref:`Setting Conditional Breakpoint` +Before debugging the project, you need to specify the serial port of the device: -10. :ref:`Disassembly view` +1. Select the serial port -11. :ref:`Watchpoints (Data Breakpoints)` - -12. :ref:`Send commands to GDB` - -13. :ref:`ESP-IDF: Peripheral View` - -14. :ref:`Post-mortem debug use cases` - - -Start a debug session --------------------------------- - -Before debbugging the project, you needs to specify the serial port of the device: - -1. Select the Serial Port: - -- Navigate to **View** > **Command Palette**. +- Navigate to ``View`` > ``Command Palette``. - Type **ESP-IDF: Select Port to Use** and select the command to specify the serial port of your device. -2. Make sure that openOCD configuration files are correct by: +2. Make sure that OpenOCD configuration files are correct -- Navigate to **View** > **Command Palette**. +- Navigate to ``View`` > ``Command Palette``. -- Type **ESP-IDF: Select OpenOCD Board Configuration** and select the command to to choose the OpenOCD configuration files for the extension OpenOCD server. +- Type **ESP-IDF: Select OpenOCD Board Configuration** and select the command to choose the OpenOCD configuration files for the extension OpenOCD server. .. note:: - * Please review `Configuration of OpenOCD for Specific Target `_ to understand which board or configuration to use for your specific hardware. - * Make sure to configure your drivers as mentioned in ESP-IDF `Configure JTAG Interface `_ documentation. -- (Linux users) Make sure to copy the `OpenOCD udev rules files `_ into the ``/etc/udev/rules.d`` directory before running OpenOCD and starting a debug session. + * Please review `Configuration of OpenOCD for Specific Target `_ to understand which board or configuration to use for your specific hardware. + * Make sure to configure your drivers as mentioned in ESP-IDF `Configure JTAG Interface `_ documentation. + +- (Linux users) Copy the `OpenOCD udev rules files `_ into the ``/etc/udev/rules.d`` directory before running OpenOCD and starting a debug session. -To start debugging select menu **Run** and **Start Debugging** or just press F5. +To start debugging, select ``Run`` > ``Start Debugging`` from the menu or press F5. .. image:: ../../media/tutorials/debug/init_halted.png -You can see the output from GDB in the debug console and the OpenOCD output in the menu **View** > **Output** > Select **ESP-IDF** from dropdown output. +You can see the GDB output in the debug console and the OpenOCD output under ``View`` > ``Output`` by selecting ``ESP-IDF`` from the dropdown menu. -This cover the basic functionality of the ESP-IDF extension. Take a look at the :ref:`Additional IDE Features` documentation for more. +The above covers the basic functionality of the ESP-IDF extension. For more information, please refer to :ref:`Additional IDE Features `. -What happens in the background? -------------------------------------- +Debugging Process Overview +-------------------------- .. figure:: ../_static/jtag-debugging-overview.jpg :align: center - :alt: JTAG debugging - overview diagram + :alt: JTAG debugging – overview diagram :figclass: align-center - JTAG debugging - overview diagram + JTAG debugging – overview diagram -1. First OpenOCD server is launched in the background and the output is shown in menu **View** > **Output** > Select **ESP-IDF** from the dropdown. +1. First, the OpenOCD server is launched in the background and the output appears under menu ``View`` > ``Output`` by selecting ``ESP-IDF`` from the dropdown menu. -By default it will be launched using localhost, port ``4444`` for Telnet communication, port ``6666`` for TCL communication and port ``3333`` for GDB. you can modify **openocd.tcl.host** and **openocd.tcl.port** configuration settings to modify these values. You can also set **idf.openOcdDebugLevel** to lower or increase (0-4) the messages from OpenOCD in the ESP-IDF output. + By default, the OpenOCD server is launched on localhost, port ``4444`` for Telnet communication, port ``6666`` for TCL communication and port ``3333`` for GDB. You can change these settings by modifying ``openocd.tcl.host`` and ``openocd.tcl.port``. You can adjust the verbosity of OpenOCD messages displayed in the ESP-IDF output by setting ``idf.openOcdDebugLevel``. The value can range from 0 to 4. -2. Next The `Eclipse CDT GDB Adapter `_ is launched in the background and the output is shown in the ``Debug Console``. This debug adapter will start the connection to the device by launch the GDB debug session. +2. Next, the `Eclipse CDT GDB Adapter `_ is launched in the background, with its output shown in the ``Debug Console``. This adapter initiates the GDB debug session to connect to the device. -This adapter is a middle man between Visual Studio Code, configured toolchain GDB and OpenOCD server. You can see how `Espressif chips debugging works `_ and how Visual Studio Code use `Debug adapters `_ to communicate with many debug tools. + This adapter acts as an intermediary between Visual Studio Code, the configured toolchain GDB and the OpenOCD server. Learn more about `Espressif chips debugging `_ and how Visual Studio Code uses `debug adapters `_ to communicate with various debug tools. -Setting a custom application image offset -------------------------------------------------------------- +Setting a Custom Application Image Offset +----------------------------------------- -If you modify the application image offset you need to modify openOCD launch arguments to update the application image offset. This can happens if OpenOCD output (Menu View -> Output -> `ESP-IDF`) shows an error like this: +If you modify the application image offset, you need to update OpenOCD launch arguments accordingly. This is necessary if the OpenOCD output (Menu ``View`` > ``Output`` > ``ESP-IDF``) shows an error like: .. code-block:: - Failed to get flash maps (-6)! - ❌ Error: Failed to get flash maps (-6)! - Warn : Application image is invalid! Check configured binary flash offset 'appimage_offset'. + Failed to get flash maps (-6)! + ❌ Error: Failed to get flash maps (-6)! + Warn : Application image is invalid! Check configured binary flash offset 'appimage_offset'. -To update openOCD launch arguments, open the project's ``.vscode/settings.json`` and add or modify: +To update OpenOCD launch arguments, open the project's ``.vscode/settings.json`` and add or modify: .. code-block:: JSON - { - "idf.openOcdLaunchArgs": [ - "-c", - "init", - "-c", - "reset halt", - "-c", - "esp appimage_offset 0x20000" - ] - } + { + "idf.openOcdLaunchArgs": [ + "-c", + "init", + "-c", + "reset halt", + "-c", + "esp appimage_offset 0x20000" + ] + } where ``0x20000`` is your application image offset used in the partition table. -Navigating Through the Code, Call Stack and Threads -------------------------------------------------------- +Navigating through the Code, Call Stack and Threads +--------------------------------------------------- -When the target is halted, the editor will show the line of code where the program halted and the list of threads in the ``Call Stack`` sub-window ``(a)`` on the ``Run`` icon in the Activity Bar on the side of Visual Studio Code. The first line of call stack under main ``(b)`` contains the last called function ``app_main()``, which in turned was called from ``main_task()`` as shown in the previous image. Each line of the stack also contains the file name and line number ``(c)`` where the function was called. By clicking on each of the stack entries, you will see the file opened. +When the target halts, the editor will show the line of code where the program halts and the list of threads in the ``Call Stack`` sub-window ``(a)`` on the ``Run`` icon in the Activity Bar on the side of Visual Studio Code. The first line of call stack under main ``(b)`` contains the last called function ``app_main()``, which in turn was called from ``main_task()`` as shown in the previous image. Each line of the stack also contains the file name and line number ``(c)`` where the function was called. By clicking on each of the stack entries, you will see the file opened. -By expanding threads you can navigate throughout the application. Some threads contains much longer call stack where you can see, besides function calls, numbers like ``0x4000bff0`` representing address of binary code not provided in source form. +By expanding threads, you can navigate throughout the application. Some threads contain longer call stacks where you can see, besides function calls, numbers like ``0x4000bff0``, representing addresses of binary code not provided in source form. .. image:: ../../media/tutorials/debug/thread5.png -Go back to the ``app_main()`` in Thread #1 to familiar code of blink.c file that will be examined in more details in the following examples. Debugger makes it easy to navigate through the code of entire application. This comes handy when stepping through the code and working with breakpoints and will be discussed below. +Go back to the ``app_main()`` in Thread #1 to familiarize yourself with the code in the ``blink.c`` file, which will be examined in more detail in the following examples. Debugger makes it easy to navigate through the code of entire application. This is useful when stepping through the code and working with breakpoints, as will be discussed below. Setting and Clearing Breakpoints -------------------------------------------------------- +-------------------------------- -When debugging, we would like to be able to stop the application at critical lines of code and then examine the state of specific variables, memory and registers / peripherals. To do so we are using breakpoints. They provide a convenient way to quickly get to and halt the application at specific line. +When debugging, you often need to pause the application at critical points in the code to examine the state of specific variables, memory, registers and peripherals. To achieve this, you can use breakpoints, which provide a convenient way to quickly halt the application at a specific line of code. -Let's establish two breakpoints when the state of LED changes. Based on the code listing above, this happens at lines 57 and 80. To set a breakpoint, go to the desired line and press F9 or click on the circle shown next to the line number (editor margin). The list of breakpoints is shown in the ``Breakpoints`` sub-window on the ``Run`` icon in the Activity Bar on the side of Visual Studio Code. +For example, establish two breakpoints where the state of LED changes. Based on the code listing below, this happens at lines 57 and 80. To set a breakpoint, go to the desired line and press F9 or click on the circle shown next to the line number in the editor margin. The list of breakpoints appears in the ``Breakpoints`` sub-window under the ``Run`` icon in the Activity Bar on the side of Visual Studio Code. .. image:: ../../media/tutorials/debug/breakpoint.png .. note:: - Consider that ESP32 has a maximum of 2 hardware breakpoints. Please look at `ESP-IDF Debugging tips: Breakpoints `_ for more information. -The Visual Studio Code shows a **Debug toolbar** on the top of the editor with several actions as explained in `Visual Studio Code Debug Actions `_. + ESP32 supports a maximum of two hardware breakpoints. For more information, refer to `Breakpoints and Watchpoints Available `_. + +Once a debug session starts, a **debug toolbar** will appear on the top of the VS Code editor with several actions, as explained in `Visual Studio Code Debug Actions `_. -If you press F5 (Continue/Pause) the processor will run and halt at the next breakpoint. If you press F5 again, it will stop at the next breakpoint and so on. you will be able to see that LED is changing the state after each click to "Continue" program execution. +Press F5 (Continue/Pause), the processor will run and halt at the next breakpoint. Press F5 again to stop at the next breakpoint, and so on. You can observe that the LED changes the state after each "Continue" command. -Read more about breakpoints under `breakpoints and watchpoints available `_ and `what else should i know about breakpoints? `_. +Learn more about breakpoints under `What Else Should I Know About Breakpoints? `_. Halting the Target Manually -------------------------------------------------------- +--------------------------- -When debugging, you may resume application and enter code waiting for some event or staying in infinite loop without any break points defined. In such case, to go back to debugging mode, you can break program execution manually by pressing "Continue/Pause" button. To check it, delete all breakpoints and click "Continue". Then click “Pause”. Application will be halted at some random point and LED will stop blinking. +When debugging, you may resume the application and enter code that waits for some event or stays in infinite loop without any break points defined. In such cases, to go back to debugging mode, you can break program execution manually by pressing "Continue/Pause" button. To check it, delete all breakpoints and click "Continue". Then click “Pause”. Application will halt at some random point and the LED will stop blinking. -It is also possible to step through the code using “Step Into (F11)” and “Step Over (F10)” commands. The difference is that “Step Into (F11)” is entering inside subroutines calls, while “Step Over (F10)” steps over the call, treating it as a single source line. +You can also step through the code using the "Step Into (F11)" and "Step Over (F10)" commands. The difference is that “Step Into (F11)” enters inside subroutine calls, while “Step Over (F10)” treats it as a single source line. -Before being able to demonstrate this functionality, using information discussed in previous paragraph, make sure that you have only one breakpoint defined at line 57 of ``blink.c``. +Before demonstrating this functionality, make sure that you have only one breakpoint defined at line 57 of ``blink.c`` using information discussed in previous paragraphs. -Resume program by entering pressing F5 and let it halt. Now press “Step Over (F10)”, one by one couple of times, to see how debugger is stepping one program line at a time. +Resume the program by pressing F5 and let it halt. Now press "Step Over (F10)" a few times to see how the debugger steps through the program one line at a time. .. image:: ../../media/tutorials/debug/step_over.png Stepping Through the Code -------------------------------------------------------- +------------------------- -If you press “Step Into (F11)” instead, then debugger will step inside subroutine call. +If you press "Step Into (F11)" instead, then debugger will step inside the subroutine call. .. image:: ../../media/tutorials/debug/step_into.png -In this particular case debugger stepped inside ``vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS)`` and effectively moved to `tasks.c` code. +In this case, the debugger steps inside ``vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS)`` and effectively moves to the ``tasks.c`` code. .. note:: - * See `Why stepping with “next” does not bypass subroutine calls? `_ for potential limitations using the ``next`` command. -If you press “Step Out (Shift + F11)” instead, then debugger will step outside the subroutine call. + * See `Why Stepping with "next" Does Not Bypass Subroutine Calls? `_ for potential limitations using the ``next`` command. + +If you press "Step Out (Shift + F11)" instead, then debugger will step outside the subroutine call. .. image:: ../../media/tutorials/debug/step_out.png Watching and Setting Program Variables -------------------------------------------------------- +-------------------------------------- -A common debugging tasks is checking the value of a program variable as the program runs. To be able to demonstrate this functionality, update file ``blink.c`` by adding a declaration of a global variable int i above definition of function ``blink_task``. Then add ``i++`` inside ``while(1)`` of this function to get ``i`` incremented on each blink. +A common debugging task is checking the value of a program variable as the program runs. To demonstrate this functionality, update file ``blink.c`` by declaring a global variable ``int i`` above the definition of the function ``blink_task``. Then add ``i++`` inside ``while(1)`` of this function to increment ``i`` on each blink. -Stop debugging by pressing "Stop (Shift + F5)". Build and flash the code to the ESP and restart the debugger by pressing F5. Once the application is halted, set a breakpoint in the line where ``i++`` is. +Stop debugging by pressing "Stop (Shift + F5)". Build and flash the code to the target chip, then restart the debugger by pressing F5. Once the application halts, set a breakpoint on the line where ``i++`` is located. -Next in the ``Watch`` sub-window on the ``Run`` icon in the Activity Bar on the side of Visual Studio Code, click the ``+`` and enter ``i`` to start watching its value. +In the ``Watch`` sub-window on the ``Run`` icon in the Activity Bar on the side of Visual Studio Code, click the ``+`` and enter ``i`` to start watching its value. -Continue the program execution by pressing F5. Each time the program is halted, you will see ``i`` being incremented. +Resume program execution by pressing F5. Each time the program pauses, the value of ``i`` will have incremented. .. image:: ../../media/tutorials/debug/watch_set_program_vars.png Setting Conditional Breakpoint -------------------------------------------------------- +------------------------------ -You can also set a breakpoint to halt the program execution if a certain condition is satisfied. See `Visual Studio Code conditional breakpoints `_. +You can also set a breakpoint to halt the program execution if a certain condition is satisfied. See `Visual Studio Code Conditional Breakpoints `_. -To set a new conditional breakpoint, go to the desired line and right click on the circle shown next to the line number (editor margin) and select ``Add Conditional Breakpoint`` action. You can also modify a breakpoint to add a condition in the list of breakpoints in the ``Breakpoints`` sub-window on the ``Run`` icon in the Activity Bar on the side of Visual Studio Code. Click the ``pencil`` icon on the breakpoint and set the breakpoint condition. +To set a new conditional breakpoint, go to the desired line, right-click on the circle next to the line number (editor margin), and select ``Add Conditional Breakpoint`` action. You can also modify a breakpoint to add a condition in the list of breakpoints in the ``Breakpoints`` sub-window on the ``Run`` icon in the Activity Bar. Click the ``pencil`` icon on the breakpoint and set the breakpoint condition. -For this example, go to line 79 and right click on the circle shown next to the line number (editor margin) and select ``Add Conditional Breakpoint`` action and set ``i=2``. When you start the debug, it will stop on line 79 when ``i`` has value of 2. +For this example, go to line 79, right-click on the circle next to the line number (editor margin), select ``Add Conditional Breakpoint`` action, and set ``i=2``. When you start debugging, the debugger will stop on line 79 when ``i`` equals 2. .. image:: ../../media/tutorials/debug/conditional_breakpoint.png -Disassembly view -------------------------------------------------------- +Disassembly View +---------------- -You can check the assembly code from the debugging session by doing a right click in any line in of source code file and pressing ``Open Disassembly View``. This will open the **Disassemble View** showing the assembly code with C code where you can set breakpoints too. +You can check the assembly code during a debugging session by right-clicking on any line in in a source code file and selecting ``Open Disassembly View``. **Disassemble View** shows the assembly code with C code, where you can also set breakpoints. .. image:: ../../media/tutorials/debug/disassembly_view.png Watchpoints (Data Breakpoints) -------------------------------------------------------- +------------------------------ -See `ESP-IDF breakpoints and watchpoints available `_ for more information. +See `Breakpoints and Watchpoints Available `_ for more information. -Send commands to GDB -------------------------------------------------------- +Send Commands to GDB +-------------------- -You can send any GDB commands in the Debug console with ``> COMMAND``. For example ``> i threads``. +You can send any GDB command in the debug console with ``> COMMAND``. For example, ``> i threads``. -You can also see binary data variables content clicking ``View Binary Data`` next to variable name. +To view binary data variables, click ``View Binary Data`` next to the variable name. .. image:: ../../media/tutorials/debug/gdb_commands.png -More about `Command Line Debugging `_. +Learn more about `Command Line Debugging `_. + ESP-IDF: Peripheral View -------------------------------------------------------- +------------------------ -Our extension implements a ``ESP-IDF: Peripheral View`` tree view in the ``Run and Debug`` view which will use the SVD file defined in the **IDF Svd File Path (idf.svdFilePath)** configuration setting to populate a set of peripherals registers values for the active debug session target. You could download Espressif SVD files from `Espressif SVD `_ repository. +ESP-IDF extension provides an ``ESP-IDF: Peripheral View`` tree in the ``Run and Debug`` view. This tree view uses the SVD file specified in the ``IDF SVD File Path (idf.svdFilePath)`` configuration to populate a set of peripheral register values for the active debug session target. You can download Espressif SVD files from `Espressif SVD `_ repository. .. image:: ../../media/tutorials/debug/peripheral_viewer.png -Post-mortem debug use cases -------------------------------------------------------- +Post-mortem Debugging Use Cases +------------------------------- -You can start a monitor session that can capture fatal error events with **ESP-IDF: Launch IDF Monitor for CoreDump / GDB-Stub Mode** command and, if configured in your project's sdkconfig, trigger the start of a debug session for GDB remote protocol server (GDBStub) or `ESP-IDF Core Dump `_ when an error is found. Read more in the `panic handler documentation `_. +You can start a monitor session to capture fatal error events with **ESP-IDF: Launch IDF Monitor for Core Dump Mode/GDB Stub Modec** command. If configured in your project's sdkconfig, it can trigger the start of a debug session for GDB remote protocol server (GDBStub) or `ESP-IDF Core Dump `_ when an error occurrs. For more information, see `Panic Handler `_. - **Core Dump** is configured when **Core Dump's Data Destination** is set to either ``UART`` or ``FLASH`` using the **ESP-IDF: SDK Configuration Editor** extension command or ``idf.py menuconfig`` in a terminal. -- **GDB Stub** is configured when **Panic Handler Behaviour** is set to ``Invoke GDBStub`` using the **ESP-IDF: SDK Configuration Editor** extension command or ``idf.py menuconfig`` in a terminal. \ No newline at end of file +- **GDB Stub** is configured when ``Panic Handler Behaviour`` is set to ``Invoke GDBStub`` using the **ESP-IDF: SDK Configuration Editor** extension command or ``idf.py menuconfig`` in a terminal. diff --git a/docs_espressif/en/monitoroutput.rst b/docs_espressif/en/monitoroutput.rst index c67dfeddb..15c3867d2 100644 --- a/docs_espressif/en/monitoroutput.rst +++ b/docs_espressif/en/monitoroutput.rst @@ -17,7 +17,7 @@ To view the serial monitor output from your device, please follow the instructio .. image:: ../../media/tutorials/basic_use/monitor.png -Next step is to :ref:`Debug Your Project `. +Next step is to :doc:`debug your project `. .. note:: * The monitor baud rate is defined with ``CONFIG_ESPTOOLPY_MONITOR_BAUD`` from project's SDK Configuration Editor. You can override it by setting a value in **idf.monitorBaudRate**. \ No newline at end of file diff --git a/docs_espressif/zh_CN/debugproject.rst b/docs_espressif/zh_CN/debugproject.rst index 15bad7e41..b5e66c0d3 100644 --- a/docs_espressif/zh_CN/debugproject.rst +++ b/docs_espressif/zh_CN/debugproject.rst @@ -1 +1,215 @@ -.. include:: ../en/debugproject.rst \ No newline at end of file +调试项目 +======== + +:link_to_translation:`en:[English]` + +目录 +==== + +.. contents:: + :depth: 2 + :local: + + +启动调试会话 +------------ + +在调试项目之前,请先指定设备的串口: + +1. 选择串口: + +- 点击 ``查看`` > ``命令面板``。 + +- 输入 **ESP-IDF:选择要使用的端口**,指定设备的串口。 + +2. 确保 OpenOCD 配置文件正确 + +- 点击 ``查看`` > ``命令面板``。 + +- 输入 **ESP-IDF:选择 OpenOCD 开发板配置**,选择扩展中 OpenOCD 服务器的配置文件。 + +.. note:: + + * 请查看 `根据目标芯片配置 OpenOCD `_,为目标硬件选择开发板或配置。 + * 请确保按照 `配置 JTAG 接口 `_ 中的说明来配置驱动程序。 + +- (适用于 Linux 用户)在运行 OpenOCD 并启动调试会话前,请确保将 `OpenOCD udev 规则文件 `_ 复制到 ``/etc/udev/rules.d`` 目录中。 + +在顶部菜单栏中点击 ``运行`` > ``启动调试``,或者直接按 F5 启动调试。 + +.. image:: ../../media/tutorials/debug/init_halted.png + +可以在调试控制台中查看 GDB 输出。点击 ``查看`` > ``输出``,在下拉菜单中选择 ``ESP-IDF``,可以查看 OpenOCD 输出。 + +以上内容为 ESP-IDF 扩展的基本功能,详情请参阅 :ref:`其他 IDE 功能 `。 + +调试过程概览 +------------ + +.. figure:: ../_static/jtag-debugging-overview.jpg + :align: center + :alt: JTAG 调试 – 概览图 + :figclass: align-center + + JTAG 调试 – 概览图 + +1. 首先,OpenOCD 服务器在后台启动。可以点击菜单栏中的 ``查看`` > ``输出``,并在下拉菜单中选择 ``ESP-IDF`` 来查看输出。 + + 默认情况下,OpenOCD 服务器在当前计算机上启动,并通过端口 ``4444`` 与 Telnet 通信;端口 ``6666`` 用于 TCL 通信;端口 ``3333`` 用于 GDB。通过修改 ``openocd.tcl.host`` 和 ``openocd.tcl.port`` 配置,可以变更以上设置。通过设置 ``idf.openOcdDebugLevel`` 参数(范围是 0~4),可以调整 OpenOCD 在 ESP-IDF 输出窗口中显示消息的详细程度。 + +2. 接下来,`Eclipse CDT GDB 适配器 `_ 在后台启动,输出显示在 ``调试控制台`` 中。该调试适配器将通过启动 GDB 调试会话来连接目标设备。 + + 此适配器是 VS Code、配置的工具链 GDB 以及 OpenOCD 服务器之间的中间桥梁。可参考以下链接,查看 `乐鑫芯片调试工作原理 `_,以及 VS Code 如何使用 `调试适配器 `_ 与不同调试工具进行通信。 + +自定义应用程序镜像偏移量 +------------------------ + +如果修改了应用程序镜像偏移量,则应更新相应的 OpenOCD 启动参数。点击菜单栏 ``查看`` > ``输出``,并在下拉菜单栏中选择 ``ESP-IDF``,如果 OpenOCD 输出显示如下错误,则应立即进行参数更改: + +.. code-block:: + + Failed to get flash maps (-6)! + ❌ Error: Failed to get flash maps (-6)! + Warn : Application image is invalid! Check configured binary flash offset 'appimage_offset'. + +要更新 openOCD 启动参数,请打开项目的 ``.vscode/settings.json`` 文件并添加或修改以下代码: + +.. code-block:: JSON + + { + "idf.openOcdLaunchArgs": [ + "-c", + "init", + "-c", + "reset halt", + "-c", + "esp appimage_offset 0x20000" + ] + } + +其中 ``0x20000`` 是分区表中使用的应用程序镜像偏移量。 + +浏览代码、调用栈和线程 +---------------------- + +目标程序暂停时,编辑器将显示程序在哪一行代码处暂停,同时 VS Code 左侧活动栏 ``运行`` 图标下的 ``调用堆栈`` 子窗口中会出现线程列表(见 ``(a)``)。``调用堆栈`` 子窗口的第一行包含了最后调用的函数 ``app_main()`` (见 ``(b)``)。如前图所示,该函数由 ``main_task()`` 调用。栈的每一行还列出了函数调用自哪一文件的第几行(见 ``(c)``),点击每个栈条目,可以打开相应文件。 + +展开线程就可以浏览整个应用程序。一些线程包含较长的调用栈,除了函数调用外,还可以看到类似 ``0x4000bff0`` 的数字,代表未在源代码中出现的二进制代码地址。 + +.. image:: ../../media/tutorials/debug/thread5.png + +回到线程 #1 中的 ``app_main()`` 函数,熟悉 ``blink.c`` 文件里的代码,后续例程中将展开分析。使用调试器可以快速浏览整个应用程序的代码,尤其是在执行代码和处理断点时非常方便。下文将详细讨论这一功能。 + + +设置和清除断点 +-------------- + +调试时,常常需要在关键代码行暂停应用程序,检查特定变量、存储、寄存器以及外设的状态,断点在此起到了重要作用。断点能帮助快速锁定关键代码行,并在该行暂停应用程序。 + +例如可以在 LED 状态变化处设置两个断点,根据下图中的代码,断点应分别位于第 57 和 80 行。要设置断点,请先转到这两行并按 F9,也可以点击行号左侧的圆点。点击 VS Code 侧边栏的 ``运行``(Run) 图标,在 ``断点`` (Breakpoints) 子窗口中可以查看断点列表。 + +.. image:: ../../media/tutorials/debug/breakpoint.png + +.. note:: + + 请注意,ESP32 最多支持两个硬件断点。详情请参阅 `可用的断点和观察点 `_。 + +启动调试会话后,VS Code 编辑器顶部将出现一个 **调试工具栏**,包含部分快捷操作按钮。详情请参阅 `VS Code 调试操作 `_。 + +按 F5(继续/暂停),处理器将开始运行并在下一个断点处停止;再次按 F5,程序将在下一个断点处停止。依此类推,每次执行“继续”命令时,LED 都会改变状态。 + +更多有关断点的信息,请参阅 `关于断点的补充知识 `_。 + +手动暂停目标 +------------ + +在进行调试时,你可能会恢复应用程序,进入等待某些事件或处于无限循环状态的代码,且没有定义任何断点。此时,若想回到调试模式,可以点击“继续”或“暂停”按钮手动中断程序。若想验证这一点,请删除所有断点并点击“继续”,然后点击“暂停”。如果起作用,那么应用程序将随机暂停,且 LED 停止闪烁。 + +也可以使用“单步调试 (F11)”和“单步跳过 (F10)”命令逐步执行代码。二者的区别在于,“单步调试”能进入子程序调用内部,而“单步跳过”则将整个函数作为一个单元执行完毕。 + +演示此功能前,请先阅读前一章节的内容,确保在 ``blink.c`` 文件的第 57 行只定义了一个断点。 + +按 F5 恢复程序并将其暂停。多次按 F10 单步跳过,观察调试器如何逐行执行程序。 + +.. image:: ../../media/tutorials/debug/step_over.png + +逐行执行代码 +------------ + +如果按 F11 单步调试,则调试器进入子程序调用内部。 + +.. image:: ../../media/tutorials/debug/step_into.png + +此时,调试器进入了 ``vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS)`` 函数内部并跳转到 ``tasks.c`` 文件中的相关代码处。 + +.. note:: + + * 请参阅 `"next" 命令无法跳过子程序的原因 `_,了解 ``next`` 命令存在的限制。 + +如果按 Shift + F11 单步跳出,则调试器将退出子程序调用。 + +.. image:: ../../media/tutorials/debug/step_out.png + +监视和设置程序变量 +------------------ + +常见的调试任务之一是检查程序运行时程序变量的值。若想演示此功能,请先在 ``blink.c`` 文件中函数 ``blink_task`` 定义的上方声明全局变量 ``int i``。然后在此函数的 ``while(1)`` 中添加 ``i++``,以便在每次闪烁时递增 ``i``。 + +按 Shift + F5 停止调试。为目标芯片构建并烧录项目,按 F5 重启调试器。一旦应用程序暂停,请在 ``i++`` 所在行设置一个断点。 + +在 VS Code 侧边栏 ``运行`` 图标下的 ``监视`` 子窗口中,点击 ``+`` 并输入 ``i``,开始监视变量的值。 + +按 F5 继续执行程序。每次程序暂停,都将看到 ``i`` 值递增。 + +.. image:: ../../media/tutorials/debug/watch_set_program_vars.png + +设置条件断点 +------------ + +你也可以设置条件断点,在满足特定条件时停止执行程序。请参阅 `VS Code 条件断点 `_。 + +要设置新的条件断点,请转到所需行并右键单击行号左侧的圆点,选择 ``添加条件断点`` 操作。也可以点击 VS Code 侧边栏的 ``运行`` 图标,找到 ``断点`` 子窗口中的断点列表,点击断点上的铅笔图标并设置条件,从而修改断点。 + +如例图所示,找到第 79 行,右键单击行号边的圆点,选择 ``添加条件断点`` (Add Conditional Breakpoint) 操作,并设置 ``i=2``。开始调试后,当 ``i`` 值为 2 时,调试器将在第 79 行暂停。 + +.. image:: ../../media/tutorials/debug/conditional_breakpoint.png + +反汇编视图 +---------- + +在调试过程中,右键单击源代码文件的任意行并选择 ``打开反汇编视图``,可以查看程序的汇编代码。**反汇编视图** (Disassembly) 展示了与 C 代码对应的汇编代码,你也可以在其中设置断点。 + +.. image:: ../../media/tutorials/debug/disassembly_view.png + +观察点(数据断点) +------------------ + +详情请参阅 `可用的断点和观察点 `_。 + +给 GDB 发送命令 +--------------- + +在调试控制台中使用 ``> COMMAND`` 可以发送任何 GDB 命令。例如 ``> i threads``。 + +点击变量名称旁边的 ``查看二进制数据`` (View Binary Data) 可以查看二进制数据变量。 + +.. image:: ../../media/tutorials/debug/gdb_commands.png + +详情请参阅 `使用命令行的调试示例 `_。 + + +ESP-IDF:外设视图 +----------------- + +ESP-IDF 扩展在 ``运行和调试`` 视图中提供了 ``ESP-IDF:外设视图`` 树视图。该树视图使用 ``IDF SVD 文件路径 (idf.svdFilePath)`` 配置中定义的 SVD 文件,为当前调试会话的目标填充一组外设寄存器值。你可以从 `乐鑫 SVD `_ 仓库下载所需的 SVD 文件。 + +.. image:: ../../media/tutorials/debug/peripheral_viewer.png + + +事后调试用例 +------------ + +启动监视会话,通过 **ESP-IDF:启动 IDF 监视器以支持核心转储模式/GDB 存根模式** 命令找到致命错误事件。若提前在项目的 sdkconfig 文件中启用了特定选项,那么上述命令发现错误时就会触发 GDB 远程协议服务器 (GDBStub) 或 `ESP-IDF 核心转储 `_。详情请参阅 `紧急处理程序 `_。 + +- 配置 **核心转储**:在扩展中使用命令 **ESP-IDF:SDK 配置编辑器** 或在终端中使用 ``idf.py menuconfig``,将 **核心转储的数据目标** 设置为 ``UART`` 或 ``FLASH``。 +- 配置 **GDB Stub**:在扩展中使用命令 **ESP-IDF:SDK 配置编辑器** 或在终端中使用 ``idf.py menuconfig``,将 **紧急处理程序行为** 设置为 ``Invoke GDBStub``。