Arduino ESP8266 WiFiUDP发送数据包导致挂起然后崩溃

Arduino ESP8266 WiFiUDP发送数据包导致挂起然后崩溃,arduino,crash,udp,esp8266,arduino-esp8266,Arduino,Crash,Udp,Esp8266,Arduino Esp8266,我正在构建一个C#windows窗体程序,该程序将与ESP8266进行通信。我希望不必发布太多的代码,因为这两个程序都相当大。我会尽力解释我的问题 C#程序在连接到ESP8266软接入点时通过UDP广播发送数据包。ESP8266可以从C#表单接收和解析数据包。问题是我试图立即将响应包发送回C#表单。这就是问题所在。在调用“write()”或“endPacket()”时,ESP8266将被挂起/冻结一段时间,然后它将崩溃。有时“endPacket()”实际上不会挂起/冻结并发回响应数据包,但它仍然

我正在构建一个C#windows窗体程序,该程序将与ESP8266进行通信。我希望不必发布太多的代码,因为这两个程序都相当大。我会尽力解释我的问题

C#程序在连接到ESP8266软接入点时通过UDP广播发送数据包。ESP8266可以从C#表单接收和解析数据包。问题是我试图立即将响应包发送回C#表单。这就是问题所在。在调用“write()”或“endPacket()”时,ESP8266将被挂起/冻结一段时间,然后它将崩溃。有时“endPacket()”实际上不会挂起/冻结并发回响应数据包,但它仍然会立即崩溃

大多数情况下,错误输出似乎是:“ets 2013年1月8日,rst原因:4,启动模式:(3,6)”。但有时情况不同

我在代码中也尝试过使用“yield()”函数,但没有成功

欢迎提供任何指导或解决方案

ESP8266程序:有问题的主要代码:

bool BatteryOptimizer::ProcessData()
{
    size_t enc_data_len = 0;
    size_t dec_data_len = 0;
    //int ass_data_size_temp = 0;
    char encrypted_data[BO_UDP_PACKET_SIZE];
    char decrypted_data[BO_UDP_PACKET_SIZE];
    char associated_data_temp[BO_AES_ASSOCIATED_DATA_SIZE];
    uint8_t iv[GCM_AES_256_IV_TAG_SIZE];
    uint8_t tag[GCM_AES_256_IV_TAG_SIZE];
    bool status = false;
    uint8_t msg_type = 0;

    char response_packet[BO_PACKET_SIZE];
    size_t response_packet_size = BO_PACKET_SIZE;

    msg_type = (uint8_t)BatteryOptimizer::collector_manager->fields[1].ui64_field; //Get Msg Type

    //See if Message type is correct first before continuing
    if (msg_type < BO_AES_ASSOCIATED_DATA_SIZE)
    {
        enc_data_len = (size_t)(collector_manager->fields[3].ui64_field - GCM_AES_256_IV_TAG_SIZE); //Get encrypted data length

        memcpy(iv, BatteryOptimizer::collector_manager->fields[2].c_array, GCM_AES_256_IV_TAG_SIZE); //Get IV
        memcpy(encrypted_data, BatteryOptimizer::collector_manager->fields[3].c_array, enc_data_len); //Get encrypted data
        memcpy(tag, BatteryOptimizer::collector_manager->fields[3].c_array + enc_data_len, GCM_AES_256_IV_TAG_SIZE); //Get tag

        //ass_data_size_temp = BatteryOptimizer::associated_data[msg_type].length(); //Get associated data legnth
        BatteryOptimizer::associated_data[msg_type].toCharArray(associated_data_temp, BO_AES_ASSOCIATED_DATA_SIZE); //Get associated data

        //Decrypt data
        Serial.println("ProcessData: Attempting to decrypt data!");
        status = Decrypt_GCM_AES256((uint8_t *)encrypted_data,
                        enc_data_len,
                        iv,
                        tag,
                        associated_data_temp,
                        (uint8_t *)decrypted_data,
                        &dec_data_len);

        if (true == status)
        {
            //Execute command:
            BatteryOptimizer::ExecuteCommand(msg_type, decrypted_data, dec_data_len);

            //Build Reponse packet:
            Serial.println("ProcessData: Attempting to build Reponse packet!");
            memset(response_packet, 0, BO_PACKET_SIZE);
            BatteryOptimizer::BuildResponsePacket(associated_data_temp, response_packet, &response_packet_size);

            //Send Response packet:
            Serial.println("ProcessData: Attempting to begin packet!");
            Serial.println("ProcessData: Remote IP: ");
            Serial.println(BatteryOptimizer::udp_server.remoteIP());
            Serial.println("ProcessData: Remote Port: ");
            Serial.println(BatteryOptimizer::udp_server.remotePort());

            status = BatteryOptimizer::udp_server.beginPacket(BatteryOptimizer::udp_server.remoteIP(), BatteryOptimizer::udp_server.remotePort());
            if (true == status)
            {
                Serial.println("ProcessData: Attempting to write packet!");
                Serial.println(BatteryOptimizer::udp_server.write(response_packet, response_packet_size));
                Serial.println("ProcessData: Attempting to send packet!");
                status = BatteryOptimizer::udp_server.endPacket();
                if (true == status)
                {
                    Serial.println("ProcessData: UDP server sent reponse packet!");
                }
                else
                {
                    Serial.println("ProcessData: UDP server was unable to send repsonse packet!");
                    Serial.println("ProcessData: Tried to send response packet: " + BatteryOptimizer::associated_data[msg_type]);
                }
            }
            else
            {
                Serial.println("ProcessData: UDP server was unable to begin packet!");
                Serial.println("ProcessData: Tried to send response packet: " + BatteryOptimizer::associated_data[msg_type]);
            }

        }
        else
        {
            Serial.println("ProcessData: Failed to process data!");
            //Testing
            Serial.println("Encrypted length: ");
            Serial.println(enc_data_len);
            Serial.println("Decrypted Data: ");
            Serial.println(decrypted_data);
            Serial.println(decrypted_data + 50);
            Serial.println("Associated Data: ");
            Serial.println(associated_data_temp);
        }
    }

    return status;
} //END ProcessData

