查看: 971|回复: 0
收起左侧

IDF 监视器

[复制链接]

  离线 

  • TA的每日心情
    慵懒
    2021-7-23 17:16
  • 签到天数: 17 天

    [LV.4]

    发表于 2021-9-16 16:06:14 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 草帽王子 于 2021-9-16 16:05 编辑

    IDF 监视器是一个串行终端程序,用于收发目标设备串口的串行数据,IDF 监视器同时还兼具 IDF 的其他特性。

    在 IDF 中调用以下目标函数可以启用此监视器:
    • 若使用 CMake 编译系统,则请调用:idf.py monitor
    • 若使用传统 GNU Make 编译系统,请调用:make monitor

    操作快捷键

    为了方便与 IDF 监视器进行交互,请使用表中给出的快捷键。

    快捷键

    操作

    描述

    Ctrl+]

    退出监视器程序


    Ctrl+T

    菜单退出键

    按下如下给出的任意键之一,并按指示操作。

    • Ctrl+T


    将菜单字符发送至远程


    • Ctrl+]


    将 exit 字符发送至远程


    • Ctrl+P


    重置目标设备,进入 Bootloader,通过 RTS 线暂停应用程序

    重置目标设备,通过 RTS 线(如已连接)进入 Bootloader,此时开发板不运行任何程序。等待其他设备启动时可以使用此操作。

    • Ctrl+R


    通过 RTS 线重置目标设备

    重置设备,并通过 RTS 线(如已连接)重新启动应用程序。

    • Ctrl+F


    编译并烧录此项目

    暂停 idf_monitor,运行 flash 目标,然后恢复 idf_monitor。任何改动的源文件都会被重新编译,然后重新烧录。如果 idf_monitor 是以参数 -E 启动的,则会运行目标 encrypted-flash。

    • Ctrl+A (或者 A)


    仅编译及烧录应用程序

    暂停 idf_monitor,运行 app-flash 目标,然后恢复 idf_monitor。 这与 flash 类似,但只有主应用程序被编译并被重新烧录。如果 idf_monitor 是以参数 -E 启动的,则会运行目标 encrypted-flash。

    • Ctrl+Y


    停止/恢复在屏幕上打印日志输出

    激活时,会丢弃所有传入的串行数据。允许在不退出监视器的情况下快速暂停和检查日志输出。

    • Ctrl+L


    停止/恢复向文件写入日志输出

    在工程目录下创建一个文件,用于写入日志输出。可使用快捷键停止/恢复该功能(退出 IDF 监视器也会终止该功能)

    • Ctrl+I (或者 I)


    停止/恢复打印时间标记

    IDF 监视器可以在每一行的开头打印一个时间标记。时间标记的格式可以通过 --timestamp-format 命令行参数来改变。

    • Ctrl+H (或者 H)


    显示所有快捷键


    • Ctrl+X (或者 X)


    退出监视器程序


    Ctrl+C

    中断正在运行的应用程序

    暂停 IDF 监视器并运行 GDB 项目调试器,从而在运行时调试应用程序。这需要启 :ref:CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME 选项。


    除了 Ctrl-] 和 Ctrl-T,其他快捷键信号会通过串口发送到目标设备。


    兼具 IDF 特性

    .

    自动解码地址


    ESP-IDF 输出形式为 0x4_______ 的十六进制代码地址后,IDF 监视器将使用 addr2line 查找该地址在源代码中的位置和对应的函数名。


    ESP-IDF 应用程序发生 crash 和 panic 事件时,将产生如下的寄存器转储和回溯:

    1. abort() was called at PC 0x42067cd5 on core 0

    2. Stack dump detected
    3. Core  0 register dump:
    4. MEPC    : 0x40386488  RA      : 0x40386b02  SP      : 0x3fc9a350  GP      : 0x3fc923c0
    5. TP      : 0xa5a5a5a5  T0      : 0x37363534  T1      : 0x7271706f  T2      : 0x33323130
    6. S0/FP   : 0x00000004  S1      : 0x3fc9a3b4  A0      : 0x3fc9a37c  A1      : 0x3fc9a3b2
    7. A2      : 0x00000000  A3      : 0x3fc9a3a9  A4      : 0x00000001  A5      : 0x3fc99000
    8. A6      : 0x7a797877  A7      : 0x76757473  S2      : 0xa5a5a5a5  S3      : 0xa5a5a5a5
    9. S4      : 0xa5a5a5a5  S5      : 0xa5a5a5a5  S6      : 0xa5a5a5a5  S7      : 0xa5a5a5a5
    10. S8      : 0xa5a5a5a5  S9      : 0xa5a5a5a5  S10     : 0xa5a5a5a5  S11     : 0xa5a5a5a5
    11. T3      : 0x6e6d6c6b  T4      : 0x6a696867  T5      : 0x66656463  T6      : 0x62613938
    12. MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000007  MTVAL   : 0x00000000

    13. MHARTID : 0x00000000

    14. Stack memory:
    15. 3fc9a350: 0xa5a5a5a5 0xa5a5a5a5 0x3fc9a3b0 0x403906cc 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a50
    16. 3fc9a370: 0x3fc9a3b4 0x3fc9423c 0x3fc9a3b0 0x726f6261 0x20292874 0x20736177 0x6c6c61635
    17. 3fc9a390: 0x43502074 0x34783020 0x37363032 0x20356463 0x63206e6f 0x2065726f 0x000000300
    18. 3fc9a3b0: 0x00000030 0x36303234 0x35646337 0x3c093700 0x0000002a 0xa5a5a5a5 0x3c0937f48
    19. 3fc9a3d0: 0x00000001 0x3c0917f8 0x3c0937d4 0x0000002a 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a5e
    20. 3fc9a3f0: 0x0001f24c 0x000006c8 0x00000000 0x0001c200 0xffffffff 0xffffffff 0x000000200
    21. 3fc9a410: 0x00001000 0x00000002 0x3c093818 0x3fccb470 0xa5a5a5a5 0xa5a5a5a5 0xa5a5a5a56
    22. .....
    复制代码

    通过分析堆栈转储 IDF 监视器为寄存器转储补充如下信息:

    1. abort() was called at PC 0x42067cd5 on core 0
    2. 0x42067cd5: __assert_func at /builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/newlib/newlib/libc/stdlib/assert.c:62 (discriminator 8)

    3. Stack dump detected
    4. Core  0 register dump:
    5. MEPC    : 0x40386488  RA      : 0x40386b02  SP      : 0x3fc9a350  GP      : 0x3fc923c0
    6. 0x40386488: panic_abort at /home/marius/esp-idf_2/components/esp_system/panic.c:367

    7. 0x40386b02: rtos_int_enter at /home/marius/esp-idf_2/components/freertos/port/riscv/portasm.S:35

    8. TP      : 0xa5a5a5a5  T0      : 0x37363534  T1      : 0x7271706f  T2      : 0x33323130
    9. S0/FP   : 0x00000004  S1      : 0x3fc9a3b4  A0      : 0x3fc9a37c  A1      : 0x3fc9a3b2
    10. A2      : 0x00000000  A3      : 0x3fc9a3a9  A4      : 0x00000001  A5      : 0x3fc99000
    11. A6      : 0x7a797877  A7      : 0x76757473  S2      : 0xa5a5a5a5  S3      : 0xa5a5a5a5
    12. S4      : 0xa5a5a5a5  S5      : 0xa5a5a5a5  S6      : 0xa5a5a5a5  S7      : 0xa5a5a5a5
    13. S8      : 0xa5a5a5a5  S9      : 0xa5a5a5a5  S10     : 0xa5a5a5a5  S11     : 0xa5a5a5a5
    14. T3      : 0x6e6d6c6b  T4      : 0x6a696867  T5      : 0x66656463  T6      : 0x62613938
    15. MSTATUS : 0x00001881  MTVEC   : 0x40380001  MCAUSE  : 0x00000007  MTVAL   : 0x00000000

    16. MHARTID : 0x00000000

    17. Backtrace:
    18. panic_abort (details=details@entry=0x3fc9a37c "abort() was called at PC 0x42067cd5 on core 0") at /home/marius/esp-idf_2/components/esp_system/panic.c:367
    19. 367     *((int *) 0) = 0; // NOLINT(clang-analyzer-core.NullDereference) should be an invalid operation on targets
    20. #0  panic_abort (details=details@entry=0x3fc9a37c "abort() was called at PC 0x42067cd5 on core 0") at /home/marius/esp-idf_2/components/esp_system/panic.c:367
    21. #1  0x40386b02 in esp_system_abort (details=details@entry=0x3fc9a37c "abort() was called at PC 0x42067cd5 on core 0") at /home/marius/esp-idf_2/components/esp_system/system_api.c:108
    22. #2  0x403906cc in abort () at /home/marius/esp-idf_2/components/newlib/abort.c:46
    23. #3  0x42067cd8 in __assert_func (file=file@entry=0x3c0937f4 "", line=line@entry=42, func=func@entry=0x3c0937d4 <__func__.8540> "", failedexpr=failedexpr@entry=0x3c0917f8 "") at /builds/idf/crosstool-NG/.build/riscv32-esp-elf/src/newlib/newlib/libc/stdlib/assert.c:62
    24. #4  0x4200729e in app_main () at ../main/iperf_example_main.c:42
    25. #5  0x42086cd6 in main_task (args=<optimized out>) at /home/marius/esp-idf_2/components/freertos/port/port_common.c:133
    26. #6  0x40389f3a in vPortEnterCritical () at /home/marius/esp-idf_2/components/freertos/port/riscv/port.c:129
    复制代码

    IDF 监视器在后台运行以下命令,解码各地址:

    1. riscv32-esp-elf-addr2line -pfiaC -e build/PROJECT.elf ADDRESS
    复制代码

    注解

    将环境变量 ESP_MONITOR_DECODE 设置为 0 或者调用 idf_monitor.py 的特定命令行选项:idf_monitor.py --disable-address-decoding 来禁止地址解码。


    配置 GDBStub 以启用 GDB


    默认情况下,如果 ESP-IDF 应用程序发生 crash 事件,panic 处理器将在串口上打印相关寄存器和堆栈转储(类似上述情况),然后重置开发板。


    此外,可以配置应用程序在后台运行 GDBStub 并处理运行中的应用程序突然中断事件 (Ctrl+C)。


    或者选择配置 panic 处理器以运行 GDBStub,GDBStub 工具可以与 GDB 项目调试器进行通信,允许读取内存、检查调用堆栈帧和变量等。GDBStub 虽然没有 JTAG 通用,但不需要使用特殊硬件。


    如需在发生 panic 事件时启用 GDBStub,请运行 idf.py menuconfig 打开项目配置菜单,并将 CONFIG_ESP_SYSTEM_PANIC 选项设置为 GDBStub on panic,或者将 CONFIG_ESP_SYSTEM_PANIC 设置为 GDBStub on runtime。


    在这种情况下,如果 panic 处理器被触发或应用程序突然中断 (Ctrl+C),只要 IDF 监视器监控到 GDBStub 已经加载,panic 处理器就会自动暂停串行监控并使用必要的参数运行 GDB。GDB 退出后,通过 RTS 串口线复位开发板。如果未连接 RTS 串口线,请按复位键,手动复位开发板。


    IDF 监控器在后台运行如下命令:

    1. riscv32-esp-elf-gdb -ex "set serial baud BAUD" -ex "target remote PORT" -ex interrupt build/PROJECT.elf :idf_target:`Hello NAME chip`
    复制代码


    输出筛选


    可以调用 idf.py monitor --print-filter="xyz" 启动 IDF 监视器,其中,--print-filter 是输出筛选的参数。参数默认值为空字符串,可打印任何内容。


    若需对打印内容设置限制,可指定 <tag>:<log_level> 等选项,其中 <tag> 是标签字符串,<log_level> 是 {N, E, W, I, D, V, *} 集合中的一个字母,指的是 日志 级别。


    例如,PRINT_FILTER="tag1:W" 只匹配并打印 ESP_LOGW("tag1", ...) 所写的输出,或者写在较低日志详细度级别的输出,即 ESP_LOGE("tag1", ...)。请勿指定 <log_level> 或使用详细级别默认值 *。

    注解

    编译时,可以使用主日志在 日志库 中禁用不需要的输出。也可以使用 IDF 监视器筛选输出来调整筛选设置,且无需重新编译应用程序。


    应用程序标签不能包含空格、星号 *、冒号 :,以便兼容输出筛选功能。


    如果应用程序输出的最后一行后面没有回车,可能会影响输出筛选功能,即,监视器开始打印该行,但后来发现该行不应该被写入。这是一个已知问题,可以通过添加回车来避免此问题(特别是在没有输出紧跟其后的情况下)。


    筛选规则示例


    • * 可用于匹配任何类型标签。但 PRINT_FILTER="*:I tag1:E" 打印关于 tag1 的输出时会报错,这是因为 tag1 规则比 * 规则的优先级高。
    • 默认规则(空)等价于 *:V,因为在详细级别或更低级别匹配任意标签即意味匹配所有内容。
    • "*:N" 不仅抑制了日志功能的输出,也抑制了 printf 的打印输出。为了避免这一问题,请使用 *:E 或更高的冗余级别。
    • 规则 "tag1:V"、"tag1:v"、"tag1:"、"tag1:*" 和 "tag1" 等同。
    • 规则 "tag1:W tag1:E" 等同于 "tag1:E",这是因为后续出现的具有相同名称的标签会覆盖掉前一个标签。
    • 规则 "tag1:I tag2:W" 仅在 Info 详细度级别或更低级别打印 tag1,在 Warning 详细度级别或更低级别打印 tag2。
    • 规则 "tag1:I tag2:W tag3:N" 在本质上等同于上一规则,这是因为 tag3:N 指定 tag3 不打印。
    • tag3:N 在规则 "tag1:I tag2:W tag3:N *:V" 中更有意义,这是因为如果没有 tag3:N,tag3 信息就可能打印出来了;tag1 和 tag2 错误信息会打印在指定的详细度级别(或更低级别),并默认打印所有内容。


    高级筛选规则示例


    如下日志是在没有设置任何筛选选项的情况下获得的:

    1. load:0x40078000,len:13564
    2. entry 0x40078d4c
    3. E (31) esp_image: image at 0x30000 has invalid magic byte
    4. W (31) esp_image: image at 0x30000 has invalid SPI mode 255
    5. E (39) boot: Factory app partition is not bootable
    6. I (568) cpu_start: Pro cpu up.
    7. I (569) heap_init: Initializing. RAM available for dynamic allocation:
    8. I (603) cpu_start: Pro cpu start user code
    9. D (309) light_driver: [light_init, 74]:status: 1, mode: 2
    10. D (318) vfs: esp_vfs_register_fd_range is successful for range <54; 64) and VFS ID 1
    11. I (328) wifi: wifi driver task: 3ffdbf84, prio:23, stack:4096, core=0
    复制代码

    PRINT_FILTER="wifi esp_image:E light_driver:I" 筛选选项捕获的输出如下所示:

    1. E (31) esp_image: image at 0x30000 has invalid magic byte
    2. I (328) wifi: wifi driver task: 3ffdbf84, prio:23, stack:4096, core=0
    复制代码

    PRINT_FILTER="light_driverESP32-C3 单片机芯片-IDF 监视器risc-v单片机中文社区(1) esp_image:N boot:N cpu_start:N vfs:N wifi:N *:V" 选项的输出如下:

    1. load:0x40078000,len:13564
    2. entry 0x40078d4c
    3. I (569) heap_init: Initializing. RAM available for dynamic allocation:
    4. D (309) light_driver: [light_init, 74]:status: 1, mode: 2
    复制代码


    IDF 监视器已知问题

    .

    Windows 环境下已知问题

    • 由于 Windows 控制台限制,有些箭头键及其他一些特殊键无法在 GDB 中使用。
    • 偶然情况下,idf.py 或 make 退出时,可能会在 IDF 监视器恢复之前暂停 30 秒。
    • GDB 运行时,可能会暂停一段时间,然后才开始与 GDBStub 进行通信。






    上一篇:构建系统(CMake 版)
    下一篇:链接器脚本生成机制
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-4-16 23:37 , Processed in 0.923451 second(s), 45 queries .

    快速回复 返回顶部 返回列表