Page 1 of 1

(xQueueGenericReceive)- assert failed! after esp_wifi_scan_get_ap_records()

Posted: Wed Jun 20, 2018 2:20 pm
by speedcuber92
Hello all, I recently started with freeRTOS on esp32 using ESP-IDF.
I'm trying to build and app that simply scans all available networks, and prints the details...
In the event handler, the wifi scan is started upon SYSTEM_EVENT_STA_START and then, upon SYSTEM_EVENT_SCAN_DONE a binary semaphore is given to a task.
Inside the task, esp_wifi_scan_get_ap_num() and esp_wifi_scan_get_ap_records() are called.
Ufortunately, app crashes with the following:
C:/msys32/home/Toni/esp/esp-idf/components/freertos/queue.c:1441 (xQueueGenericReceive)- assert failed!
abort() was called at PC 0x4008bfa0 on core 1
0x4008bfa0: xQueueGenericReceive at C:/msys32/home/Toni/esp/esp-idf/components/freertos/queue.c:2037


Backtrace: 0x4008d353:0x3ffd7ee0 0x4008d4ab:0x3ffd7f00 0x4008bfa0:0x3ffd7f20 0x400d244a:0x3ffd7f60
0x4008d353: invoke_abort at C:/msys32/home/Toni/esp/esp-idf/components/esp32/panic.c:649

0x4008d4ab: abort at C:/msys32/home/Toni/esp/esp-idf/components/esp32/panic.c:649

0x4008bfa0: xQueueGenericReceive at C:/msys32/home/Toni/esp/esp-idf/components/freertos/queue.c:2037

0x400d244a: app_task at C:/msys32/home/Toni/esp/wifi-scan-test/main/wifi-scan-test.c:57
I noticed that app would not crash if all the functions are called from the event handler directly, or if I comment out esp_wifi_scan_get_ap_records() function inside the task!
I checked the line 1441 inside queue.c but I really don't understand how could I affect this from the app...
Please help.

Here is the code:

Code: Select all

#include <stdio.h>
#include "esp_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "soc/timer_group_struct.h"
#include "driver/periph_ctrl.h"
#include "driver/timer.h"
#include <esp_task_wdt.h>
#include <esp_log.h>
#include "freertos/semphr.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"

wifi_scan_config_t scan_config;
SemaphoreHandle_t scan_semaphore;
wifi_country_t country_config;
wifi_ap_record_t ap_records;
uint16_t num_of_scanned_aps;

esp_err_t event_handler(void *ctx, system_event_t *event)
{
    int ev = event ->event_id;
    switch(ev)
    {
        case SYSTEM_EVENT_STA_START:
            ESP_LOGI("WIFI-SCAN-TEST", "SYSTEM_EVENT_STA_START");
            ESP_ERROR_CHECK(esp_wifi_set_country(&country_config));
            ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, 0));
            break;
        case SYSTEM_EVENT_SCAN_DONE:
            ESP_LOGI("WIFI-SCAN-TEST", "SYSTEM_EVENT_SCAN_DONE");
            xSemaphoreGive(scan_semaphore);
            break;
        default:
            ESP_LOGI("WIFI-SCAN-TEST", "Default event occured %d", ev);
            break;
    }

    return ESP_OK;
}

void app_task(void* p)
{
    while(1)
    {        
        if(xSemaphoreTake(scan_semaphore, portMAX_DELAY) == pdTRUE)
        {
            ESP_LOGI("SEMAPHORE", "Semaphore taken");

            ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&num_of_scanned_aps));
            ESP_LOGI("SCANNED", "APS number: %d", num_of_scanned_aps);  

            ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&num_of_scanned_aps, &ap_records));
            ESP_LOGI("SCANNED", "RSSI: %d", ap_records.rssi);
        } 
    }
}

void app_main()
{
    // Initialize NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
    
    wifi_config_t wifi_config;

    //wifi_config.sta.ssid = ;
    //wifi_config.sta.password = ;
    wifi_config.sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
    wifi_config.sta.bssid_set = 0;
    //wifi_config.sta.bssid = ;
    wifi_config.sta.channel = 0;
    wifi_config.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL;
    wifi_config.sta.threshold.rssi = -127;
    wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;

    //Wifi scan cnofig
    scan_config.show_hidden = 1;
    scan_config.scan_type = WIFI_SCAN_TYPE_ACTIVE;
    scan_config.scan_time.active.min = 0; 
    scan_config.scan_time.active.max = 1500;
    scan_config.channel = 0;

    //Wifi country config
    country_config.cc[0] = 'E';
    country_config.cc[1] = 'U';
    country_config.schan = 1;
    country_config.nchan = 13;
    country_config.policy = WIFI_COUNTRY_POLICY_AUTO;    

    //Initialize wifi
    tcpip_adapter_init();
    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
    ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));

    //Create semaphore
    scan_semaphore = xSemaphoreCreateBinary();

    //Create app task
    xTaskCreate(app_task, "app_task", 4000, NULL, 2, NULL);

    //Set mode -> station
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

    //Set config for station
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}

Re: (xQueueGenericReceive)- assert failed! after esp_wifi_scan_get_ap_records()

Posted: Thu Jun 21, 2018 4:10 am
by kolban
I'll stick my neck out and say your problem is here:

Code: Select all

ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&num_of_scanned_aps, &ap_records));
This statement asks to retrieve "num_of_scanned_ap" records and place them in the storage pointed to by "&ap_records". However, your definition:

Code: Select all

wifi_ap_record_t ap_records;
is only a single record. I think what you want to do is determine the number of records you are about to retrieve and then allocate a buffer large enough to hold them all and pass in the buffer as the target of the copy command.

Re: (xQueueGenericReceive)- assert failed! after esp_wifi_scan_get_ap_records()