void BatteryOptimizer::UDP_ServerLoop()
{
    char packet[BO_UDP_PACKET_SIZE];
    int packetSize;

    Serial.println("UDP server about to start parsing packets!");
    //while (BatteryOptimizer::run_udp == true)
    if (BatteryOptimizer::run_udp == true)
    {
        packetSize = BatteryOptimizer::udp_server.parsePacket();
        if (packetSize > 0)
        {
            Serial.println("Received packet! Size: ");
            Serial.println(packetSize);

            size_t len = (size_t)BatteryOptimizer::udp_server.read(packet, BO_UDP_PACKET_SIZE);
            if (len > 0)
            {
                BatteryOptimizer::collector_manager->Collect(packet, &len);
                if (COLLECT_FOUND == BatteryOptimizer::collector_manager->status)
                {
                    Serial.println("Found msg!");
                    Serial.println("Collected Packet Size:");
                    Serial.println(BatteryOptimizer::collector_manager->packet_size);

                    BatteryOptimizer::collector_manager->Check_Checksum();
                    if (COLLECT_VALID_CS == BatteryOptimizer::collector_manager->status)
                    {
                        Serial.println("Valid Checksum!");
                        BatteryOptimizer::collector_manager->Parse();
                        //Process data
                        if (true == BatteryOptimizer::ProcessData())
                        {
                            Serial.println("Process success!");
                        }
                    }
                    else
                    {
                        Serial.println("Invalid Checksum!");
                    }
                    BatteryOptimizer::collector_manager->ResetCache();
                }
                else
                {
                    Serial.println("Did not find a message!");
                }
            }
            else
            {
                Serial.println("Did not receive a complete packet!");
            }
        }
        else
        {
            Serial.println("Packet size is 0!");
        }
        Serial.println("Packet received: ");
        Serial.println(packet);
        delay(BO_UDP_DELAY);
    } //END run_udp loop

    Serial.println("UDP server no longer parsing packets! ");
} //END UDP_ServerLoop

void BatteryOptimizer::UDP_StartServer()
{
    if (BatteryOptimizer::is_udp_running == false)
    {
        Serial.println("Starting UDP server. ");
        BatteryOptimizer::udp_server.begin(BO_UDP_PORT);

        Serial.println("Listening on UDP port ");
        Serial.println(BO_UDP_PORT);
        BatteryOptimizer::run_udp = true;
        BatteryOptimizer::is_udp_running = true;
    }

} //END UDP_StartServer


private void UDP_Initialize_Client()
{
    //Start UDP server to listen in for the Battery Opetimizer device:
    udp_client = new UdpClient( listenPort );
    end_point = new IPEndPoint( IPAddress.Broadcast, listenPort );
    udp_client.EnableBroadcast = true;
    udp_client.MulticastLoopback = false;
}

private void UDP_ReceiveContinuously( IAsyncResult res )
{
    byte[] received = udp_client.EndReceive( res, ref end_point );

    //Process Data:
    UDP_ProcessData( ref received );


    UDP_SetupReceive();
} //END UDP_ReceiveContinuously

private void UDP_SetupReceive()
{
    try
    {
        udp_client.BeginReceive( new AsyncCallback( UDP_ReceiveContinuously ), null );
    }
    catch (Exception e)
    {
        MessageBox.Show( e.ToString() );
    }
} //END UDP_SetupReceive

作为更新,我了解了如何使用异常解码器。这是输出

0x40206afe: raise_exception at core_esp8266_postmortem.cpp line ?
0x40206b10: __assert_func at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/core_esp8266_postmortem.cpp line 275
0x40100ba2: get_unpoisoned_check_neighbors at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_local.c line 125
0x402074bd: uart_write at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/uart.cpp line 509
0x40100c91: umm_poison_free_fl at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_local.c line 148
0x40205690: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
0x4010038c: free at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/heap.cpp line 259
0x40205690: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h line 164
0x4020ebe5: operator delete(void*) at /workdir/repo/gcc/libstdc++-v3/libsupc++/del_op.cc line 48
0x4020ebd0: operator delete[](void*) at /workdir/repo/gcc/libstdc++-v3/libsupc++/del_opv.cc line 33
0x40204b40: Collector::FreeUnnecessaryResources() at D:\Projects\Arduino\libraries\DataHandler/DataHandler.cpp line 331 (discriminator 3)
0x40201912: BatteryOptimizer::UDP_OnPacket(AsyncUDPPacket) at C:\Users\SPENCE~1\AppData\Local\Temp\arduino_build_863316\sketch/battery_optimizer.cpp line 312 (discriminator 1)
0x4020105f: BP_OnPacket(AsyncUDPPacket&) at D:\Projects\Arduino\ESP8266\BatteryPerserver/BatteryPerserver.ino line 55
0x40208910: precache at ?? line ?
0x40102b12: wDev_ProcessFiq at ?? line ?
0x402082c0: std::_Function_handler ::_M_invoke(std::_Any_data const&, AsyncUDPPacket&) at c:\users\spencerbell\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\2.5.0-4-b40a506\xtensa-lx106-elf\include\c++\4.8.2/functional line 2073
0x40202da2: AsyncUDP::_recv(udp_pcb*, pbuf*, ip4_addr*, unsigned short) at D:\Projects\Arduino\libraries\ESPAsyncUDP\src/AsyncUDP.cpp line 197
0x40208910: precache at ?? line ?
0x40221f4b: cnx_start_handoff_cb at ?? line ?
0x401009a5: check_poison_neighbors$part$3 at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_local.c line 71
0x40100a61: umm_malloc_core at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_malloc.cpp line 458
0x40101a17: ppCalFrameTimes at ?? line ?
0x40202dd8: AsyncUDP::_s_recv(void*, udp_pcb*, pbuf*, ip4_addr const*, unsigned short) at D:\Projects\Arduino\libraries\ESPAsyncUDP\src/AsyncUDP.cpp line 210
0x4021314c: udp_input at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/lwip2-src/src/core/udp.c line 404
0x4022eb18: pbuf_alloc at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/glue-esp/lwip-esp.c line 669
0x40217cf0: ip4_input at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/lwip2-src/src/core/ipv4/ip4.c line 1461
0x40100c77: umm_free at C:\Users\SpencerBell\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266\umm_malloc/umm_malloc.cpp line 398
0x4020f349: ethernet_input_LWIP2 at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/lwip2-src/src/netif/ethernet.c line 188
0x4020f168: esp2glue_ethernet_input at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/glue-lwip/lwip-git.c line 469
0x4022ebfe: ethernet_input at /local/users/gauchard/arduino/arduino_esp8266/esp8266-lwip/tools/sdk/lwip2/builder/glue-esp/lwip-esp.c line 365

经过数周的搜索和修改代码。我发现我只是用了太多的内存。我在我的代码中找到了几个地方,在那里我减少了数组的大小,现在它工作得很好

作为说明,我还切换到使用ESPAsyncUDP库: