Skip to content

Maybe timing problem #92

@zlomennypez

Description

@zlomennypez

IDE / Tooling

pioarduino

What happened?

Hi. Firstly thank you for your lib. I uses latest pioarduino, emodbus library with AsyncTCP modbus and I take often WDT_TASK_RESET with trace to Async_TCP (newest version or older 3.3.2 version from menodev). I tried experiment to call my mikrotik router on port 502, where I dont have any Modbus, so I should get error from modbus. But after a few attempts WDT_TASK_RESET apply (backtrace) or all the code freezes (in case of change stack size). I tried to find the problem, and I added simple Serial.println("debugging messages") to AsyncTCP.cpp Paradoxly this change solved the problem of freezing or WDT_RESET and I don´t know, if it´s timing problem of library or ESP32 core itself.

AsyncTCP.cpp

As you can see, no other changes were made. Serial.printf is very slow, so it should degradate the code speed even more, but with it there arent any no WDT_TASK_ERROR. I dont want to use this kind of solution, but I really don´t know, where should I look for.

Stack Trace

ETH Got IP: 'eth0'
*eth0: <UP,100M,FULL_DUPLEX,AUTO,ADDR:0x1> (DHCPC_OFF,GARP,IP_MOD)
ether 36:CD:B0:07:9B:80
inet 192.168.0.99 netmask 255.255.255.0 broadcast 192.168.0.255
gateway 192.168.0.1 dns 8.8.8.8

Error for Device 199: EA - IP connection failed
Error for Device 199: EA - IP connection failed
Error for Device 199: EA - IP connection failed
Error for Device 199: EA - IP connection failed
Error for Device 199: EA - IP connection failed
E (15975) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:
E (15975) task_wdt: - async_tcp (CPU 0/1)
E (15975) task_wdt: Tasks currently running:
E (15975) task_wdt: CPU 0: IDLE0
E (15975) task_wdt: CPU 1: IDLE1
E (15975) task_wdt: Print CPU 0 (current core) backtrace

Backtrace: 0x4205B506:0x3FC9A480 0x4037A10D:0x3FC9A4B0 0x4037BFBF:0x3FCB0350 0x4205C209:0x3FCB0370 0x403803CB:0x3FCB0390 0x4037F24E:0x3FCB03B0
#0 0x4205B506 in task_wdt_timeout_handling at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/task_wdt/task_wdt.c:416
(inlined by) task_wdt_isr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/task_wdt/task_wdt.c:507
#1 0x3FC9A480 in _xt_exception_table at ??:?
#2 0x4037A10D in _xt_lowint1 at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/xtensa/xtensa_vectors.S:1240
#3 0x3FC9A4B0 in _xt_exception_table at ??:?
#4 0x4037BFBF in xt_utils_wait_for_intr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/xtensa/include/xt_utils.h:82
(inlined by) esp_cpu_wait_for_intr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_hw_support/cpu.c:55
#5 0x4205C209 in esp_vApplicationIdleHook at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/freertos_hooks.c:58
#6 0x403803CB in prvIdleTask at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:4353 (discriminator 1)
#7 0x4037F24E in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139

E (15975) task_wdt: Aborting.
E (15975) task_wdt: Print CPU 1 backtrace

Backtrace: 0x4037bfbf:0x3fcb0900 0x4205c209:0x3fcb0920 0x403803cb:0x3fcb0940 0x4037f24e:0x3fcb0960
#0 0x4037bfbf in xt_utils_wait_for_intr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/xtensa/include/xt_utils.h:82
(inlined by) esp_cpu_wait_for_intr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_hw_support/cpu.c:55
#1 0x4205c209 in esp_vApplicationIdleHook at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/freertos_hooks.c:58
#2 0x403803cb in prvIdleTask at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/tasks.c:4353 (discriminator 1)
#3 0x4037f24e in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:139

ELF file SHA256: 5907fdcc7