Posted: Thu Jun 21, 2018 6:36 am
by speedcuber92
Ok I'll try that, thanks!
Meanwhile I tried the same code, only this time I didn't use semaphore, but event group, and it didn't crash...weird stuff...I'll try to expand the buffer and let you know what happens.

Ok so I did what you told me and it works like a charm now. Thank you very much!

Code: Select all

#include <stdio.h>
#include "esp_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/event_groups.h"
#include "soc/timer_group_struct.h"
#include "driver/periph_ctrl.h"
#include "driver/timer.h"
#include <esp_task_wdt.h>
#include <esp_log.h>
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "nvs_flash.h"

wifi_scan_config_t scan_config;
wifi_country_t country_config;

SemaphoreHandle_t scan_semaphore;
//EventGroupHandle_t event_group_handle;
#define SCAN_DONE_GROUP_BIT    (1<<0)
#define DESIRED_GROUP_BITS     SCAN_DONE_GROUP_BIT

#define NETWORK_SSID            "TenzorOffice2"      
#define NETWORK_PASS            "Tenzor1234"      



esp_err_t event_handler(void *ctx, system_event_t *event)
{
    int ev = event ->event_id;
    switch(ev)
    {
        case SYSTEM_EVENT_STA_START:
            ESP_LOGI("WIFI-SCAN-TEST", "SYSTEM_EVENT_STA_START");
            ESP_ERROR_CHECK(esp_wifi_set_country(&country_config));
            ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, 0));
            //ESP_ERROR_CHECK(esp_wifi_connect());
            break;
        case SYSTEM_EVENT_SCAN_DONE:
            ESP_LOGI("WIFI-SCAN-TEST", "SYSTEM_EVENT_SCAN_DONE");
            xSemaphoreGive(scan_semaphore);
            //xEventGroupSetBits(event_group_handle, SCAN_DONE_GROUP_BIT);
            break;
        case SYSTEM_EVENT_STA_CONNECTED:
            ESP_LOGI("WIFI-SCAN-TEST", "SYSTEM_EVENT_STA_CONNECTED");
            break;
        case SYSTEM_EVENT_STA_GOT_IP:
            ESP_LOGI("WIFI-SCAN-TEST", "SYSTEM_EVENT_STA_GOT_IP");
            //Create TCP/UDP tasks here
            break;        
        case SYSTEM_EVENT_STA_DISCONNECTED:
            ESP_LOGI("WIFI-SCAN-TEST", "SYSTEM_EVENT_STA_DISCONNECTED");
            ESP_ERROR_CHECK(esp_wifi_connect());
            break;            
        default:
            ESP_LOGI("WIFI-SCAN-TEST", "Default event occured %d", ev);
            break;
    }

    return ESP_OK;
}

void app_task(void* p)
{
    //EventBits_t event_bits;
    while(1)
    {      
        //event_bits = xEventGroupWaitBits(event_group_handle, SCAN_DONE_GROUP_BIT, pdTRUE, pdTRUE, portMAX_DELAY);
        //if((event_bits & DESIRED_GROUP_BITS) == SCAN_DONE_GROUP_BIT)
        if(xSemaphoreTake(scan_semaphore, portMAX_DELAY))
        {
            //ESP_LOGI("EVENT GROUP", "SCAN_DONE_GROUP_BIT bit set");
            ESP_LOGI("SEMAPHORE", "Semaphore taken");

            uint16_t num_of_scanned_aps;
            ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&num_of_scanned_aps));
            ESP_LOGI("SCANNED", "APS number: %d", num_of_scanned_aps); 

            wifi_ap_record_t *ap_records = (wifi_ap_record_t*)calloc(num_of_scanned_aps, sizeof(wifi_ap_record_t));

            ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&num_of_scanned_aps, ap_records));
            for(uint8_t i=0; i<num_of_scanned_aps; i++)
            {
                ESP_LOGI("SCANNED", "BSSID: %s", ap_records[i].bssid);
                ESP_LOGI("SCANNED", "SSID: %s", ap_records[i].ssid);
                ESP_LOGI("SCANNED", "PRIMARY: %d", ap_records[i].primary);
                ESP_LOGI("SCANNED", "SECONDARY: %d", ap_records[i].second);
                ESP_LOGI("SCANNED", "RSSI: %d", ap_records[i].rssi);
                printf("\n\n");
            }
            free(ap_records);
        } 
    }
}

void app_main()
{
    // Initialize NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
    
    wifi_config_t wifi_config;

    sprintf((char*)wifi_config.sta.ssid, NETWORK_SSID);
    sprintf((char*)wifi_config.sta.password, NETWORK_PASS);

    wifi_config.sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
    wifi_config.sta.bssid_set = 0;
    //wifi_config.sta.bssid = ;
    wifi_config.sta.channel = 0;
    wifi_config.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL;
    wifi_config.sta.threshold.rssi = -127;
    wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN;

    //Wifi scan cnofig
    scan_config.show_hidden = 1;
    scan_config.scan_type = WIFI_SCAN_TYPE_ACTIVE;
    scan_config.scan_time.active.min = 0; 
    scan_config.scan_time.active.max = 1500;
    scan_config.channel = 0;

    //Wifi country config
    sprintf((char*)country_config.cc, "EU");
    country_config.schan = 1;
    country_config.nchan = 13;
    country_config.policy = WIFI_COUNTRY_POLICY_AUTO;    

    //Initialize wifi
    tcpip_adapter_init();
    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
    ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));

    //Create event group or semaphore
    //event_group_handle = xEventGroupCreate();
    scan_semaphore = xSemaphoreCreateBinary();
    //Create app task
    xTaskCreate(app_task, "app_task", 8000, NULL, 1, NULL);

    //Set mode -> station
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

    //Set config for station
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());
}