(I hope this is the right place to ask questions about the ESP8266_RTOS_SDK)
I have a program that I've taken from the samples directory (protocols/tcp_client) in the RTOS SDK and added code from the uart sample just so I can use the keyboard to tell the client when to start. The tcp_client task simply does a socket send to & recv from the server (a simple sockets server running on a linux desktop). It runs great until I tried to add another sample task:
static void test_task(void *pvParameters)
{
vTaskDelay(MYDELAY2);
ESP_LOGI(TAG, "asdf 123");
}
And then, in the app_main(), I create the task:
xTaskCreate(test_task, "test", 2048, NULL, 10, NULL);
I try to run it and it either locks up and then crashes or just crashes as soon as it connects to the server. It usually crashes right after it prints out the message in the 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);
}
When I added the task for the uart it works, but when I add the task to print the test message and do the time delay, it crashes.