Arduino ESP8266 WiFiUDP发送数据包导致挂起然后崩溃
我正在构建一个C#windows窗体程序,该程序将与ESP8266进行通信。我希望不必发布太多的代码,因为这两个程序都相当大。我会尽力解释我的问题 C#程序在连接到ESP8266软接入点时通过UDP广播发送数据包。ESP8266可以从C#表单接收和解析数据包。问题是我试图立即将响应包发送回C#表单。这就是问题所在。在调用“write()”或“endPacket()”时,ESP8266将被挂起/冻结一段时间,然后它将崩溃。有时“endPacket()”实际上不会挂起/冻结并发回响应数据包,但它仍然会立即崩溃 大多数情况下,错误输出似乎是:“ets 2013年1月8日,rst原因:4,启动模式:(3,6)”。但有时情况不同 我在代码中也尝试过使用“yield()”函数,但没有成功 欢迎提供任何指导或解决方案 ESP8266程序:有问题的主要代码: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()”实际上不会挂起/冻结并发回响应数据包,但它仍然
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库: