簡體   English   中英

C++ ESP8266 微控制器上的向量迭代器問題

[英]C++ Problem with Vector Iterator on ESP8266 Microcontroller

我目前在 C++ 中遇到向量迭代器的問題。 該應用程序在 ESP8266 NodeMCU 微控制器上運行。 一旦我調用 function CWebServer::getAvailableNetworks() (可以在下面找到實現),程序崩潰並且我收到以下錯誤:

User exception (panic/abort/assert)
Abort called

>>>stack>>>

ctx: cont
sp: 3ffffd10 end: 3fffffc0 offset: 0000
3ffffd10:  00000000 00000000 00000000 00000000
3ffffd20:  000000fe 00000000 00000000 00000000
3ffffd30:  00000000 00000000 00000000 b8b1aabc  
3ffffd40:  3ffefd60 3fff44cc 00000000 40205e9c
3ffffd50:  3fff451c 00000001 3fff44fc 4020e7ea  
3ffffd60:  00000000 00000000 00000000 4020e7fc
3ffffd70:  00000000 3ffffe0c 00000000 4020e219  
3ffffd80:  3ffffe04 00000000 00000000 00000000
3ffffd90:  00000000 00000000 00000000 40226fac  
3ffffda0:  00000000 40205e9c 3fff451c 40226fbd
3ffffdb0:  3fff44fc 3fff44cc 3fff44fc 402277d8
3ffffdc0:  00000000 00000000 3fff44fc 4020e224  
3ffffdd0:  40000000 00000000 00000000 00000000  
3ffffde0:  00000000 00000000 00000000 40226fac
3ffffdf0:  3ffefb6c 40205e9c 3fff451c 40226fbd
3ffffe00:  3fff44fc 4022770c 3fff44fc 40227783  
3ffffe10:  3fff451c 00000001 3ffffe80 40209f32
3ffffe20:  3ffe90e4 3fffc200 3ffe90f1 4022f3b3  
3ffffe30:  3fff43dc 3ffefa4c 3ffe8a37 4020ca74
3ffffe40:  4020ca68 3ffefa4c 3ffe8a37 40205e9c  
3ffffe50:  00000001 3ffffe8c 3ffe90e5 4022f3f6
3ffffe60:  3ffffe80 00000001 3ffefa4c 40205e9c  
3ffffe70:  00000001 00000001 3ffefa4c 40209915
3ffffe80:  00000000 00000000 00000000 3fff43e8  
3ffffe90:  00000001 00000001 00000020 401009b7
3ffffea0:  3fff3d4c 3fffff00 3ffffee0 40205e9c  
3ffffeb0:  00000001 00000001 3fff3c54 4021837a
3ffffec0:  3fffff00 3ffef94c 3fff3c54 401000e1
3ffffed0:  3fff3c54 3ffef94c 3fff3c54 40205ed8
3ffffee0:  3fff3d00 0015001f 8015001f 80fe8614
3ffffef0:  3fff3c54 3ffef94c 3ffef90c 40208526  
3fffff00:  3fff3d4c 0015001f 00c6a700 00000000  
3fffff10:  807a1200 3fff4400 0000005f 80007641
3fffff20:  3ffef94c 00000001 402183ac 00000001
3fffff30:  00000001 00000000 00001388 4020bb3e
3fffff40:  00000000 3fff43a4 3ffef90c 3ffefac8  
3fffff50:  00000001 3ffef930 3ffef90c 402093ec
3fffff60:  40218d50 00000000 00001388 4020ca74  
3fffff70:  00000000 3fff43a4 3ffe8a37 4020cd39
3fffff80:  3fffdad0 00000000 3ffefa88 402094b0  
3fffff90:  3fffdad0 00000000 3ffefa88 4020a140
3fffffa0:  feefeffe feefeffe 3ffefa88 4020e454  
3fffffb0:  feefeffe feefeffe 3ffe8614 40100cb9
<<<stack<<<

 ets Jan  8 2013,rst cause:1, boot mode:(3,7)

load 0x4010f000, len 3456, room 16
tail 0
chksum 0x84
csum 0x84
va5432625
~ld

這是導致問題的function():

void CWebServer::getAvailableNetworks()
{

    Serial.println("Get network scan result.");
    bool statusSend = false;
    try
    {
        
        std::string output = "{\"networks\":";
        std::vector<sWiFi_Data*> data = CWiFiConnection::getAvailableNetworks();

        if(data.size() <= 0)
        {
            output += "{}";
        }
        
        for(std::vector<sWiFi_Data*>::iterator it = data.begin(); it != data.end(); ++it)
        {

            // This line is for testing. Later on the JSON output will be calculated here from the Vector.
            Serial.println(((*it)->SSID).c_str());

        }
        output += "}";

        statusSend = true;
        server.send(200, "application/json", output.c_str());

    } catch(ScanException& e)
    {
        statusSend = true;
        server.send(425);
    } catch(std::exception e)
    {
        statusSend = true;
        server.send(500);
        Serial.println();
        Serial.println("Unknown Exception while getting the network data:");
        Serial.println(e.what());
        Serial.println();
    }

    if(!statusSend) server.send(500);

}

這個 function 應該將網絡掃描的結果發送到客戶端。 網絡掃描只需調用 function WiFi.scanNetworks(true, true); 這是 ESP8266WiFi 的一部分。 問題是由 Serial.println(((*it)->SSID).c_str()); 行引起的一旦程序到達這一點,錯誤就會出現並且程序崩潰。 如果我只是刪除這條線並且根本不接觸矢量,那么一切都運行良好。 所以我假設向量迭代器是這里的壞人。

只是為了完整性:如您所見,向量存儲指向“sWiFi_Data”類型結構的指針。 此結構在另一個 class(處理 WiFi 連接的 class)中定義,它看起來像這樣:

struct sWiFi_Data
{
    std::string SSID;
    std::string BSSID;
    int32_t RSSI;
    uint8_t channel;
    uint8_t encryptionType;
    bool isHidden;
};

正如您可能已經注意到,在 CWebServer::getAvailableNetworks() function 內部,該向量是另一個 function (CWiFiConnection::getAvailableNetworks(); ) 的結果。 這個 function 在 CWiFiConnection class 內部。 它看起來像這樣:

std::vector<sWiFi_Data*> CWiFiConnection::getAvailableNetworks()
{

    std::vector<sWiFi_Data*> data;
    int8_t n = WiFi.scanComplete();

    if(n == -1) throw ScanException("Warning: Trying to access network scan data while scan is not completed yet.");
    if(n == -2) throw ScanException("Warning: Trying to access network scan, but scan was never triggered.");
    if(n >= 0)
    {
        
        for(int i = 0; i < n; i++)
        {

            uint8_t encrytptionType = 0;
            switch(WiFi.encryptionType(i)) {
            case ENC_TYPE_NONE:
                encrytptionType = 1;    // None, Open Network
            case ENC_TYPE_WEP:
                encrytptionType = 2;    // WEP
            case ENC_TYPE_TKIP:
                encrytptionType = 3;    // WPA
            case ENC_TYPE_CCMP:
                encrytptionType = 4;    // WPA 2
            case ENC_TYPE_AUTO:
                encrytptionType = 5;    // Auto
            default:
                encrytptionType = 0;    // Unknown
            }

            sWiFi_Data wifiData;
            wifiData.SSID = WiFi.SSID(i).c_str();
            wifiData.BSSID = WiFi.BSSIDstr(i).c_str();
            wifiData.RSSI = WiFi.RSSI(i);
            wifiData.channel = WiFi.channel(i);
            wifiData.encryptionType = encrytptionType;
            wifiData.isHidden = WiFi.isHidden(i);

            data.push_back(&wifiData);

        }

        WiFi.scanDelete();

        return data;

    } else
    {
        throw ScanException("Warning: No networks found.");
    }
    
}

順便說一句:ScanException 只是我寫的一個通用異常。 沒什么特別的,所以我認為我不需要在此處包含代碼。

只是為了澄清一下,通信過程如下所示:

  1. 客戶端發送請求以掃描網絡。
  2. 服務器只調用方法: WiFi.scanNetworks(true, true); (參數:bool async,bool showHidden)
  3. 因為掃描是異步的,所以客戶端通過向服務器發送請求來檢查結果。
  4. 服務器總是通過調用 CWebServer::getAvailableNetworks() function(我們的問題函數)來響應這些請求。
  5. 理論上,如果結果還沒有,這個 function 應該用代碼 425(“尚未准備好”)回復,如果掃描完成,應該將所有可用網絡的數據作為 JSON 發送(這將在行Serial.println(((*it)->SSID).c_str()); 目前是。

順便說一句:我還嘗試在控制台內僅使用 output 向量的大小。 這工作正常。 所以向量內肯定有值。

希望任何人都可以在這里幫助我。 非常感謝。

  • 詹尼斯

ps.:可以在此處找到包含 ESP8266 網絡掃描示例的文檔: https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/scan-examples.html

這一行: data.push_back(&wifiData); 存儲臨時 object wifiData的地址,一旦 scope(即封閉的 for 循環迭代)退出,它將被銷毀。

當您稍后訪問這些地址中的任何一個時,它(可能)會導致段錯誤(如果您幸運的話)。

與其使用std::vector<sWiFi_Data*>不如使用std::vector<sWiFi_Data>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM