stack overflow while using multiple UARTs

kbaud1
Posts: 52
Joined: Wed Jan 17, 2018 11:55 pm

stack overflow while using multiple UARTs

Postby kbaud1 » Thu Apr 25, 2019 6:04 pm

I am getting a stack overflow error when I try to display to the monitor ("make monitor") data received on UART 1 or 2. I am wondering if this is related to the the buffer sync problem (https://github.com/espressif/arduino-esp32/pull/1849) or is there something else I am missing?

Code: Select all

/* UART Echo Example*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "esp_log.h"

/**
 * This is an example which echos any data it receives on UART1 back to the sender,
 * with hardware flow control turned off. It does not use UART driver event queue.
 *
 * - Port: UART1
 * - Receive (Rx) buffer: on
 * - Transmit (Tx) buffer: off
 * - Flow control: off
 * - Event queue: off
 * - Pin assignment: see defines below
 */

#define ECHO_TEST_TXD  (GPIO_NUM_4)
#define ECHO_TEST_RXD  (GPIO_NUM_5)
#define ECHO_TEST_RTS  (UART_PIN_NO_CHANGE)
#define ECHO_TEST_CTS  (UART_PIN_NO_CHANGE)

#define BUF_SIZE (2048)

static void echo_task()
{
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity    = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE
    };
    uart_param_config(UART_NUM_1, &uart_config);
    uart_set_pin(UART_NUM_1, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);
    uart_driver_install(UART_NUM_1, BUF_SIZE * 2, 0, 0, NULL, 0);

    // Configure a temporary buffer for the incoming data
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
    //uint8_t data[128];

    while (1) {
        // Read data from the UART
    	uart_read_bytes(UART_NUM_1, data, BUF_SIZE, 20 / portTICK_RATE_MS);

    	//int length = 0;
    	//ESP_ERROR_CHECK(uart_get_buffered_data_len(UART_NUM_1, (size_t*)&length));
    	//length = uart_read_bytes(UART_NUM_1, data, length, 100);

        // send received data to "make monitor" output
        printf((const char *)data);
    }
}

void app_main()
{
	printf("UART test\r\n\r\n");
    xTaskCreate(echo_task, "uart_echo_task", 1024, NULL, 10, NULL);
}
I (188) boot: ESP-IDF v3.2-dev-640-gcc8ad721 2nd stage bootloader
I (188) boot: compile time 08:20:14
I (189) boot: Enabling RNG early entropy source...
I (209) boot: SPI Speed : 40MHz
I (222) boot: SPI Mode : DIO
I (235) boot: SPI Flash Size : 4MB
I (248) boot: Partition Table:
I (259) boot: ## Label Usage Type ST Offset Length
I (281) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (305) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (328) boot: 2 factory factory app 00 00 00010000 00100000
I (351) boot: End of partition table
I (364) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x095c4 ( 38340) map
I (475) esp_image: segment 1: paddr=0x000195ec vaddr=0x3ffb0000 size=0x02128 ( 8488) load
I (498) esp_image: segment 2: paddr=0x0001b71c vaddr=0x3ffb2128 size=0x00000 ( 0) load
I (499) esp_image: segment 3: paddr=0x0001b724 vaddr=0x40080000 size=0x00400 ( 1024) load
0x40080000: _WindowOverflow4 at C:/msys32/home/Peter/esp/esp-idf/components/freertos/xtensa_vectors.S:1685

I (527) esp_image: segment 4: paddr=0x0001bb2c vaddr=0x40080400 size=0x044e4 ( 17636) load
I (597) esp_image: segment 5: paddr=0x00020018 vaddr=0x400d0018 size=0x1389c ( 80028) map
0x400d0018: _flash_cache_start at ??:?

I (771) esp_image: segment 6: paddr=0x000338bc vaddr=0x400848e4 size=0x055ec ( 21996) load
0x400848e4: vTaskDelete at C:/msys32/home/Peter/esp/esp-idf/components/freertos/tasks.c:4617

I (829) esp_image: segment 7: paddr=0x00038eb0 vaddr=0x400c0000 size=0x00000 ( 0) load
I (831) esp_image: segment 8: paddr=0x00038eb8 vaddr=0x50000000 size=0x00000 ( 0) load
I (887) boot: Loaded app from partition at offset 0x10000
I (888) boot: Disabling RNG early entropy source...
I (893) cpu_start: Pro cpu up.
I (903) cpu_start: Starting app cpu, entry point is 0x40080f0c
0x40080f0c: call_start_cpu1 at C:/msys32/home/Peter/esp/esp-idf/components/esp32/cpu_start.c:226

I (1) cpu_start: App cpu up.
I (936) heap_init: Initializing. RAM available for dynamic allocation:
I (957) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM
I (975) heap_init: At 3FFB3178 len 0002CE88 (179 KiB): DRAM
I (995) heap_init: At 3FFE0440 len 00003BC0 (14 KiB): D/IRAM
I (1014) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM
I (1034) heap_init: At 40089ED0 len 00016130 (88 KiB): IRAM
I (1054) cpu_start: Pro cpu start user code
I (360) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
UART test

1267
1267
1264
1264
1264
1264
1264
1264
1264
1264
1267
1264
1264
1264
1264
1264
1264
1267
1264
1264
1267
1261***ERROR*** A stack overflow in task uart_echo_task has been detected.
abort() was called at PC 0x4008815c on core 1
The hardware setup is an EFM8 Sending RS232 serial at 115200 baud to GPIO 5 of the ESP32. This is the ADC reading in mv. It varies around this value. Here is a typical output (captured with PICO logic analyzer):
Packet Data
1: 1
2: 2
3: 6
4: 4
5: CR
6: LF
7: 1
8: 2
9: 6
10: 4
11: CR
12: LF
13: 1
14: 2
15: 6
16: 7
17: CR
18: LF
19: 1
20: 2
...

PeterR
Posts: 216
Joined: Mon Jun 04, 2018 2:47 pm

Re: stack overflow while using multiple UARTs

Postby PeterR » Thu Apr 25, 2019 7:17 pm

1024 is quite light for a task which printf().

I set 2048 for my driver soak test stacks (which are only a little more complicated than your code) but I had issues so I went to 4096 as a no brainer.
(Clearly a no brainer as there is no reason why I should use 2^n as a stack size!)

EDIT: & I did not study the code in detail but are you sure that data is \0 terminated and does not contain %s?
(that's from the receiver's perspective (warts n all), not what was sent!)

kbaud1
Posts: 52
Joined: Wed Jan 17, 2018 11:55 pm

Re: stack overflow while using multiple UARTs

Postby kbaud1 » Thu Apr 25, 2019 8:00 pm

Good idea. I changed it to 4096. This changed the behavior although it is erratic. Sometimes now it will print ~100 readings before crashing while other times it just crashes right away.
I (360) cpu_start: Starting scheduler on PRO CPU.
I (0) cpu_start: Starting scheduler on APP CPU.
UART test

1264
1264
1274
1274
1267
1264
1267
1264
1264
1264
... (several pages of this...)
1261
1267
1264
1267
1264
1264
1267
1267
1264
1267
1267
1267
1267
1264

Traceback (most recent call last):
File "C:/msys32/home/Peter/esp/esp-idf/tools/idf_monitor.py", line 770, in <module>
main()
File "C:/msys32/home/Peter/esp/esp-idf/tools/idf_monitor.py", line 685, in main
monitor.main_loop()
File "C:/msys32/home/Peter/esp/esp-idf/tools/idf_monitor.py", line 357, in main_loop
self.handle_serial_input(data)
File "C:/msys32/home/Peter/esp/esp-idf/tools/idf_monitor.py", line 416, in handle_serial_input
self.console.write_bytes(line + b'\n')
File "C:/msys32/mingw32/lib/python2.7/site-packages/serial/tools/miniterm.py", line 63, in write_bytes
self.byte_output.write(byte_string)
File "C:/msys32/home/Peter/esp/esp-idf/tools/idf_monitor.py", line 737, in write
data = data.encode('latin-1')
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf9 in position 2: ordinal not in range(128)
make: *** [/home/Peter/esp/esp-idf/components/esptool_py/Makefile.projbuild:106: monitor] Error 1


I also watched the data stream a while using an external logic analyzer (PicoScope). Exported to a excel worksheet. Did not see any anomalies. But it is certainly possible?

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: stack overflow while using multiple UARTs

Postby fly135 » Thu Apr 25, 2019 10:14 pm

I checked stack usage of one of my tasks both before and after printing to the terminal. Performing a print increased the stack requirement by almost 1K. This was done by dynamically changing the flag to print while running. So the task had been running long enough to not have any other things going on that would have changed the min free stack.

Minimum Free Stack
-------------------------
3344 before print
2480 after print

John A

PeterR
Posts: 216
Joined: Mon Jun 04, 2018 2:47 pm

Re: stack overflow while using multiple UARTs

Postby PeterR » Fri Apr 26, 2019 1:06 pm

Looks like your monitor is being crashed as well due to encoding issues which is consistent with my earlier suggestion.
To rephrase: No good will come from sending a raw stream to printf() (eventually).

I would:
printf("%.20s\n", line)

or similar.

I would also check for non ascii characters & dump if found.

kbaud1
Posts: 52
Joined: Wed Jan 17, 2018 11:55 pm

Re: stack overflow while using multiple UARTs

Postby kbaud1 » Fri Apr 26, 2019 3:51 pm

printf("%.20s\n",(const char *)data); works. Thanks. It does insert occasional new lines that are not necessary:
1267

1264
1264
1264
12
64
1264
1264
1264

1267
1264
1264

1267

PeterR
Posts: 216
Joined: Mon Jun 04, 2018 2:47 pm

Re: stack overflow while using multiple UARTs

Postby PeterR » Fri Apr 26, 2019 5:13 pm

Cool.
I would look a little deeper though.
What length strings did you have? What frequency of error etc?

My suggestion my just be masking a root issue e.g. rogue pointer.
You shouldn't be getting many UART corruptions so that suggests another problem.

Have fun!

User avatar
fly135
Posts: 606
Joined: Wed Jan 03, 2018 8:33 pm
Location: Orlando, FL

Re: stack overflow while using multiple UARTs

Postby fly135 » Fri Apr 26, 2019 6:51 pm

If you develop with windows I prefer Teraterm over the monitor. It won't crash on a binary char. You can write it to a log file and use HexEdit to see exactly what those problematic non-ascii values are.

You should ensure that you terminate the end of your recv'd data with a zero before calling print.

John A

Who is online

Users browsing this forum: axellin, MSN [Bot] and 18 guests