Mdebug¶
Mdebug (Mesh Network debug) 是用于 ESP-MDF 中重要的一种调试方案,目的是将通过无线 espnow 协议、TCP 协议、串口等方式实现 ESP-MDF 设备日志高效的获取,从而更加方便快捷读取设备日志信息,然后可以根据提取出来的日志进行对应的分析等。
Mdebug 指南主要分为以下几个形式:
介绍¶
传统的调试方法是通过连接串口读取所有的日志信息,其中这些日志信息有部分是不必要信息,浪费了用户大量筛选时间,而且需要通过 PC 端和设备同时在线连接才能采集到日志信息,导致了时间和资源的浪费。
Mdebug 调试方法与传统的调试方法的不同之处在于,在不影响正常设备的运行的同时,Mdebug 调试可以通过无线调试,日志存储,控制命令筛选日志,从而提高了日志的使用效率和方便性,为设备查找问题和读取需要的信息节约时间和资源。
- Mdebug 主要分为命令管理和日志管理这两种方式
- 命令管理可以大致分为 输入源 、命令/指令 、用户自定义添加;
- 日志管理可以大致分为 UART 、Flash storage 、ESPNOW。
功能¶
mdebug espnow
:将设备中日志数据通过ESPNOW
无线 WiFi 形式传输给其他设备或者服务器等,从而提高了调试的方便和效率。mdebug flash
:将设备中日志数据直接写入到 flash 内存中,该 flash 内存中已经创建好内存空间,掉电保护日志信息,可以随时读取该日志信息,提高了数据的可利用性以及客户的方便。mdebug log
:将设备中日志数据通过串口监视器读取,同时设置 UART, flash, espnow`使能状态,其中日志信息将 `ESP_MDF 中 MDF_LOGI、MDF_LOGD、MDF_LOGW、MDF_LOGE 等日志信息读取出来。mdebug console
:将设备中日志数据通过在终端中的输入命令行形式读取,提高了用户的可操作性和实用性。
调试方法¶
调试方法可以概括为两种方法,一种是 UART 串口调试,另一种是无线 WiFi 调试。
- 串口调试在 PC 端使用串口调试工具( linux 下用 minicom 更好),直接获得输出的日志信息,还有可以通过控制命令行调试方法输出需要的日志信息。
- 无线 WiFi 调试有两种通讯方式分别是 TCP/IP 协议和 ESPNOW 协议,一种是日志信息通过 TCP/IP 协议传输到 Sever 端,另一种是从子节点的日志信息通过 ESPNOW 协议传输到根节点,然后从根节点的串口或者 TCP/IP 形式提取日志信息。也可以通过控制命令行调试方法输出需要的日志信息。
命令管理¶
1. 输入源¶
- 串口
- PC 端的监视器
- ESPNOW
- 无线调试工具 (ESP-WROVER-KIT-V2)
2. 命令/操作¶
2.1 一般指令
- help
- 打印已注册命令及其说明
- version
- 获取芯片和 SDK 版本
- heap
- 获取当前可用堆内存大小
- restart
- 软重启芯片
- reset
- 清除设备所有配置信息
2.2 日志命令
命令定义 log -or [<tag>] [<level>] [-s <addr(xx:xx:xx:xx:xx:xx)>] [-e <enable_type (‘uart’or’flash’or’espnow’)>] [-d <disable_type(‘uart’or’flash’or’espnow’)>] 指令 log -o 将获取日志使能状态 log -r 读取日志信息 log -s 将日志发送到指定设备 参数 tag 使用 tag 过滤日志 level 使用 level 过滤日志 addr 监视设备 MAC 地址 e ‘uart’ or ‘flash’ or ‘espnow’ 使能 uart,flash,espnow d ‘uart’ or ‘flash’ or ‘espnow’ 禁止串口,flash,espnow 示例 log mdebug_cmd INFO 设置 TAG 为 mwifi 的日 志输出等级为 INFO log * NONE 设置所有的日志不输出 2.3 coredump 命令
命令定义 coredump [-loe] [-q ] [-s <addr (xx:xx:xx:xx:xx:xx)>] 指令 coredump -l 获取该设备上的 coredump 数据长度 coredump -o 读取该设备上的 coredump 数据并打印 到控制台 coredump -e 擦除该设备上的 coredump 数据 coredump -s 发送设备上的 coredump 数据到指定设备 参数 addr 监视设备 MAC 地址 sequence coredump 数据的序号 示例 coredump -s 30:ae:a4:00:4b:90 将 coredump 数据发送到 30:ae:a4:00:4b:90 设备 coredump -q 110 -s 30:ae:a4:00:4b:90 将序号 110 开始的 coredump 数据发 送到 30:ae:a4:80:16:3c 设备
3. 自定义添加¶
可以根据 ESP-MDF 中的 example:function_demo/mwifi/console_test,用户可以自定义添加。
日志管理¶
Mdebug 中根据日志写入方式不同,大致可以分为两种形式:
- 设备的日志信息通过打印方式直接从
串口打印
出来或者把日志信息写入 flash 存储
,然后再调用读取。日志信息的存储将设备日志先写入 flash 内存中(这里的 flash 内存中分配了一个分区为 storage,为了存储设备日志,但是这里的分配的内存是有限的,根据用户设置的文件大小而决定),将会以文件的形式暂存起来,然后通过串口或者无线方式将数据以数据包的形式发送给 PC 或者是服务器;- 设备将通过
espnow
形式发送日志信息。将子节点日志信息通过 ESP-MESH 网络将数据发送给根节点,再从根节点的设备读取日志信息。
Mdebug 中根据日志读取方式不同,日志中有三种使能状态,分别是 uart
、flash
、espnow
使能。
1. UART 使能¶
将串口使能,日志信息将会通过 vprintf
打印出来。
读取日志的 I/O 口是 UART0,该串口的引脚为 TXD0 是 GPIO1, RXD0 是 GPIO3,同时也是下载串口。
UART0 TXDO RXD0 GPIO1 GPIO3 读取日志信息,诊断设备出现的问题和查找问题;如果在设备正常运行时,可以关闭串口使能,如果不关闭串口打印,将会占用内存,同时串口打印信息过多,还会激活看门狗,使正常设备运行程序
Backtrace
。串口默认状态为使能状态,用户可以根据自己需要进行关闭。
2. Flash 使能¶
写入 flash 使能,将日志信息存入 flash 中。
2.1 将 log 保存到 flash
分区表中选择出来一定的内存空间为
storage
,这里分配的内存为了给 log 写入到 flash 中提供内存空间。文件名为spiffs
,
spiffs 分区:
# Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 16k otadata, data, ota, 0xd000, 8k phy_init, data, phy, 0xf000, 4k ota_0, app, ota_0, 0x10000, 1920k ota_1, app, ota_1, , 1920k coredump, data, coredump, , 64K storage, data, spiffs, , 64K reserved, data, 0xfe, , 64K注解
- 更新分区表前,需要先擦除整个 flash;
- 分区表无法通过 OTA 的方式进行修改;
- 文件空间大小可以根据用户合理的选择进行内存分配。
2.2 日志信息存取
- 日志初始化,创建两个文本 flash 内存空间,并获取文本的状态
stat
,判断写入还是读取,使用到主要函数为esp_vfs_spiffs_register
、esp_spiffs_info
、sprintf
、fopen
;- 存取中加入一个互斥锁,当读取日志信息时,则会关闭写入功能,主要用到的函数为
xSemaphoreTake
,xSemaphoreGive
;- 写入flash中,先写入时间戳,并记下文本数组的地址指针 g_log_info[g_log_index],主要用到的函数为
time
,localtime_r
,strftime
;- 写入日志数据,同时记下写入文本1数组的地址指针 g_log_index,为了下次日志写入 flash 做好地址寻址,使用到主要函数为
fseek
、fwrite
;- 判断,如果文本1数组的地址指针已满,清零文本1的地址指针,地址偏移到文本2的地址指针,开始写入日志数据;如果未满,将会继续在文本1中写入日志数据;
- 同理,当文本2数组的地址指针已满,清零文本2的地址指针,地址偏移到文本1的地址指针,开始写入日志数据;如果未满,将会继续在文本2中写入日志数据;
- 根据写入地址指针 g_log_info 获取读取文本地址指针 log_info ,然后读取文本中日志数据,同时也记下读取文本数据的地址偏移指针 offset,为下次从 flash 读取日志做好地址寻址,使用到主要函数为
fseek
、fread
;- 判断,如果文本未读取,将会继续读取文本日志数据;如果文本读取完成,将会结束读取任务。
注解
- 日志数据的头是增加了时间戳,这里只是作为实验,并没有实时校准,用户可以根据自己的需求进行修改;
- 日志存储的文件大小为 CONFIG_MDEBUG_FLASH_FILE_MAX_SIZE = 16384,用户可以根据自己需求修改日志文件的存储空间;
日志重定向
将日志存储信息输出重新进行定义,这是为了对于日志写入 flash 进行调试,当日志输出信息出现问题时,可以更好的调试日志输出信息是否正确,使用到的调试函数为MDEBUG_PRINTF(fmt, ...)
;- 增加了数据的擦除,当数据存满,将会清除数据指针,重新开始从文件头指针地址开始写入或者读取,用到的主要函数
rewind
。2.3 日志数据的格式
日志数据将来自 ESP_MDF 中 MDF_LOGI、MDF_LOGD、MDF_LOGW、MDF_LOGE 等,这是通过 IDF 的日志库会默认使用类 vprintf 的函数将格式化的字符串输出到专用的 UART 上。提取出来的数据如下图所示:
因在 MDF 中的日志信息存在头和尾有不需要的数据,这就需要提取和选择有效的字符串数据信息,因此需要将其进行去除和筛选,然后再进行日志数据提取。
Front data
中包含了字体颜色等添加的信息,所以需要将头部部分数据去除,Tail data
中包含了换行等数据,同样是需要去除, 对于 MDF_LOGD 没有这些无用数据,所以不需要进行处理。
3. ESPNOW 使能¶
3.1 ESP-NOW 特性
- 收发双方必须在同一个信道上
- 接收端在非加密通信的情况下可以不添加发送端的 MAC 地址(加密通信时需要添加),但是发送端必须要添加接收端的 MAC 地址
- ESP-NOW 最多可添加 20 个配对设备,同时支持其中最多 6 个设备进行通信加密
- 通过注册回调函数的方式接收数据包,以及检查发送情况(成功或失败)
- 利用 CTR 和 CBC-MAC 协议 (CCMP) 保护数据的安全
3.2 ESP-NOW 使能流程
通过使能 espnow,可以将子节点的日志数据通过espnow发送给根节点,使得从根节点读取子节点的日志信息,然后通过串口读取日志信息。
这个可以使用 example:wireless_debug 进行测试,ESP-NOW debug 接收板可以不直接与路由器进行连接,只需与 ESP-MESH 网络在同一信道上即可。若需要与接收其他 ESP-MESH 设备的 log,需要在监听的设备中添加以下代码:
MDF_ERROR_ASSERT(mdebug_console_init()); MDF_ERROR_ASSERT(mdebug_espnow_init()); mdebug_cmd_register_common();
关于更多 espnow 可以参看 example:wireless_debug 以及 官方文档 ESPNOW
。
注解
由于 ESP-NOW 和 ESP-MESH 一样,都是通过 Wi-Fi 接口进行数据包收发,因此,当 ESP-MESH 设备数据传输量较大时,会对其控制命令接收或数据传输产生一些延时。
经实际测试,在网络环境良好的情况下,以下配置参数导致的 ESP-MESH 设备延时是可以忽略的阈值:
- 50 个 ESP-MESH 设备(设备数量越多,网络环境越差)
- ESP-NOW 接收端添加 10 个 ESP-MESH 设备(接收端添加数量越多,网络环境越差)
- 传输日志级别为 info (日志级别越低,网络环境越差)