Page 1 of 1

ESP32 crash after calling httpd_stop

Posted: Mon Mar 14, 2022 10:49 am
by zazas321
Hello. I am using esp http_server file serving example and I have slightly modified it.
When the program starts, I start and initialise the wifi in AP_STA mode with the following function:

Code: Select all

void WIFI_INIT_AP_STA(void)
{
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    //ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); // since we always do this after scanning, dont need to add event loop anymore

    esp_netif_t *ap_netif = esp_netif_create_default_wifi_ap();
    assert(ap_netif);

    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&wifi_event_handler,NULL,NULL));


    wifi_config_t wifi_config = {
        .ap = {
            .ssid = EXAMPLE_ESP_WIFI_SSID_AP,
            .ssid_len = strlen(EXAMPLE_ESP_WIFI_SSID_AP),
            .channel = EXAMPLE_ESP_WIFI_CHANNEL,
            .password = EXAMPLE_ESP_WIFI_PASS_AP,
            .max_connection = EXAMPLE_MAX_STA_CONN,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK
        },
    };
    if (strlen(EXAMPLE_ESP_WIFI_PASS_AP) == 0) {
        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
    }
    

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI("WIFI AP", "wifi_init_softap finished. SSID:%s password:%s channel:%d",
             EXAMPLE_ESP_WIFI_SSID_AP, EXAMPLE_ESP_WIFI_PASS_AP, EXAMPLE_ESP_WIFI_CHANNEL);
}
Then, after the wifi is initialsied I start the webserver:

Code: Select all

esp_err_t start_file_server(const char *base_path)
{
    static struct file_server_data *server_data = NULL;
    /* Validate file storage base path */
    if (!base_path || strcmp(base_path, "/spiffs") != 0) {
        ESP_LOGE("START_SERVER", "File server presently supports only '/spiffs' as base path");
        return ESP_ERR_INVALID_ARG;
    }

    if (server_data) {
        ESP_LOGE("START_SERVER", "File server already started");
        return ESP_ERR_INVALID_STATE;
    }

    /* Allocate memory for server data */
    server_data = calloc(1, sizeof(struct file_server_data));
    if (!server_data) {
        ESP_LOGE("START_SERVER", "Failed to allocate memory for server data");
        return ESP_ERR_NO_MEM;
    }
    strlcpy(server_data->base_path, base_path,
            sizeof(server_data->base_path));

    httpd_handle_t server = NULL;
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    /* Use the URI wildcard matching function in order to
     * allow the same handler to respond to multiple different
     * target URIs which match the wildcard scheme */
    config.uri_match_fn = httpd_uri_match_wildcard;

    ESP_LOGI("START_SERVER", "Starting HTTP Server on port: '%d'", config.server_port);
    if (httpd_start(&server, &config) != ESP_OK) {
        ESP_LOGE("START_SERVER", "Failed to start file server!");
        return ESP_FAIL;
    }

    //URI handler for getting uploaded files 
    httpd_uri_t file_download = {
        .uri       = "/",  // Match all URIs of type /path/to/file
        .method    = HTTP_GET,
        .handler   = download_get_handler,
       .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_download);





    httpd_uri_t image_handler = {
        .uri       = "/",  // Match all URIs of type /path/to/file
        .method    = HTTP_GET,
        .handler   = image_get_handler,
       .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_download);



    

        /* URI handler for uploading files to server */
    httpd_uri_t file_upload = {
        .uri       = "/upload/*",   // Match all URIs of type /upload/path/to/file
        .method    = HTTP_POST,
        .handler   = upload_post_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_upload);

    /* URI handler for deleting files from server */
    httpd_uri_t file_delete = {
        .uri       = "/delete/*",   // Match all URIs of type /delete/path/to/file
        .method    = HTTP_POST,
        .handler   = delete_post_handler,
        .user_ctx  = server_data    // Pass server data as context
    };
    httpd_register_uri_handler(server, &file_delete);



        httpd_uri_t uri_post = {
        .uri      = "/rollback",
        .method   = HTTP_POST,
        .handler  = post_handler,
        .user_ctx = NULL
    };
    httpd_register_uri_handler(server, &uri_post);

    return ESP_OK;
}

So in my main.c, I call:

Code: Select all

    WIFI_INIT_AP_STA();
    ESP_ERROR_CHECK(start_file_server("/spiffs"));

Everything works as expected. Notice in my WIFI_INIT_AP_STA I have registered wifi_event_handler and there I can capture when the client connects and disconnects to my access point.

Code: Select all


static void wifi_event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{
    if (event_id == WIFI_EVENT_AP_STACONNECTED) {
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
        ESP_LOGI(TAG_WEBSERVER, "station "MACSTR" join, AID=%d",MAC2STR(event->mac), event->aid);
        wifi_connected_clients += 1;
        printf("connected clients = %u \n",wifi_connected_clients);
    } else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) {
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
        ESP_LOGI(TAG_WEBSERVER, "station "MACSTR" leave, AID=%d",MAC2STR(event->mac), event->aid);
        wifi_connected_clients -= 1;
        printf("connected clients = %u \n",wifi_connected_clients);
        if(wifi_connected_clients == 0){
        httpd_handle_t* server = (httpd_handle_t*) arg;
            if (*server) {
                ESP_LOGI(TAG_WEBSERVER, "Stopping webserver");
                httpd_stop(*server);
                *server = NULL;
            }
        }
    }
}

When the client is disconnected, I want to stop the webserver so I use httpd_stop(*server);

But the program crashes immediately after calling this:

Code: Select all

connected clients = 0
Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x400e042f  PS      : 0x00060030  A0      : 0x801b7130  A1      : 0x3ffe1440
0x400e042f: wifi_event_handler at C:\Users\petrikas.lu\Work\Projects\Elstat\elstat\build/../components/WIFI/WIFI.c:527

A2      : 0x00000000  A3      : 0x3f42bf70  A4      : 0x00000000  A5      : 0x3ffbc040  
A6      : 0x00000000  A7      : 0x00000001  A8      : 0x800e042a  A9      : 0x3ffe13f0  
A10     : 0x00000017  A11     : 0x3ffdfc18  A12     : 0x3f4111a4  A13     : 0x00006a86
A14     : 0x3f411130  A15     : 0x00000098  SAR     : 0x00000004  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff


Backtrace:0x400e042c:0x3ffe14400x401b712d:0x3ffe1480 0x401b6c72:0x3ffe14b0 0x401b6d45:0x3ffe14f0 0x40090675:0x3ffe1510
0x400e042c: wifi_event_handler at C:\Users\petrikas.lu\Work\Projects\Elstat\elstat\build/../components/WIFI/WIFI.c:525

0x401b712d: handler_execute at C:/Users/petrikas.lu/esp/esp-idf/components/esp_event/esp_event.c:145

0x401b6c72: esp_event_loop_run at C:/Users/petrikas.lu/esp/esp-idf/components/esp_event/esp_event.c:590 (discriminator 3)

0x401b6d45: esp_event_loop_run_task at C:/Users/petrikas.lu/esp/esp-idf/components/esp_event/esp_event.c:115 (discriminator 15)

0x40090675: vPortTaskWrapper at C:/Users/petrikas.lu/esp/esp-idf/components/freertos/port/xtensa/port.c:131





ELF file SHA256: 6256c365e96cde0f

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:6604
ho 0 tail 12 room 4
load:0x40078000,len:14808
ho 0 tail 12 room 4
load:0x40080400,len:3792
0x40080400: _init at ??:?

entry 0x40080694
Could someone help me understand what could be wrong and how to properly stop the webserver?