mirror of https://github.com/ARMmbed/mbed-os.git
ESP8266: handles reset ready as OOB
Makes possible to recover from spurious resets addiotionally to planned ones.pull/9473/head
parent
f2abdcbcc6
commit
876a397101
|
|
@ -25,6 +25,7 @@
|
||||||
#include "PinNames.h"
|
#include "PinNames.h"
|
||||||
#include "platform/Callback.h"
|
#include "platform/Callback.h"
|
||||||
#include "platform/mbed_error.h"
|
#include "platform/mbed_error.h"
|
||||||
|
#include "rtos/Kernel.h"
|
||||||
|
|
||||||
#define TRACE_GROUP "ESPA" // ESP8266 AT layer
|
#define TRACE_GROUP "ESPA" // ESP8266 AT layer
|
||||||
|
|
||||||
|
|
@ -51,6 +52,8 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
|
||||||
_sock_already(false),
|
_sock_already(false),
|
||||||
_closed(false),
|
_closed(false),
|
||||||
_busy(false),
|
_busy(false),
|
||||||
|
_reset_check(_rmutex),
|
||||||
|
_reset_done(false),
|
||||||
_conn_status(NSAPI_STATUS_DISCONNECTED)
|
_conn_status(NSAPI_STATUS_DISCONNECTED)
|
||||||
{
|
{
|
||||||
_serial.set_baud(ESP8266_DEFAULT_BAUD_RATE);
|
_serial.set_baud(ESP8266_DEFAULT_BAUD_RATE);
|
||||||
|
|
@ -71,6 +74,7 @@ ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
|
||||||
_parser.oob("UNLINK", callback(this, &ESP8266::_oob_socket_close_err));
|
_parser.oob("UNLINK", callback(this, &ESP8266::_oob_socket_close_err));
|
||||||
_parser.oob("ALREADY CONNECTED", callback(this, &ESP8266::_oob_conn_already));
|
_parser.oob("ALREADY CONNECTED", callback(this, &ESP8266::_oob_conn_already));
|
||||||
_parser.oob("ERROR", callback(this, &ESP8266::_oob_err));
|
_parser.oob("ERROR", callback(this, &ESP8266::_oob_err));
|
||||||
|
_parser.oob("ready", callback(this, &ESP8266::_oob_reset));
|
||||||
// Don't expect to find anything about the watchdog reset in official documentation
|
// Don't expect to find anything about the watchdog reset in official documentation
|
||||||
//https://techtutorialsx.com/2017/01/21/esp8266-watchdog-functions/
|
//https://techtutorialsx.com/2017/01/21/esp8266-watchdog-functions/
|
||||||
_parser.oob("wdt reset", callback(this, &ESP8266::_oob_watchdog_reset));
|
_parser.oob("wdt reset", callback(this, &ESP8266::_oob_watchdog_reset));
|
||||||
|
|
@ -234,20 +238,31 @@ bool ESP8266::startup(int mode)
|
||||||
|
|
||||||
bool ESP8266::reset(void)
|
bool ESP8266::reset(void)
|
||||||
{
|
{
|
||||||
|
static const int ESP8266_BOOTTIME = 10000; // [ms]
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
_smutex.lock();
|
_smutex.lock();
|
||||||
set_timeout(ESP8266_CONNECT_TIMEOUT);
|
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
unsigned long int start_time = rtos::Kernel::get_ms_count();
|
||||||
if (_parser.send("AT+RST")
|
_reset_done = false;
|
||||||
&& _parser.recv("OK\n")
|
set_timeout(ESP8266_RECV_TIMEOUT);
|
||||||
&& _parser.recv("ready")) {
|
if (!_parser.send("AT+RST") || !_parser.recv("OK\n")) {
|
||||||
done = true;
|
tr_debug("reset(): AT+RST failed or no response");
|
||||||
break;
|
goto EXIT;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_rmutex.lock();
|
||||||
|
while ((rtos::Kernel::get_ms_count() - start_time < ESP8266_BOOTTIME) && !_reset_done) {
|
||||||
|
_process_oob(ESP8266_RECV_TIMEOUT, true); // UART mutex claimed -> need to check for OOBs ourselves
|
||||||
|
_reset_check.wait_for(100); // Arbitrary relatively short delay
|
||||||
|
}
|
||||||
|
|
||||||
|
done = _reset_done;
|
||||||
|
_rmutex.unlock();
|
||||||
|
|
||||||
|
tr_debug("reset(): done: %s", done ? "OK" : "FAIL");
|
||||||
|
|
||||||
|
EXIT:
|
||||||
_clear_socket_packets(ESP8266_ALL_SOCKET_IDS);
|
_clear_socket_packets(ESP8266_ALL_SOCKET_IDS);
|
||||||
set_timeout();
|
set_timeout();
|
||||||
_smutex.unlock();
|
_smutex.unlock();
|
||||||
|
|
@ -963,6 +978,25 @@ void ESP8266::_oob_watchdog_reset()
|
||||||
"_oob_watchdog_reset() modem watchdog reset triggered\n");
|
"_oob_watchdog_reset() modem watchdog reset triggered\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ESP8266::_oob_reset()
|
||||||
|
{
|
||||||
|
|
||||||
|
_rmutex.lock();
|
||||||
|
_reset_done = true;
|
||||||
|
_reset_check.notify_all();
|
||||||
|
_rmutex.unlock();
|
||||||
|
|
||||||
|
for (int i = 0; i < SOCKET_COUNT; i++) {
|
||||||
|
_sock_i[i].open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Makes possible to reinitialize
|
||||||
|
_conn_status = NSAPI_STATUS_ERROR_UNSUPPORTED;
|
||||||
|
_conn_stat_cb();
|
||||||
|
|
||||||
|
tr_debug("_oob_reset(): reset detected");
|
||||||
|
}
|
||||||
|
|
||||||
void ESP8266::_oob_busy()
|
void ESP8266::_oob_busy()
|
||||||
{
|
{
|
||||||
char status[5];
|
char status[5];
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
#include "platform/ATCmdParser.h"
|
#include "platform/ATCmdParser.h"
|
||||||
#include "platform/Callback.h"
|
#include "platform/Callback.h"
|
||||||
#include "platform/mbed_error.h"
|
#include "platform/mbed_error.h"
|
||||||
|
#include "rtos/ConditionVariable.h"
|
||||||
#include "rtos/Mutex.h"
|
#include "rtos/Mutex.h"
|
||||||
|
|
||||||
// Various timeouts for different ESP8266 operations
|
// Various timeouts for different ESP8266 operations
|
||||||
|
|
@ -396,6 +397,7 @@ private:
|
||||||
PinName _serial_rts;
|
PinName _serial_rts;
|
||||||
PinName _serial_cts;
|
PinName _serial_cts;
|
||||||
rtos::Mutex _smutex; // Protect serial port access
|
rtos::Mutex _smutex; // Protect serial port access
|
||||||
|
rtos::Mutex _rmutex; // Reset protection
|
||||||
|
|
||||||
// AT Command Parser
|
// AT Command Parser
|
||||||
mbed::ATCmdParser _parser;
|
mbed::ATCmdParser _parser;
|
||||||
|
|
@ -435,6 +437,7 @@ private:
|
||||||
void _oob_watchdog_reset();
|
void _oob_watchdog_reset();
|
||||||
void _oob_busy();
|
void _oob_busy();
|
||||||
void _oob_tcp_data_hdlr();
|
void _oob_tcp_data_hdlr();
|
||||||
|
void _oob_reset();
|
||||||
|
|
||||||
// OOB state variables
|
// OOB state variables
|
||||||
int _connect_error;
|
int _connect_error;
|
||||||
|
|
@ -444,6 +447,8 @@ private:
|
||||||
bool _closed;
|
bool _closed;
|
||||||
bool _error;
|
bool _error;
|
||||||
bool _busy;
|
bool _busy;
|
||||||
|
rtos::ConditionVariable _reset_check;
|
||||||
|
bool _reset_done;
|
||||||
|
|
||||||
// Modem's address info
|
// Modem's address info
|
||||||
char _ip_buffer[16];
|
char _ip_buffer[16];
|
||||||
|
|
|
||||||
|
|
@ -577,6 +577,10 @@ int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
|
||||||
return NSAPI_ERROR_NO_SOCKET;
|
return NSAPI_ERROR_NO_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_sock_i[socket->id].open) {
|
||||||
|
return NSAPI_ERROR_CONNECTION_LOST;
|
||||||
|
}
|
||||||
|
|
||||||
if (!size) {
|
if (!size) {
|
||||||
// Firmware limitation
|
// Firmware limitation
|
||||||
return socket->proto == NSAPI_TCP ? 0 : NSAPI_ERROR_UNSUPPORTED;
|
return socket->proto == NSAPI_TCP ? 0 : NSAPI_ERROR_UNSUPPORTED;
|
||||||
|
|
@ -604,6 +608,10 @@ int ESP8266Interface::socket_recv(void *handle, void *data, unsigned size)
|
||||||
return NSAPI_ERROR_NO_SOCKET;
|
return NSAPI_ERROR_NO_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!_sock_i[socket->id].open) {
|
||||||
|
return NSAPI_ERROR_CONNECTION_LOST;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t recv;
|
int32_t recv;
|
||||||
if (socket->proto == NSAPI_TCP) {
|
if (socket->proto == NSAPI_TCP) {
|
||||||
recv = _esp.recv_tcp(socket->id, data, size);
|
recv = _esp.recv_tcp(socket->id, data, size);
|
||||||
|
|
@ -791,6 +799,10 @@ void ESP8266Interface::update_conn_state_cb()
|
||||||
default:
|
default:
|
||||||
_initialized = false;
|
_initialized = false;
|
||||||
_conn_stat = NSAPI_STATUS_DISCONNECTED;
|
_conn_stat = NSAPI_STATUS_DISCONNECTED;
|
||||||
|
for (int i = 0; i < ESP8266_SOCKET_COUNT; i++) {
|
||||||
|
_sock_i[i].open = false;
|
||||||
|
_sock_i[i].sport = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inform upper layers
|
// Inform upper layers
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue