FreeRTOS task and Queue are not working together

lalitahuja33
Posts: 16
Joined: Wed Jul 22, 2020 1:03 pm

FreeRTOS task and Queue are not working together

Postby lalitahuja33 » Sat Oct 31, 2020 9:59 am

I'm trying to implement esp-now in my existing code which has FreeRTOS tasks and what I have observed that the Receive function of esp-now doesn't work when other RTOS tasks are there in the app_main but when I comment those RTOS tasks the Receive function works.

code that works

Code: Select all

    s_recv_queue = xQueueCreate(10, sizeof(recv_packet_t));
    assert(s_recv_queue);
    BaseType_t err = xTaskCreatePinnedToCore(queue_process_task, "recv_task", 8192, NULL, 6, NULL,1);
    assert(err == pdPASS);
    s_evt_group = xEventGroupCreate();
    assert(s_evt_group);

    init_espnow_master();
    send_espnow_data();

//    vTaskDelay(200);
//	xTaskCreatePinnedToCore(rtcc_task,"RTCC_TASK",4096,NULL,3,&RTCCHandle,1);
//	vTaskDelay(200);
//	xTaskCreatePinnedToCore(wifi_task,"WiFi_TASK",8192,NULL,5,&WIFIHandle,0);
//	vTaskDelay(200);
//	xTaskCreatePinnedToCore(ledc_task,"P10_TASK",8192,NULL,5,&LEDCHandle,1);
//	vTaskDelay(200);
//	xTaskCreatePinnedToCore(r485_task,"RS485_TASK",4096,NULL,6,&R485Handle,1);
code that doesn't work

Code: Select all

    s_recv_queue = xQueueCreate(10, sizeof(recv_packet_t));
    assert(s_recv_queue);
    BaseType_t err = xTaskCreatePinnedToCore(queue_process_task, "recv_task", 8192, NULL, 6, NULL,1);
    assert(err == pdPASS);
    s_evt_group = xEventGroupCreate();
    assert(s_evt_group);

    init_espnow_master();
    send_espnow_data();
    
       vTaskDelay(200);
	xTaskCreatePinnedToCore(rtcc_task,"RTCC_TASK",4096,NULL,3,&RTCCHandle,1);
	vTaskDelay(200);
	xTaskCreatePinnedToCore(wifi_task,"WiFi_TASK",8192,NULL,5,&WIFIHandle,0);
	vTaskDelay(200);
	xTaskCreatePinnedToCore(ledc_task,"P10_TASK",8192,NULL,5,&LEDCHandle,1);
	vTaskDelay(200);
	xTaskCreatePinnedToCore(r485_task,"RS485_TASK",4096,NULL,6,&R485Handle,1);

abansal22
Posts: 105
Joined: Wed Apr 22, 2020 8:24 am

Re: FreeRTOS task and Queue are not working together

Postby abansal22 » Sat Oct 31, 2020 11:23 am

Hello,
Please provide the full code.

Thanks

lalitahuja33
Posts: 16
Joined: Wed Jul 22, 2020 1:03 pm

Re: FreeRTOS task and Queue are not working together

Postby lalitahuja33 » Sat Oct 31, 2020 11:55 am

Hey @abansal22
Here is the esp now code that is not working with the RTOS task combined with the above.
But it wirkes when run standalone.

Code: Select all

#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/event_groups.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "tcpip_adapter.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_now.h"


#include "sdkconfig.h"

static const char *TAG = "Basic_Master";

static xQueueHandle s_recv_queue;



// Define the structure of your data
typedef struct __attribute__((packed)) {
    float item1;
    float item2;
    float item3;
    float item4;
    float item5;
    float item6;
} my_data_t;

void my_data_populate(my_data_t *data);

static EventGroupHandle_t s_evt_group;

// Destination MAC address
// The default address is the broadcast address, which will work out of the box, but the slave will assume every tx succeeds.
// Setting to the master's address will allow the slave to determine if sending succeeded or failed.
//   note: with default config, the master's WiFi driver will log this for you. eg. I (721) wifi:mode : sta (12:34:56:78:9a:bc)
#define MY_RECEIVER_MAC {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}

#define MY_ESPNOW_PMK "pmk1234567890123"
#define MY_ESPNOW_CHANNEL 1

typedef struct {
    uint8_t sender_mac_addr[ESP_NOW_ETH_ALEN];
    my_data_t data;
} recv_packet_t;


// Your task to handle received my_data_t
void my_data_receive(const uint8_t *sender_mac_addr, const my_data_t *data)
{
    ESP_LOGI(TAG, "Data from "MACSTR": 1 - %f 2 - %f 3 - %f 4 - %f 5 - %f, 6 - %f",
                MAC2STR(sender_mac_addr),
                data->item1,
				data->item2,
				data->item3,
				data->item4,
				data->item5,
				data->item6);
}

static void queue_process_task(void *p)
{
    static recv_packet_t recv_packet;

    ESP_LOGI(TAG, "Listening");
    for(;;)
    {
        if(xQueueReceive(s_recv_queue, &recv_packet, portMAX_DELAY) != pdTRUE)
        {
            continue;
        }

        // Refer to user function
        my_data_receive(recv_packet.sender_mac_addr, &recv_packet.data);
    }
}

#define MY_ESPNOW_WIFI_MODE WIFI_MODE_STA
#define MY_ESPNOW_WIFI_IF   ESP_IF_WIFI_STA
// #define MY_ESPNOW_WIFI_MODE WIFI_MODE_AP
// #define MY_ESPNOW_WIFI_IF   ESP_IF_WIFI_AP

void my_data_populate(my_data_t *data)
{
    ESP_LOGI(TAG, "Populating my_data t");
    data->item1 = 11.11;
	data->item2 = 22.22;
	data->item3 = 33.33;
	data->item4 = 44.44;
	data->item5 = 55.55;
	data->item6 = 66.66;

}


static void packet_sent_cb(const uint8_t *mac_addr, esp_now_send_status_t status)
{
    if (mac_addr == NULL) {
        ESP_LOGE(TAG, "Send cb arg error");
        return;
    }

    assert(status == ESP_NOW_SEND_SUCCESS || status == ESP_NOW_SEND_FAIL);
    xEventGroupSetBits(s_evt_group, BIT(status));
}

static void recv_cb(const uint8_t *mac_addr, const uint8_t *data, int len)
{
    static recv_packet_t recv_packet;

    ESP_LOGI(TAG, "%d bytes incoming from " MACSTR, len, MAC2STR(mac_addr));
    
    if(len != sizeof(my_data_t))
    {
        ESP_LOGE(TAG, "Unexpected data length: %d != %u", len, sizeof(my_data_t));
        return;
    }

    memcpy(&recv_packet.sender_mac_addr, mac_addr, sizeof(recv_packet.sender_mac_addr));
    memcpy(&recv_packet.data, data, len);
    if (xQueueSend(s_recv_queue, &recv_packet, 0) != pdTRUE) {
        ESP_LOGW(TAG, "Queue full, discarded");
        return;
    }
}

static void init_espnow_master(void)
{
    const wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK( nvs_flash_erase() );
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );
    tcpip_adapter_init();
    ESP_ERROR_CHECK( esp_event_loop_create_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(MY_ESPNOW_WIFI_MODE) );
    ESP_ERROR_CHECK( esp_wifi_start() );
#if MY_ESPNOW_ENABLE_LONG_RANGE
    ESP_ERROR_CHECK( esp_wifi_set_protocol(MY_ESPNOW_WIFI_IF, WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N|WIFI_PROTOCOL_LR) );
#endif
    ESP_ERROR_CHECK( esp_now_init() );
    ESP_ERROR_CHECK( esp_now_register_recv_cb(recv_cb) );
    ESP_ERROR_CHECK( esp_now_set_pmk((const uint8_t *)MY_ESPNOW_PMK) );

    ESP_ERROR_CHECK( esp_now_register_send_cb(packet_sent_cb) );
    // Alter this if you want to specify the gateway mac, enable encyption, etc
    const esp_now_peer_info_t broadcast_destination = {
        .peer_addr = MY_RECEIVER_MAC,
        .channel = MY_ESPNOW_CHANNEL,
        .ifidx = MY_ESPNOW_WIFI_IF
    };
    ESP_ERROR_CHECK( esp_now_add_peer(&broadcast_destination) );
}


static esp_err_t send_espnow_data(void)
{
    const uint8_t destination_mac[] = MY_RECEIVER_MAC;
    static my_data_t data;

    // Go to the user function to populate the data to send
    my_data_populate(&data);

    // Send it
    ESP_LOGI(TAG, "Sending %u bytes to " MACSTR, sizeof(data), MAC2STR(destination_mac));
    esp_err_t err = esp_now_send(destination_mac, (uint8_t*)&data, sizeof(data));
    if(err != ESP_OK)
    {
        ESP_LOGE(TAG, "Send error (%d)", err);
        return ESP_FAIL;
    }

    // Wait for callback function to set status bit
    EventBits_t bits = xEventGroupWaitBits(s_evt_group, BIT(ESP_NOW_SEND_SUCCESS) | BIT(ESP_NOW_SEND_FAIL), pdTRUE, pdFALSE, 2000 / portTICK_PERIOD_MS);
    if ( !(bits & BIT(ESP_NOW_SEND_SUCCESS)) )
    {
        if (bits & BIT(ESP_NOW_SEND_FAIL))
        {
            ESP_LOGE(TAG, "Send error");
            return ESP_FAIL;
        }
        ESP_LOGE(TAG, "Send timed out");
        return ESP_ERR_TIMEOUT;
    }

    ESP_LOGI(TAG, "Sent!");
    return ESP_OK;
}


void app_main(void)
{
    s_recv_queue = xQueueCreate(10, sizeof(recv_packet_t));
    assert(s_recv_queue);
    BaseType_t err = xTaskCreate(queue_process_task, "recv_task", 8192, NULL, 4, NULL);
    assert(err == pdPASS);
    s_evt_group = xEventGroupCreate();
    assert(s_evt_group);

    init_espnow_master();
    send_espnow_data();
}

alexvazquez
Posts: 2
Joined: Wed Jan 12, 2022 12:04 am

Re: FreeRTOS task and Queue are not working together

Postby alexvazquez » Wed Jan 12, 2022 12:06 am

Hi, Im having same issue trying to use espnow with my ESP32 using arduino and the board reboots. Did you find out how to make it work with FreeRTOS? Appreicate it

Who is online

Users browsing this forum: Google [Bot] and 171 guests