# 嵌入式调试

运行 PX4 的自动驾驶仪支持通过 GDB 或 LLDB 进行调试。

# 识别内存消耗大户

下面的命令将列出最大的静态分配:

arm-none-eabi-nm --size-sort --print-size --radix=dec build/px4_fmu-v2_default/px4_fmu-v2_default.elf | grep " [bBdD] ";

该 NSH 命令提供剩余的可用内存:

免费的

顶部命令显示每个应用程序的堆栈使用情况:

顶级

堆栈使用量是通过堆栈着色计算的,因此不是当前的使用量,而是任务开始以来的最大值。

# 堆分配

在 POSIX 上,可以通过 SITL 追踪动态堆分配。 gperftools (打开新窗口).

# 安装说明

# 乌班图
苏都 apt-get 安装 google-perftools libgoogle-perftools-dev

# 开始堆剖析

首先,按如下步骤构建固件:

生产 px4_sitl_default

启动 jmavsim: ./Tools/jmavsim_run.sh -l

在另一个终端,键入

CD build/px4_sitl_default/tmp/rootfs
出口 HEAPPROFILE=/tmp/heapprofile.hprof
出口 堆配置文件时间间隔=30

请根据系统输入:

# Fedora
环境 LD_PRELOAD=/lib64/libtcmalloc.so PX4_SIM_MODEL=马兰花 ../../bin/px4 ../../etc -s etc/init.d-posix/rcS pprof --pdf ../../bin/px4 /tmp/heapprofile.hprof.0001.heap >; heap.pdf
# 乌班图
环境 LD_PRELOAD=/usr/lib/libtcmalloc.so PX4_SIM_MODEL=马兰花 ../../bin/px4 ../../etc -s etc/init.d-posix/rcS google-pprof --pdf ../../bin/px4 /tmp/heapprofile.hprof.0001.heap >; heap.pdf

它将生成一份 pdf 文件,其中包含堆分配图。图表中的数字全部为零,因为它们的单位是 MB。只需查看百分比即可。它们显示的是实时内存(节点和子树的内存),即最后仍在使用的内存。

参见 gperftools 文档 (打开新窗口) 了解更多信息。

# 硬故障调试

硬故障是 CPU 执行无效指令或访问无效内存地址时的一种状态。当 RAM 中的关键区域已损坏时,可能会出现这种情况。

# 视频

以下视频演示了使用 Eclipse 和 JTAG 调试器在 PX4 上进行硬故障调试。该视频在 2019 年 PX4 开发人员大会上播放。

# 调试 NuttX 中的硬故障

可能导致硬故障的典型情况是处理器覆盖堆栈,然后处理器从堆栈返回无效地址。这可能是由于代码中的一个错误造成的,即一个乱指针破坏了堆栈,或者另一个任务覆盖了这个任务的堆栈。

  • NuttX 维护两个堆栈:用于中断处理的 IRQ 堆栈和用户堆栈
  • 堆栈是向下增长的。因此,下面示例中的最高地址是 0x20021060,大小是 0x11f4(4596 字节),因此最低地址是 0x2001fe6c。
在 file:armv7-m/up_hardfault.c 行断言失败: 184 任务:ekf_att_pos_estimator sp:20003f90 IRQ 堆栈:基数:20003fdc 大小:000002e8 20003f80:080d27c6 20003f90 20021060 0809b8d5 080d288c 000000b8 08097155 00000010 20003fa0: 20003ce0 00000003 00000000 0809bb61 0809bb4d 080a6857 e000ed24 080a3879 20003fc0: 00000000 2001f578 080ca038 000182b8 20017cc0 0809bad1 20020c14 00000000 Sp: 20020ce8 用户栈: base: 20021060
  size: 000011f4 20020ce0: 60000010 2001F578 2001F578 080CA038 000182B8 0808439F 2001FB88 20020D4C 20020D00: 20020D44 080A1073 666B655B 65686320 205d6b63 6f6c6576 79746963 76696420
