Использование RTOS SDK - сбой при добавлении другой задачи

task

(Я надеюсь, что это правильное место, чтобы задать вопросы о ESP8266_RTOS_SDK)

У меня есть программа, которую я взял из каталога samples (protocols/tcp_client) в RTOS SDK и добавил код из образца uart только для того, чтобы я мог использовать клавиатуру, чтобы сказать клиенту, когда начать. Задача tcp_client просто отправляет сокет на & recv с сервера (простой сервер сокетов, работающий на рабочем столе linux). Он отлично работает, пока я не попытался добавить еще один пример задачи:

 static void test_task(void *pvParameters)
    {
        vTaskDelay(MYDELAY2);
        ESP_LOGI(TAG, "asdf 123");
    }

А затем в app_main () я создаю задачу:

xTaskCreate(test_task, "test", 2048, NULL, 10, NULL);

Я пытаюсь запустить его, и он либо блокируется, а затем выходит из строя, либо просто выходит из строя, как только подключается к серверу. Обычно он выходит из строя сразу после того, как распечатает сообщение в test_task.

 #include <string.h>
    #include <sys/param.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "esp_system.h"
    #include "esp_log.h"
    #include "esp_netif.h"
    #include "esp_event.h"
    #include "protocol_examples_common.h"
    #include "nvs.h"
    #include "nvs_flash.h"
    #include "lwip/err.h"
    #include "lwip/sockets.h"
    #include "lwip/sys.h"
    #include <lwip/netdb.h>
    #include "freertos/queue.h"
    #include "driver/uart.h"

    #define HOST_IP_ADDR CONFIG_EXAMPLE_IPV4_ADDR
    #define MYDELAY1 (75 / portTICK_PERIOD_MS)
    #define MYDELAY2 (125 / portTICK_PERIOD_MS)
    #define MYDELAY3 (250 / portTICK_PERIOD_MS)
    #define MYDELAY4 (500 / portTICK_PERIOD_MS)
    #define MYDELAY5 (1000 / portTICK_PERIOD_MS)
    #define MYDELAY6 (2000 / portTICK_PERIOD_MS)
    #define MYDELAY7 (5000 / portTICK_PERIOD_MS)
    #define PORT CONFIG_EXAMPLE_PORT

    static const char *TAG = "example";
    #define EX_UART_NUM UART_NUM_0
    #define BUF_SIZE (1024)
    #define RD_BUF_SIZE (BUF_SIZE)
    static QueueHandle_t uart0_queue;
    unsigned char state;
    int sock;

    static void test_task(void *pvParameters)
    {
        vTaskDelay(MYDELAY2);
        ESP_LOGI(TAG, "asdf 123");
    }

    static void tcp_client_task(void *pvParameters)
    {
        char rx_buffer[128];
        char send_buff[100];
        char addr_str[128];
        int addr_family;
        int ip_protocol;
        int i = 0;
        char xbyte = 0x21;
        int len, err;

        struct sockaddr_in destAddr;
    //  destAddr.sin_addr.s_addr = inet_addr(HOST_IP_ADDR);
    // can set ip address either explicitly or using 'make menuconfig' and go to 'example      configuration'
        destAddr.sin_addr.s_addr = inet_addr("192.168.88.103");
        inet_ntoa_r(((struct sockaddr_in *)&destAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) -     1);
        ESP_LOGI(TAG, "address : %s", addr_str);
        destAddr.sin_family = AF_INET;
        destAddr.sin_port = htons(PORT);
        addr_family = AF_INET;
        ip_protocol = IPPROTO_IP;
        inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);


        sock =  socket(addr_family, SOCK_STREAM, ip_protocol);
        if (sock < 0)
        {
            ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
            state = 51;
        }
        ESP_LOGI(TAG, "Socket created %d",sock);

        memset(send_buff,0,sizeof(send_buff));
        for(i = 0;i < 99;i++)
        {
            send_buff[i] = xbyte;
            if(++xbyte > 0x7e)
                xbyte = 0x21;
        }
        send_buff[99] = 0;

        ESP_LOGI(TAG,"press '1' to connect, then press '2' to start client, '3' to shutdown");

        while (1)
        {
            switch(state)
            {
                case 0:
                vTaskDelay(MYDELAY3);
                break;
            case 49:
                err = connect(sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
                if (err != 0)
                {
                    ESP_LOGE(TAG, "Socket unable to connect: errno %d", errno);
                    close(sock);
                    vTaskDelay(MYDELAY1);
                    state = 0;
                }
                ESP_LOGI(TAG, "Successfully connected %d",err);
                state = 0;
                break;
            case 50:
                //ESP_LOGI(TAG, "starting...");

                err = send(sock, send_buff, 80, 0);
                if (err < 0)
                {
                    ESP_LOGE(TAG, "Error occured during sending: errno %d", errno);
                    state = 0;
                    break;
                }
                //ESP_LOGI(TAG,"send returned: %d",err);

                vTaskDelay(MYDELAY1);

                len = recv(sock, rx_buffer, 80, 0);
                // Error occured during receiving
                if (len < 0)
                {
                    ESP_LOGE(TAG, "recv failed: errno %d", errno);
                    state = 0;
                    break;
                }
                else 
                {
                    rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
                    //ESP_LOGI(TAG, "Received %d bytes from %s:", len, addr_str);
                    ESP_LOGI(TAG, "%s", rx_buffer);
                }

                vTaskDelay(MYDELAY1);

                if (sock == -1)
                {
                    ESP_LOGE(TAG, "Shutting down socket, press '1' to restart...");
                    shutdown(sock, 0);
                    close(sock);
                    state = 0;
                }
                break;
            case 51:
                ESP_ERROR_CHECK(example_disconnect());
                break;
            case 52:
                shutdown(sock,0);
                close(sock);
                ESP_LOGI(TAG,"shutdown - deleting task");
                vTaskDelete(NULL);
                break;
            default:
                ESP_LOGI(TAG,"press '1' to connect, then press '2' to start client %d",state);
                vTaskDelay(MYDELAY3);
                state = 0;
                break;
        }
    }
}
//#if 0
static void uart_event_task(void *pvParameters)
{
    uart_event_t event;
    int i;
    uint8_t *dtmp = (uint8_t *) malloc(RD_BUF_SIZE);

    for (;;) {
        // Waiting for UART event.
        if (xQueueReceive(uart0_queue, (void *)&event, (portTickType)portMAX_DELAY)) {
            bzero(dtmp, RD_BUF_SIZE);
            //ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);

            switch (event.type) {
                // Event of UART receving data
                // We'd better handler data event fast, there would be much more data events than
                // other types of events. If we take too much time on data event, the queue might be full.
                case UART_DATA:
                    ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
                    uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);
                    state = dtmp[0];
                    ESP_LOGI(TAG,"state: %d",state);
//                    uart_write_bytes(EX_UART_NUM, (const char *) dtmp, event.size);
                    break;

                // Event of HW FIFO overflow detected
                case UART_FIFO_OVF:
                    ESP_LOGI(TAG, "hw fifo overflow");
                    // If fifo overflow happened, you should consider adding flow control for your application.
                    // The ISR has already reset the rx FIFO,
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(uart0_queue);
                    break;

                // Event of UART ring buffer full
                case UART_BUFFER_FULL:
                    ESP_LOGI(TAG, "ring buffer full");
                    // If buffer full happened, you should consider encreasing your buffer size
                    // As an example, we directly flush the rx buffer here in order to read more data.
                    uart_flush_input(EX_UART_NUM);
                    xQueueReset(uart0_queue);
                    break;

                case UART_PARITY_ERR:
                    ESP_LOGI(TAG, "uart parity error");
                    break;

                // Event of UART frame error
                case UART_FRAME_ERR:
                    ESP_LOGI(TAG, "uart frame error");
                    break;

                // Others
                default:
                    ESP_LOGI(TAG, "uart event type: %d", event.type);
                    break;
            }
        }
    }
    free(dtmp);
    dtmp = NULL;
    vTaskDelete(NULL);
}
//#endif

void app_main()
{
    ESP_ERROR_CHECK(nvs_flash_init());
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    ESP_ERROR_CHECK(example_connect());
        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(EX_UART_NUM, &uart_config);

    // Install UART driver, and get the queue.


    uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 100, &uart0_queue, 0);

    xTaskCreate(test_task, "test", 2048, NULL, 10, NULL);

    xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);

    xTaskCreate(tcp_client_task, "tcp_client", 2048, NULL, 5, NULL);
}

Когда я добавил задачу для uart, она работает, но когда я добавляю задачу для печати тестового сообщения и делаю временную задержку, она выходит из строя.

, 👍1


1 ответ


1

У меня не было задачи в виде бесконечного цикла. Это должно быть:

static void test_task(void *pvParameters)
{
    while(1)
    {
        vTaskDelay(MYDELAY6);
        ESP_LOGI(TAG, "test 123");
     }
}
,