E (7932) esp_core_dump_flash: Core dump flash config is corrupted! CRC=0x7bd5c66f instead of 0x0
E (7941) esp_core_dump_elf: Elf write init failed!
E (7945) esp_core_dump_common: Core dump write failed with error=-1
Rebooting...
xxESP-ROM:esp32s3-20210327
Build:Mar 27 2021
rst:0xc (RTC_SW_CPU_RST),boot:0xb (SPI_FAST_FLASH_BOOT)
Saved PC:0x4205b511
#0 0x4205b511 in task_wdt_timeout_handling at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/task_wdt/task_wdt.c:421
(inlined by) task_wdt_isr at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp_system/task_wdt/task_wdt.c:507
`

Minimal Reproductible Example (MRE)

This is simple example. If you try to some kind of device, which doesnt respond correctly, WDT_TASK_ERROR appears.

// =================================================================================================
// eModbus: Copyright 2020 by Michael Harwerth, Bert Melis and the contributors to ModbusClient
// MIT license - see license.md for details
// =================================================================================================

// Example code to show the usage of the eModbus library.
// Please refer to root/Readme.md for a full description.

// Includes: <Arduino.h> for Serial etc., WiFi.h for WiFi support
#include <Arduino.h>
#include <WiFi.h>

// Include the header for the ModbusClient TCP style
#include <ModbusClientTCPasync.h>

#ifndef MY_SSID
#define MY_SSID "WiFi network ID"
#endif
#ifndef MY_PASS
#define MY_PASS "WiFi network password"
#endif

char ssid[] = MY_SSID; // SSID and ...
char pass[] = MY_PASS; // password for the WiFi network used
IPAddress ip = {192, 168, 0, 1}; // IP address of modbus server
uint16_t port = 502; // port of modbus server

// Create a ModbusTCP client instance
ModbusClientTCPasync MB(ip, port);

// Define an onData handler function to receive the regular responses
// Arguments are Modbus server ID, the function code requested, the message data and length of it,
// plus a user-supplied token to identify the causing request
void handleData(ModbusMessage response, uint32_t token)
{
Serial.printf("Response: serverID=%d, FC=%d, Token=%08X, length=%d:\n", response.getServerID(), response.getFunctionCode(), token, response.size());
for (auto& byte : response) {
Serial.printf("%02X ", byte);
}
Serial.println("");
}

// Define an onError handler function to receive error responses
// Arguments are the error code returned and a user-supplied token to identify the causing request
void handleError(Error error, uint32_t token)
{
// ModbusError wraps the error code and provides a readable error message for it
ModbusError me(error);
Serial.printf("Error response: %02X - %s token: %d\n", (int)me, (const char *)me, token);
}

// Setup() - initialization happens here
void setup() {
// Init Serial monitor
Serial.begin(115200);
while (!Serial) {}
Serial.println("__ OK __");

// Connect to WiFi
WiFi.begin(ssid, pass);
delay(200);
while (WiFi.status() != WL_CONNECTED) {
Serial.print(". ");
delay(1000);
}
IPAddress wIP = WiFi.localIP();
Serial.printf("WIFi IP address: %u.%u.%u.%u\n", wIP[0], wIP[1], wIP[2], wIP[3]);

// Set up ModbusTCP client.
// - provide onData handler function
MB.onDataHandler(&handleData);
// - provide onError handler function
MB.onErrorHandler(&handleError);
// Set message timeout to 2000ms and interval between requests to the same host to 200ms
MB.setTimeout(10000);
// Start ModbusTCP background task
MB.setIdleTimeout(60000);
}

// loop() - nothing done here today!
void loop() {
static unsigned long lastMillis = 0;
if (millis() - lastMillis > 5000) {
lastMillis = millis();

// Create request for
// (Fill in your data here!)
// - server ID = 1
// - function code = 0x03 (read holding register)
// - start address to read = word 10
// - number of words to read = 4
// - token to match the response with the request. We take the current millis() value for it.
//
// If something is missing or wrong with the call parameters, we will immediately get an error code 
// and the request will not be issued
Serial.printf("sending request with token %d\n", (uint32_t)lastMillis);
Error err;
err = MB.addRequest((uint32_t)lastMillis, 1, READ_HOLD_REGISTER, 10, 4);
if (err != SUCCESS) {
  ModbusError e(err);
  Serial.printf("Error creating request: %02X - %s\n", (int)e, (const char *)e);
}
// Else the request is processed in the background task and the onData/onError handler functions will get the result.
//
// The output on the Serial Monitor will be (depending on your WiFi and Modbus the data will be different):
//     __ OK __
//     . WIFi IP address: 192.168.178.74
//     Response: serverID=20, FC=3, Token=0000056C, length=11:
//     14 03 04 01 F6 FF FF FF 00 C0 A8

}
}

I confirm that:

  • I have read the documentation.
  • I have searched for similar discussions.
  • I have searched for similar issues.
  • I have looked at the examples.
  • I have upgraded to the lasted version of AsyncTCP.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions