FreeRTOS task and Queue are not working together

lalitahuja33
Posts: 15
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: 63
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: 15
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();
}

Who is online

Users browsing this forum: Bing [Bot] and 51 guests