ESP32 FreeRTOS TCP/IP task problem

Vilius
Posts: 26
Joined: Mon Nov 13, 2023 9:22 am

ESP32 FreeRTOS TCP/IP task problem

Postby Vilius » Thu Oct 17, 2024 10:24 am

Hi,

I am developing a project where ESP32 acts like a TCP client. The code is really long, but key points are that receive_data_task and send_data_task are created in the main program. My main program is executed by core0 (the faster core) and the tcp tasks are executed on core1.

As soon as esp32 connects to the server, it has to receive some parameters from it (task is kept until the parameters are received.) Then the task is deleted and core1 shifts to the tcp send_data_task. All this worked on a prototype that was built using ESP-Ethernet-kit devboard. Now I am implementing it to the custom PCB where problems start to occur. The exact same code with exact same menuconfig settings don't work as expected. ESP32 receives the data, but it does not send ACKs back to the server, sometimes it does not send data to the server etc. TCP behavior is really unpredictable and unusable. I experimentally found out that if I put the receive data task code in my main program, everything works perfectly, server gets it's ACKs back, data transmission is fluent, latencies are low, it works like a clock.

I spent quite some time experimenting with receive_data_task and send_data_task stack sizes, priorities, cores that are assigned to do the task etc. Tried with all core1, core0 and no core affinity to tcp task options in the menuconfig, but all this did not make a difference. Bottom line is that my tcp code algorithm only works in the main program, regardless of the options... (I can not leave it like that, because my main program is used for a different purpose.) I suspect this problem has nothing to do with the hardware, but software problem seems like a mystery either :) Any observations are highly appreciated.


In the datagrams,
ESP's IP: 192.168.1.241
Server's IP: 192.168.1.23

Code with tcp tasks separated (not working one):

Code: Select all

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include "freertos/timers.h"
#include "soc/soc.h"
#include "soc/gpio_struct.h"
#include "soc/gpio_reg.h"
#include "esp32/rom/ets_sys.h"
#include "soc/rtc.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "esp_transport.h"
#include "esp_transport_tcp.h"
#include "esp_transport_socks_proxy.h"
#include <sys/time.h>
#include <errno.h>
#include <arpa/inet.h>
#include <math.h>
#include "ethernet_init.h"
#include "sdkconfig.h"
#include "lwip/sockets.h"
#include "lwip/inet.h"
#include <netinet/in.h>
#include <fcntl.h>

#define BROADCAST_PORT 8000
#define MESSAGE "Scintilator"
#define MAX_MESSAGE_LEN 128
#define TCP_TARGET_LEN 16
#ifdef CONFIG_EXAMPLE_ENABLE_PROXY
#define PROXY_ADDR CONFIG_EXAMPLE_PROXY_ADDR
#define PROXY_PORT CONFIG_EXAMPLE_PROXY_PORT
#endif
#define MAX_RETRY_COUNT 5
#define MAX_POLL_TIMEOUT_ERRORS 5
#define INTERRUPT_INPUT 32
#define GPIO_CLOCK 33
#define NUM_GPIO_PINS 12
#define NUM_CYCLES 32
#define BIT_1 14
#define BIT_2 13
#define BIT_3 15
#define BIT_4 4
#define BIT_5 16
#define BIT_6 17
#define BIT_7 5
#define BIT_8 18
#define BIT_9 19
#define BIT_10 21
#define BIT_11 12
#define BIT_12 2
#define MAX_BROADCAST_ADDR_LEN 16

uint64_t get_time_us() {
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}

esp_netif_t *eth_netif = NULL; // Declare eth_netif globally
static const char *TAG = "tcp_transport_client";
esp_transport_handle_t transport = NULL;
static bool is_connected = false;
static int unsuccessful_retries = 0;
static int consecutive_poll_timeout_errors = 0;
static bool received_from_server = false;
char global_broadcast_address_str[MAX_BROADCAST_ADDR_LEN];
bool trigger = false;
bool protocol_transition = false;
uint32_t data_array[NUM_CYCLES] = {0};
char TCP_TARGET[TCP_TARGET_LEN];

static const gpio_num_t GPIO_PINS[NUM_GPIO_PINS] = {
    BIT_1, BIT_2, BIT_3, BIT_4,
    BIT_5, BIT_6, BIT_7, BIT_8,
    BIT_9, BIT_10, BIT_11, BIT_12
};

TaskHandle_t tcpTaskHandle;
SemaphoreHandle_t tcpMutex;
SemaphoreHandle_t dataReceivedSemaphore;
QueueHandle_t tcpDataQueue;
TimerHandle_t timerHandle;
TimerHandle_t DHCP_timer_handle;

int counter = 0;
bool global_digit = false;
int received_integer = 0;
bool timer_started = false;

void establish_connection();
void disconnect_if_connected();
void Impulse_Count();
void close_connection();
void send_data_over_tcp(uint32_t *data_array, size_t num_elements);
void send_data_task(void *pvParameters);
void receive_data_task(void *pvParameters);
static void IRAM_ATTR gpio_interrupt_handler(void *args);

static void eth_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data){
    uint8_t mac_addr[6] = {0};
    esp_eth_handle_t eth_handle = *(esp_eth_handle_t *)event_data;
    switch (event_id) {
    case ETHERNET_EVENT_CONNECTED:
        esp_eth_ioctl(eth_handle, ETH_CMD_G_MAC_ADDR, mac_addr);
        ESP_LOGI(TAG, "Ethernet Link Up");
        ESP_LOGI(TAG, "Ethernet HW Addr %02x:%02x:%02x:%02x:%02x:%02x",
                 mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
        ESP_LOGI(TAG, "Waiting 60 seconds to obtain IP address from DHCP");
        xTimerStart(DHCP_timer_handle, 0);
                 vTaskDelay(10 / portTICK_PERIOD_MS);
        break;
    case ETHERNET_EVENT_DISCONNECTED:
        ESP_LOGI(TAG, "Ethernet Link Down");
        break;
    case ETHERNET_EVENT_START:
        ESP_LOGI(TAG, "Ethernet Started");
        break;
    case ETHERNET_EVENT_STOP:
        ESP_LOGI(TAG, "Ethernet Stopped");
        break;
    default:
        break;
    }
}

void DHCP_timer_callback(TimerHandle_t xTimer) {
    if(strncmp(TCP_TARGET, "169", 3) == 0){
    ESP_LOGE(TAG, "Did not obtain IP address from DHCP in 60 seconds. Executing software reset...");
    esp_restart();  
    }
    /*
    else{
        xTimerStop(DHCP_timer_handle, 0);
        ESP_LOGI(TAG, "Dynamically allocated IP address acquired");
        return;
    }
    */
}

void udp_client_send_message(char *ip, int dest_port, char *message) {
    int addr_family = AF_INET;
    int ip_protocol = IPPROTO_IP;
    struct sockaddr_in dest_addr;
    dest_addr.sin_addr.s_addr = inet_addr(ip);
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(dest_port);
    int sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
    if (sock < 0) {
        ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
        return;
    }
    ESP_LOGI(TAG, "Socket created, sending to %s:%d", ip, dest_port);
    int err = sendto(sock, message, strlen(message), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
    if (err < 0) {
        ESP_LOGE(TAG, "Error occurred during sending: errno %d", errno);
    } else {
        ESP_LOGI(TAG, "Message sent: %s", message);
    }
    /*
    if (sock != -1) {
        shutdown(sock, 0);
        close(sock);
        printf ("UDP socket closed\n");
    }
    */
}

static void got_ip_event_handler(void *arg, esp_event_base_t event_base,int32_t event_id, void *event_data){
    printf ("Start of gotip\n");
    vTaskDelay(10 / portTICK_PERIOD_MS);

    ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
    if (!event) {
        ESP_LOGE(TAG, "Event data is NULL");
        printf("Could not retrieve network parameters");
        return;
    }
    bool server_reception = false;
    char ip[16];
    char subnet_mask[16];
    inet_ntoa_r(event->ip_info.ip, ip, sizeof(ip));
    inet_ntoa_r(event->ip_info.netmask, subnet_mask, sizeof(subnet_mask));
    struct in_addr addr;
    inet_aton(ip, &addr);
    struct in_addr subnet;
    inet_aton(subnet_mask, &subnet);
    struct in_addr network_address;
    network_address.s_addr = addr.s_addr & subnet.s_addr;
    struct in_addr broadcast_address;
    broadcast_address.s_addr = network_address.s_addr | ~subnet.s_addr;
    snprintf(global_broadcast_address_str, MAX_BROADCAST_ADDR_LEN, "%lu.%lu.%lu.%lu",
             (broadcast_address.s_addr >> 24) & 0xFF,
             (broadcast_address.s_addr >> 16) & 0xFF,
             (broadcast_address.s_addr >> 8) & 0xFF,
             broadcast_address.s_addr & 0xFF);

    if(strncmp(ip, "169", 3) == 0){
        ESP_LOGI(TAG, "Automatically configured IP address acquired, waiting for DHCP address");
        return;
    }
    else{
        xTimerStop(DHCP_timer_handle, 0);
        ESP_LOGI(TAG, "Dynamically allocated IP address acquired");
    }

    printf("Network Address: %s\n", inet_ntoa(network_address));
    printf("Broadcast Address: %s\n", inet_ntoa(broadcast_address));

    vTaskDelay(10 / portTICK_PERIOD_MS);

    udp_client_send_message(inet_ntoa(broadcast_address),BROADCAST_PORT,MESSAGE);
    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sock < 0) {
        ESP_LOGE(TAG, "Unable to create socket: errno %d", errno);
        return;
    }
    struct sockaddr_in client_addr;
    client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(BROADCAST_PORT);
    if (bind(sock, (struct sockaddr *)&client_addr, sizeof(client_addr)) < 0) {
        ESP_LOGE(TAG, "Socket bind failed: errno %d", errno);
        return;
    }
    char rx_buffer[MAX_MESSAGE_LEN];
    struct sockaddr_in source_addr;
    socklen_t socklen = sizeof(source_addr);
   
    while (!server_reception) {
        int len = recvfrom(sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&source_addr, &socklen);
        if (len < 0) {
            ESP_LOGE(TAG, "recvfrom failed: errno %d", errno);
            break;
        } else {
            rx_buffer[len] = 0;
            printf("MARK1");
            ESP_LOGI(TAG, "Message received: Scintilator. From %s:%d",inet_ntoa(source_addr.sin_addr), ntohs(source_addr.sin_port));
            printf("MARK");
            snprintf(TCP_TARGET, TCP_TARGET_LEN, "%s", inet_ntoa(source_addr.sin_addr));
            server_reception = true;
        }
    }
    //if (sock != -1) {
        shutdown(sock, 0);
        close(sock);
        printf ("UDP socket closed\n");
    //}
    protocol_transition = true;
}

void timerCallback(TimerHandle_t xTimer) {
    gpio_intr_disable(GPIO_NUM_15);
    vTaskDelay(35 / portTICK_PERIOD_MS);
    ESP_LOGI(TAG, "Timer expired. Disconnecting from server...");
    vTaskDelay(5000 / portTICK_PERIOD_MS);
    close_connection();
    ESP_LOGI(TAG, "Interrupt count: %d", counter);
}
void Impulse_Count(){
    gpio_intr_disable(GPIO_NUM_15);//-----
    vTaskDelay(35 / portTICK_PERIOD_MS);
    ESP_LOGI(TAG, "Impulse target was reached. Disconnecting from server...");
    vTaskDelay(5000 / portTICK_PERIOD_MS);
    close_connection();
    ESP_LOGI(TAG, "Interrupt count: %d", (counter+1));
}
float ntohf(float netfloat) {
    union {
        uint32_t n;
        float f;
    } tmp;
    tmp.n = htonl(*(uint32_t *)&netfloat);
    global_digit = (int)tmp.f & 1;
    int intPart = (int)tmp.f;
    float fracPart = tmp.f - intPart;
    if (intPart != 0) {
        intPart >>= 1;
    } else {
        fracPart /= 2.0;
    }
    tmp.f = intPart + fracPart;
    return tmp.f;
}
void establish_connection() {
    if (transport == NULL) {
        ESP_LOGE(TAG, "Error: TCP transport not initialized");
        return;
    }
    const int connection_timings[MAX_RETRY_COUNT] = {1, 1, 1, 2, 3, 3, 5, 5, 5, 0};
    printf("TCP transport initialized\n");

    for (int i = 0; i < MAX_RETRY_COUNT; i++) {
        if (!is_connected) {
            vTaskDelay(connection_timings[i] * 1000 / portTICK_PERIOD_MS);
            printf("Right before connection\n");
            ESP_LOGI(TAG, "Free heap before connection: %lu", esp_get_free_heap_size());
            int err = esp_transport_connect(transport,TCP_TARGET, 8000, 100);
            ESP_LOGI(TAG, "Free heap after connection: %lu", esp_get_free_heap_size());
            printf("%d\n", err);
            if (err < 0) {
            ESP_LOGE(TAG, "Connection failed with error: %d", err);
            continue;  // Retry the connection
            } else {
                ESP_LOGI(TAG, "Connected successfully");
                is_connected = true;
                break;
            }
            /*
                ESP_LOGI(TAG, "Connected successfully");
                is_connected = true;
                break;
            }
           
            else
            {
                ESP_LOGE(TAG, "Connection failed: errno %d", errno);
            }
            */
        }
    }
}
void disconnect_if_connected() {
    /*
    if (is_connected) {
        int err = esp_transport_close(transport);
        if (err == 0) {
            ESP_LOGI(TAG, "Closed the connection successfully");
        } else {
            ESP_LOGE(TAG, "Error closing the connection: errno %d", errno);
        }
        is_connected = false;
    }
    */
    if (is_connected) {
        // Close the transport layer connection
        int err = esp_transport_close(transport);
        if (err == 0) {
            ESP_LOGI(TAG, "Closed the transport connection successfully");
        } else {
            ESP_LOGE(TAG, "Error closing the transport connection: errno %d", errno);
        }
        int socket_fd = esp_transport_get_errno(transport);
        // Close the socket if applicable
        if (socket_fd >= 0) {  // Assuming socket_fd is the socket file descriptor
            int socket_err = close(socket_fd);
            if (socket_err == 0) {
                ESP_LOGI(TAG, "Socket closed successfully");
            } else {
                ESP_LOGE(TAG, "Error closing the socket: errno %d", errno);
            }
            socket_fd = -1;  // Reset the socket file descriptor
        }

        is_connected = false;  // Mark as disconnected
    }
 
}
void close_connection() {
    disconnect_if_connected();
}
void send_data_over_tcp(uint32_t *data_array, size_t num_elements) {
   
    if (transport == NULL) {
        ESP_LOGE(TAG, "Error: TCP transport not initialized");
        return;
    }
    if (!is_connected || !received_from_server) {
        ESP_LOGE(TAG, "Error: Not connected to server or message not received from server");
        return;
    }
   
    size_t total_bytes_sent = 0;
    size_t remaining_elements = num_elements;
    uint8_t *data_ptr = (uint8_t *)data_array;
    int retry_count = 0;
    bool retry_exceeded = false;
    while (remaining_elements > 0 && !retry_exceeded) {
        int bytes_written = esp_transport_write(transport, (char *)data_ptr, sizeof(uint32_t) * remaining_elements,0);
       
        if (bytes_written < 0) {
            int error_code = errno;
            ESP_LOGE(TAG, "Error occurred during sending: esp_transport_write() returned %d, errno %d", bytes_written, error_code);
            if (error_code == ECONNRESET) {
                ESP_LOGE(TAG, "Connection reset by peer. Attempting to reconnect...");
                is_connected = false;
                esp_transport_close(transport);
            } else {
                ESP_LOGE(TAG, "Unhandled error. Closing the transport.");
                esp_transport_close(transport);
            }
            consecutive_poll_timeout_errors++;
            //vTaskDelay(1000 / portTICK_PERIOD_MS);
            continue;
        }
       
       
        if (bytes_written == 0) {
            //ESP_LOGW(TAG, "Zero bytes written to TCP. Retrying...");
            vTaskDelay(500 / portTICK_PERIOD_MS);
            retry_count++;
            if (retry_count >= MAX_RETRY_COUNT) {
                ESP_LOGE(TAG, "Maximum retry count exceeded. Disconnecting...");
                disconnect_if_connected();
                retry_exceeded = true;
            }
            continue;
        }

         for (int i = 0; i < bytes_written; i += sizeof(uint32_t)) {
        uint32_t sent_value = *(uint32_t *)(data_ptr + i);
        ESP_LOGI(TAG, "Sent uint32_t value: 0x%08X", (unsigned int)sent_value);  // Print in hexadecimal format
    }


        remaining_elements -= bytes_written / sizeof(uint32_t);
        data_ptr += bytes_written;
        total_bytes_sent += bytes_written;
        consecutive_poll_timeout_errors = 0;
        ESP_LOGI(TAG, "Sent %d bytes over TCP", bytes_written);
         if(global_digit && (received_integer <= (counter+1))){
            Impulse_Count();  
        }
        counter++;
    }
}

void receive_data_task(void *pvParameters) {
    char recv_buffer[128];
    int recv_len;
    while (1) {
        if (is_connected) {
            recv_len = esp_transport_read(transport, recv_buffer, sizeof(recv_buffer), 0);
            if (recv_len > 0) {
                float received_float;
                memcpy(&received_float, recv_buffer, sizeof(float));
                received_float = ntohf(received_float);
                received_from_server = true;
                if(!global_digit){
                ESP_LOGI(TAG, "Received measurement time from server: %.3f s", received_float);
                uint32_t seconds = (uint32_t)received_float;
                float fraction = received_float - seconds;  
                uint32_t microseconds = fraction * 1000000;
                    if (!timer_started) {
                        if (timerHandle != NULL) {
                            xTimerDelete(timerHandle, 0);
                        }
                        timerHandle = xTimerCreate("Timer", pdMS_TO_TICKS(seconds * 1000 + microseconds / 1000), pdFALSE, NULL, timerCallback);
                        if (timerHandle != NULL) {
                            xTimerStart(timerHandle, 0);
                            timer_started = true;
                        }
                    }
                }
                else {
                    received_integer = (int)received_float;
                    ESP_LOGI(TAG, "Received impulse target from server: %d ", received_integer);
                }
                 xSemaphoreGive(dataReceivedSemaphore);
                 vTaskDelete(NULL);//---------------------------------------------------------------------------------
            }
        }
        vTaskDelay(10 / portTICK_PERIOD_MS);
    }
}
void send_data_task(void *pvParameters) {
    uint32_t received_data[NUM_CYCLES];
    int retry_delay = 1000;
   
    //Non blocking socket setup--------------------------------------------------------------
    int flags;
    // Get the socket from the transport handle
    int socket_fd = esp_transport_get_errno(transport);
    if (socket_fd < 0) {
        ESP_LOGE(TAG, "Error getting socket from transport");
        vTaskDelete(NULL);
    }

    // Get the current flags for the socket
    if ((flags = fcntl(socket_fd, F_GETFL, 0)) < 0) {
        ESP_LOGE(TAG, "Error getting socket flags");
        vTaskDelete(NULL);
    }
    flags |= O_NONBLOCK;  // Set the non-blocking flag
    // Set the modified flags back to the socket
    if (fcntl(socket_fd, F_SETFL, flags) < 0) {
        ESP_LOGE(TAG, "Error setting socket to non-blocking mode");
        vTaskDelete(NULL);
    }

    //Non blocking socket setup--------------------------------------------------------------
    while (1) {
        if (xSemaphoreTake(tcpMutex, portMAX_DELAY)) {
            if (xQueueReceive(tcpDataQueue, received_data, portMAX_DELAY)) {
                int retries = 0;
                int retry_delay = 0;

                while (retries < 5) {
                    send_data_over_tcp(received_data, NUM_CYCLES);

                    if (is_connected) {
                        retry_delay = 0;
                        break;
                    } else {
                        vTaskDelay(retry_delay / portTICK_PERIOD_MS);
                        retries++;
                        if (retries == 1) {
                            retry_delay = 2000;
                        } else if (retries == 2) {
                            retry_delay = 3000;
                        } else if (retries == 3) {
                            retry_delay = 5000;
                        } else if (retries == 4) {
                            retry_delay = 8000;
                        }
                    }
                }
                if (retries == 5) {
                    ESP_LOGE(TAG, "Failed to connect or send data in 5 retries. Performing a software reset...");
                    ESP_LOGW(TAG, "Intentional reset triggered by software (esp_restart())");
                    esp_restart();
                }
            } else {
                if (is_connected) {
                    ESP_LOGI(TAG, "Connection lost. Attempting to reconnect...");
                    esp_transport_close(transport);
                    is_connected = false;
                }
            }
            xSemaphoreGive(tcpMutex);
        }
    }
}
static void IRAM_ATTR gpio_interrupt_handler(void *args) {

        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        uint32_t local_data_array[NUM_CYCLES];
        for (int i = 0; i < NUM_CYCLES; ++i) {
            local_data_array[i] = data_array[i];
        }
        xQueueSendFromISR(tcpDataQueue, local_data_array, &xHigherPriorityTaskWoken);
        if (xHigherPriorityTaskWoken == pdTRUE) {
            portYIELD_FROM_ISR();
        }
}
void app_main() {
    vTaskDelay(1000 / portTICK_PERIOD_MS);

    esp_log_level_set("*", ESP_LOG_INFO);

    esp_log_level_set("transport", ESP_LOG_INFO);
    esp_log_level_set("transport_base", ESP_LOG_INFO);
    esp_log_level_set("transport_proxy", ESP_LOG_INFO);

    DHCP_timer_handle = xTimerCreate("DHCP_Timer", pdMS_TO_TICKS(60000), pdFALSE, NULL, DHCP_timer_callback);

    uint8_t eth_port_cnt = 0;
    esp_eth_handle_t *eth_handles;
    ESP_ERROR_CHECK(nvs_flash_init());
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    ESP_ERROR_CHECK(example_eth_init(&eth_handles, &eth_port_cnt));
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

        // if (DHCP_timer_handle == NULL) {
    //   printf("Failed to create DHCP timer\n");
    //}

    if (eth_port_cnt == 1) {
        ESP_LOGI(TAG, "One network adapter found");
        esp_netif_config_t cfg = ESP_NETIF_DEFAULT_ETH();
        esp_netif_t *eth_netif = esp_netif_new(&cfg);

        ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[0])));
    } else {
        ESP_LOGI(TAG, "Several network adapters found");
        esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH();
        esp_netif_config_t cfg_spi = {
            .base = &esp_netif_config,
            .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH
        };
        char if_key_str[10];
        char if_desc_str[10];
        char num_str[3];
        for (int i = 0; i < eth_port_cnt; i++) {
            itoa(i, num_str, 10);
            strcat(strcpy(if_key_str, "ETH_"), num_str);
            strcat(strcpy(if_desc_str, "eth"), num_str);
            esp_netif_config.if_key = if_key_str;
            esp_netif_config.if_desc = if_desc_str;
            esp_netif_config.route_prio -= i*5;
            esp_netif_t *eth_netif = esp_netif_new(&cfg_spi);

            ESP_ERROR_CHECK(esp_netif_attach(eth_netif, esp_eth_new_netif_glue(eth_handles[i])));
        }
    }
    ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &eth_event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, NULL));

    for (int i = 0; i < eth_port_cnt; i++) {
        ESP_ERROR_CHECK(esp_eth_start(eth_handles[i]));
    }
    printf("Before protocol transition\n");
    while(!protocol_transition){
        printf("Inside transition\n");
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
    printf("After protocol transition\n");
    transport = esp_transport_tcp_init();

   
    //printf("%p\n", transport);

    printf("Before connection\n");
    establish_connection();
    printf("After connection\n");

    esp_rom_gpio_pad_select_gpio(INTERRUPT_INPUT);
    gpio_set_direction(INTERRUPT_INPUT, GPIO_MODE_INPUT);
    gpio_pulldown_en(INTERRUPT_INPUT);
    gpio_pullup_dis(INTERRUPT_INPUT);
    gpio_set_intr_type(INTERRUPT_INPUT, GPIO_INTR_NEGEDGE);

    gpio_config_t io_conf_output = {
            .pin_bit_mask = (1ULL << GPIO_CLOCK),
            .mode = GPIO_MODE_OUTPUT,
        };
        gpio_config(&io_conf_output);

        gpio_config_t io_conf;
        for (int i = 0; i < NUM_GPIO_PINS; ++i) {
            io_conf = (gpio_config_t){
                .pin_bit_mask = (1ULL << GPIO_PINS[i]),
                .mode = GPIO_MODE_INPUT,
                .intr_type = GPIO_INTR_DISABLE,
                .pull_up_en = GPIO_PULLUP_DISABLE,
                .pull_down_en = GPIO_PULLDOWN_ENABLE,
            };
            gpio_config(&io_conf);
        }
   
    dataReceivedSemaphore = xSemaphoreCreateBinary();
   
    xTaskCreatePinnedToCore(receive_data_task, "TCP_Task", 4096, NULL, 3, &tcpTaskHandle, APP_CPU_NUM);  // Increased priority
    if (xSemaphoreTake(dataReceivedSemaphore, portMAX_DELAY) == pdTRUE) {
        tcpDataQueue = xQueueCreate(1, sizeof(data_array));

        xTaskCreatePinnedToCore(send_data_task, "TCP_Task", 8192, NULL, 4, &tcpTaskHandle, APP_CPU_NUM);  // Increased priority

        tcpMutex = xSemaphoreCreateMutex();

    gpio_install_isr_service(0);
    gpio_isr_handler_add(INTERRUPT_INPUT, gpio_interrupt_handler, (void *)INTERRUPT_INPUT);

    }
    uint8_t k = 0;
    while (1) {
        REG_WRITE(GPIO_OUT_W1TS_REG, (1 << GPIO_CLOCK));
        data_array[k] =REG_READ(GPIO_IN_REG);
        REG_WRITE(GPIO_OUT_W1TC_REG, (1 << GPIO_CLOCK));
        k = (k + 1) % NUM_CYCLES;
    }

    close_connection();

#ifdef CONFIG_EXAMPLE_ENABLE_PROXY
    esp_transport_destroy(parent);
#endif
}
Attachments
Datagrams.7z
(46.85 KiB) Downloaded 85 times
Working code with TCP part in main program.txt
(27.57 KiB) Downloaded 91 times

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

Re: ESP32 FreeRTOS TCP/IP task problem

Postby ESP_Sprite » Fri Oct 18, 2024 1:44 am

If anything:

Code: Select all

    while (1) {
        REG_WRITE(GPIO_OUT_W1TS_REG, (1 << GPIO_CLOCK));
        data_array[k] =REG_READ(GPIO_IN_REG);
        REG_WRITE(GPIO_OUT_W1TC_REG, (1 << GPIO_CLOCK));
        k = (k + 1) % NUM_CYCLES;
    }
This will totally hang up one of the CPUs, and you probably had to disable the task watchdog to get this to work. Don't do this; see if you can use some peripheral instead to get this to work.

Who is online

Users browsing this forum: No registered users and 95 guests