ESP-IDF crashes while sending more than 128bytes via UART1 using uart_write_bytes() function

sumit809
Posts: 2
Joined: Tue Feb 25, 2020 6:03 am

ESP-IDF crashes while sending more than 128bytes via UART1 using uart_write_bytes() function

Postby sumit809 » Tue Feb 25, 2020 7:58 am

Code: Select all


/* 
UART Interrupt Example
*/
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "sdkconfig.h"
#include "esp_intr_alloc.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"
#include "soc/soc.h"
#include <stdarg.h>

#define BLINK_GPIO GPIO_NUM_2

static const char *TAG = "uart_events";

/**
 * This example shows how to use the UART driver to handle UART interrupt.
 *
 * - Port: UART0
 * - Receive (Rx) buffer: on
 * - Transmit (Tx) buffer: off
 * - Flow control: off
 * - Event queue: on
 * - Pin assignment: TxD (default), RxD (default)
 */

#define EX_UART_NUM UART_NUM_1
#define PATTERN_CHR_NUM (3) /*!< Set the number of consecutive and identical characters received by receiver which defines a UART pattern*/
#define ECHO_TEST_TXD (GPIO_NUM_13)
#define ECHO_TEST_RXD (GPIO_NUM_15)

#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)
// static QueueHandle_t uart0_queue;
uint8_t readFlag = 0;
int len = 0;

// Both definition are same and valid
//static uart_isr_handle_t *handle_console;
static intr_handle_t handle_console;

// Receive buffer to collect incoming data
uint8_t rxbuf[256];
static char data[256];

esp_err_t event_handler(void *ctx, system_event_t *event)
{
    if (event->event_id == SYSTEM_EVENT_SCAN_DONE)
    {
        uint16_t apCount = 0;
        esp_wifi_scan_get_ap_num(&apCount);
        printf("Number of access points found: %d\n", event->event_info.scan_done.number);
        int len = (event->event_info.scan_done.number * 7) + 1;
        char macArray[len];
        if (apCount == 0)
        {
            return ESP_OK;
        }
        wifi_ap_record_t *list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * apCount);
        macArray[0] = event->event_info.scan_done.number;
        ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&apCount, list));

        int k = 1;
        int i;
        for (i = 0; i < apCount; i++)
        {
            for (int j = 5; j >= 0; j--)
            {
                macArray[k] = list[i].bssid[j];
                k++;
            }
            macArray[k] = list[i].rssi;
            printf("\n");
            k++;
        }

        const size_t N = sizeof(macArray) / sizeof(*macArray);
        int len1 = len * 3;
        // char s1[] = "ESP:SCANW:";

        char s2[len1];

        int n;

        for (size_t i = 0, j = 0;
             i < N && (n = snprintf(s2 + j, sizeof(s2) - j, "%d", macArray[i])) > 0;
             i++)
        {
            j += n;
            len1 = j;
        }
        int len2 = len1 + 11;
        char string[len2];
        size_t length = sprintf(string, "%s%s", "ESP:SCANW:", s2);

        printf("%d\r\n", length);
        uint8_t loopCount = (length / 128) + 1;
        uint8_t remainingBytes = (length % 128);
        printf("total loops=%d\r\n", loopCount);
        printf("remaining bytes=%d\r\n", remainingBytes);
        // vTaskDelay(10 / portTICK_PERIOD_MS);
        uart_write_bytes(UART_NUM_1, (const char *)string, strlen(string));
        // vTaskDelay(10 / portTICK_PERIOD_MS);
        // for (int z = 0, i = 0; z < loopCount; z++)
        // {
        //     vTaskDelay(10 / portTICK_PERIOD_MS);
        //     if (z == (loopCount - 1))
        //     {
        //         (uart_write_bytes(UART_NUM_1, (const char *)&string[i], remainingBytes));
        //     }

        //     else
        //     {
        //         uart_write_bytes(UART_NUM_1, (const char *)&string[i], 128);
        //     }

        //     printf("CurrentLoop=%d\r\n", z);
        //     printf("i=%d\r\n", i);
        //     i += 128;
        // }

        printf("\n");
        free(list);
    }
    return ESP_OK;
}

void blink_task(void *pvParameter)
{
   wifi_scan_config_t scanConf = {
        .ssid = NULL,
        .bssid = NULL,
        .channel = 0,
        .show_hidden = true};

    while (1)
    {
        vTaskDelay(10 / portTICK_PERIOD_MS);
        if (readFlag == 1)
        {
            uart_write_bytes(EX_UART_NUM, (const char *)"ESP:ERROR", 9);
            readFlag = 0;
        }
        else if (readFlag == 2) // AT+SCANW
        {
            readFlag = 0;
            ESP_ERROR_CHECK(esp_wifi_scan_start(&scanConf, true)); //The true parameter cause the function to block until
                                                                   //the scan is done.
        }
    }
}
/*
 * Define UART interrupt subroutine to ackowledge interrupt
 */
static void IRAM_ATTR uart_intr_handle(void *arg)
{
    uint16_t rx_fifo_len; //, status;
    uint16_t i = 0;

    // status = UART1.int_st.val;             // read UART interrupt Status
    rx_fifo_len = UART1.status.rxfifo_cnt; // read number of bytes in UART buffer
    len = rx_fifo_len;
    while (rx_fifo_len)
    {
        data[i++] = UART1.fifo.rw_byte; // read all bytes
        rx_fifo_len--;
    }
    data[len] = '\0';
    // after reading bytes from buffer clear UART interrupt status
    uart_clear_intr_status(EX_UART_NUM, UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR);

    // a test code or debug code to indicate UART receives successfully,
    // you can redirect received byte as echo also
    // uart_write_bytes(EX_UART_NUM, (const char *)data, len);
    if (strcmp(data, "AT+SCANW") == 0)
        readFlag = 2;
    else
        readFlag = 1;
}

static void wifi_init()
{
    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
}

static void uart_init()
{
    /* 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};

    ESP_ERROR_CHECK(uart_param_config(EX_UART_NUM, &uart_config));

    //Set UART log level
    esp_log_level_set(TAG, ESP_LOG_INFO);

    //Set UART pins (using UART0 default pins ie no changes.)
    ESP_ERROR_CHECK(uart_set_pin(EX_UART_NUM, ECHO_TEST_TXD, ECHO_TEST_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));

    //Install UART driver, and get the queue.
    ESP_ERROR_CHECK(uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, 0, 0, NULL, 0));

    // release the pre registered UART handler/subroutine
    ESP_ERROR_CHECK(uart_isr_free(EX_UART_NUM));

    // register new UART subroutine
    ESP_ERROR_CHECK(uart_isr_register(EX_UART_NUM, uart_intr_handle, NULL, ESP_INTR_FLAG_IRAM, &handle_console));

    // enable RX interrupt
    ESP_ERROR_CHECK(uart_enable_rx_intr(EX_UART_NUM));
}

/*
 * main 
 */
void app_main()
{
    esp_log_level_set(TAG, ESP_LOG_INFO);
    nvs_flash_init();
    tcpip_adapter_init();
    wifi_init();
    uart_init();
    xTaskCreate(&blink_task, "blink_task", configMINIMAL_STACK_SIZE, NULL, 5, NULL);
}


Here I'm trying to send the number of wifi APs available and MAC addresses with their respective RSSI all in one string at once...
The code works fine if I break the string into 128bytes and put delay of minimum 10 seconds... otherwise it just crashes and restarts.
Anybody knows the issue?

ESP_Sprite
Posts: 9599
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP-IDF crashes while sending more than 128bytes via UART1 using uart_write_bytes() function

Postby ESP_Sprite » Thu Feb 27, 2020 10:38 am

I don't think you're supposed to both install a driver and grab the interrupt yourself. The driver uses the interrupt and probably won't work correctly if you re-route it to your own code.

Who is online

Users browsing this forum: No registered users and 91 guests