20020d20: 65747265 63202C64 6B636568 63636120 63206c65 69666e6f 08020067 0805c4eb 20020d40: 080ca9d4 0805c21b 080ca1cc 080ca9d4 385833fb 38217db9 00000000 080ca964 20020d60: 080ca980 080ca9a0 080ca9bc 080ca9d4 080ca9fc 080caa14 20022824 00000002 20020d80: 2002218c 0806a30f 08069ab2 81000000 3f7fffec 00000000 3b4ae00c 3b12eaa6 20020da0: 00000000 00000000 080ca010 4281fb70 20020f78 20017cc0 20020f98 20017cdc 20020dc0: 2001ee0c 0808d7ff 080ca010 00000000 3f800000 00000000 080ca020 3aa35c4e 20020de0: 3834d331 00000000 010101 00000000 01010001 000d4f89 000d4f89 000f9fda 20020e00:3f7d8df4 3bac67ea 3ca594e6 be0b9299 40b643aa 41ebe4ed bcc04e1b 43e89c96 20020e20: 448f3bc9 c3c50317 b4c8d827 362d3366 b49d74cf ba966159 00000000 00000000 20020e40:3eb4da7b 3b96b9b7 3eead66a 00000000 00000000 00000000 00000000 00000000 20020e60: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 20020e80:00000016 00000000 00000000 00010000 00000000 3c23d70a 00000000 00000000 20020ea0: 00000000 20020f78 00000000 2001ed20 20020fa4 2001f498 2001f1a8 2001f500 20020ec0: 2001f520 00000003 2001f170 ffffffe9 3b831ad2 3c23d70a 00000000 00000000 20020ee0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 20020f00:00000000 00000000 00000000 00000000 2001f4f0 2001f4a0 3d093964 00000001 20020f20: 00000000 0808ae91 20012d10 2001da40 0000260b 2001f577 2001da40 0000260b 20020f40:2001F1A8 08087FD7 08087F9D 080CF448 0000260B 080AFAB1 080AFA9D 00000003 20020F60: 2001F577 0809C577 2001ED20 2001F4D8 2001F498 0805E077 2001F568 20024540
20020f80: 00000000 00000000 00000000 0000260b 3d093a57 00000000 2001f540 2001f4f0 20020fa0: 0000260b 3ea5b000 3ddbf5fa 00000000 3c23d70a 00000000 00000000 000f423f 20020fc0: 00000000 000182b8 20017cc0 2001ed20 2001f4e8 00000000 2001f120 0805ea0d 20020fe0: 2001f090 2001f120 2001eda8 ffffffff 000182b8 00000000 00000000 00000000
20021000:00000000 00000000 00000009 00000000 08090001 2001F93C 0000000C 00000000
20021020:00000101 2001F96C 00000000 00000000 00000000 00000000 00000000 00000000
20021040:00000000 00000000 00000000 00000000 0809866d 00000000 00000000 R0: 20000f48 0a91ae0c 20020d00 20020d00 2001f578 080ca038 000182b8 20017cc0 R8: 2001ed20 2001f4e8 2001ed20 00000005 20020d20 20020ce8 0808439f 08087c4e xPSR: 61000000 BASEPRI: 00000000 CONTROL: 00000000 EXC_RETURN: ffffffe9

要解码硬故障,请加载 精确 二进制文件到调试器中:

arm-none-eabi-gdb build/px4_fmu-v2_default/px4_fmu-v2_default.elf

然后在 GDB 提示下,从 R8 中的最后一条指令开始,以闪存中的第一个地址(可识别,因为它以 0x080第一个是 0x0808439f).执行是从左向右的。因此,硬故障前的最后一个步骤是 mavlink_log.c 试图出版一些东西、

(gdb) info line *0x0808439f 线路 77".../src/modules/systemlib/mavlink_log.c"; 从地址 0x8084398 开始 <;mavlink_vasprintf+36>;
   并以 0x80843a0 结束 <;mavlink_vasprintf+44>;.
(gdb) info line *0x08087c4e 线路 311".../src/modules/uORB/uORBDevices_nuttx.cpp";
   从地址 0x8087c4e 开始 <;uORB::DeviceNode::publish(orb_metadata常量*、void*、void常量*)+2>;
   并以 0x8087c52 结束 <;uORB::DeviceNode::publish(orb_metadata常量*、void*、void常量*)+6>;.