Merge pull request #12433 from kjbracey-arm/chrono_esp

ESP8266: Convert to Chrono
pull/12971/head
Martin Kojtal 2020-05-13 19:43:42 +02:00 committed by GitHub
commit b53dc6695b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 49 deletions

View File

@ -40,6 +40,8 @@
using namespace mbed;
using namespace std::chrono;
using std::milli;
ESP8266::ESP8266(PinName tx, PinName rx, bool debug, PinName rts, PinName cts)
: _sdk_v(-1, -1, -1),
@ -275,12 +277,12 @@ bool ESP8266::startup(int mode)
bool ESP8266::reset(void)
{
static const int ESP8266_BOOTTIME = 10000; // [ms]
static const auto ESP8266_BOOTTIME = 10s;
bool done = false;
_smutex.lock();
unsigned long int start_time = rtos::Kernel::get_ms_count();
auto start_time = rtos::Kernel::Clock::now();
_reset_done = false;
set_timeout(ESP8266_RECV_TIMEOUT);
for (int i = 0; i < 2; i++) {
@ -291,10 +293,10 @@ bool ESP8266::reset(void)
while (!_reset_done) {
_process_oob(ESP8266_RECV_TIMEOUT, true); // UART mutex claimed -> need to check for OOBs ourselves
if (_reset_done || (rtos::Kernel::get_ms_count() - start_time >= ESP8266_BOOTTIME)) {
if (_reset_done || rtos::Kernel::Clock::now() - start_time >= ESP8266_BOOTTIME) {
break;
}
rtos::ThisThread::sleep_for(100);
rtos::ThisThread::sleep_for(100ms);
}
done = _reset_done;
@ -520,12 +522,12 @@ int8_t ESP8266::rssi()
return rssi;
}
int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned t_max, unsigned t_min)
int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, duration<unsigned, milli> t_max, duration<unsigned, milli> t_min)
{
_smutex.lock();
// Default timeout plus time spend scanning each channel
set_timeout(ESP8266_MISC_TIMEOUT + 13 * (t_max ? t_max : ESP8266_SCAN_TIME_MAX_DEFAULT));
set_timeout(ESP8266_MISC_TIMEOUT + 13 * (t_max != t_max.zero() ? t_max : duration<unsigned, milli>(ESP8266_SCAN_TIME_MAX_DEFAULT)));
_scan_r.res = res;
_scan_r.limit = limit;
@ -534,7 +536,7 @@ int ESP8266::scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned
bool ret_parse_send = true;
if (FW_AT_LEAST_VERSION(_at_v.major, _at_v.minor, _at_v.patch, 0, ESP8266_AT_VERSION_WIFI_SCAN_CHANGE)) {
ret_parse_send = _parser.send("AT+CWLAP=,,,%u,%u,%u", (mode == SCANMODE_ACTIVE ? 0 : 1), t_min, t_max);
ret_parse_send = _parser.send("AT+CWLAP=,,,%u,%u,%u", (mode == SCANMODE_ACTIVE ? 0 : 1), t_min.count(), t_max.count());
} else {
ret_parse_send = _parser.send("AT+CWLAP");
}
@ -870,7 +872,7 @@ void ESP8266::_oob_packet_hdlr()
_packets_end = &packet->next;
}
void ESP8266::_process_oob(uint32_t timeout, bool all)
void ESP8266::_process_oob(duration<uint32_t, milli> timeout, bool all)
{
set_timeout(timeout);
// Poll for inbound packets
@ -879,14 +881,14 @@ void ESP8266::_process_oob(uint32_t timeout, bool all)
set_timeout();
}
void ESP8266::bg_process_oob(uint32_t timeout, bool all)
void ESP8266::bg_process_oob(duration<uint32_t, milli> timeout, bool all)
{
_smutex.lock();
_process_oob(timeout, all);
_smutex.unlock();
}
int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t timeout)
int32_t ESP8266::_recv_tcp_passive(int id, void *data, uint32_t amount, duration<uint32_t, milli> timeout)
{
int32_t ret = NSAPI_ERROR_WOULD_BLOCK;
@ -949,7 +951,7 @@ BUSY:
return ret;
}
int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, duration<uint32_t, milli> timeout)
{
if (_tcp_passive) {
return _recv_tcp_passive(id, data, amount, timeout);
@ -1007,7 +1009,7 @@ int32_t ESP8266::recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout)
return NSAPI_ERROR_WOULD_BLOCK;
}
int32_t ESP8266::recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout)
int32_t ESP8266::recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, duration<uint32_t, milli> timeout)
{
_smutex.lock();
set_timeout(timeout);
@ -1125,9 +1127,9 @@ bool ESP8266::close(int id)
return false;
}
void ESP8266::set_timeout(uint32_t timeout_ms)
void ESP8266::set_timeout(duration<uint32_t, milli> timeout)
{
_parser.set_timeout(timeout_ms);
_parser.set_timeout(timeout.count());
}
bool ESP8266::readable()
@ -1198,7 +1200,7 @@ bool ESP8266::get_sntp_time(std::tm *t)
memset(buf, 0, 25);
bool done = _parser.send("AT+CIPSNTPTIME?")
&& _parser.scanf("+CIPSNTPTIME:%24c", &buf)
&& _parser.scanf("+CIPSNTPTIME:%24c", buf)
&& _parser.recv("OK\n");
_smutex.unlock();

View File

@ -28,32 +28,35 @@
#include "PinNames.h"
#include "platform/ATCmdParser.h"
#include "platform/Callback.h"
#include "platform/mbed_chrono.h"
#include "platform/mbed_error.h"
#include "rtos/Mutex.h"
#include "rtos/ThisThread.h"
#include "features/netsocket/SocketAddress.h"
// Various timeouts for different ESP8266 operations
// (some of these can't use literal form as they're needed for defaults in this header, where
// we shouldn't add a using directive for them. Defines only used in the C++ file can use literals).
#ifndef ESP8266_CONNECT_TIMEOUT
#define ESP8266_CONNECT_TIMEOUT 15000
#define ESP8266_CONNECT_TIMEOUT 15s
#endif
#ifndef ESP8266_SEND_TIMEOUT
#define ESP8266_SEND_TIMEOUT 2000
#define ESP8266_SEND_TIMEOUT 2s
#endif
#ifndef ESP8266_RECV_TIMEOUT
#define ESP8266_RECV_TIMEOUT 2000
#define ESP8266_RECV_TIMEOUT std::chrono::seconds(2)
#endif
#ifndef ESP8266_MISC_TIMEOUT
#define ESP8266_MISC_TIMEOUT 2000
#define ESP8266_MISC_TIMEOUT std::chrono::seconds(2)
#endif
#ifndef ESP8266_DNS_TIMEOUT
#define ESP8266_DNS_TIMEOUT 15000
#define ESP8266_DNS_TIMEOUT 15s
#endif
#define ESP8266_SCAN_TIME_MIN 0 // [ms]
#define ESP8266_SCAN_TIME_MAX 1500 // [ms]
#define ESP8266_SCAN_TIME_MIN_DEFAULT 120 // [ms]
#define ESP8266_SCAN_TIME_MAX_DEFAULT 360 // [ms]
#define ESP8266_SCAN_TIME_MIN 0ms
#define ESP8266_SCAN_TIME_MAX 1500ms
#define ESP8266_SCAN_TIME_MIN_DEFAULT 120ms
#define ESP8266_SCAN_TIME_MAX_DEFAULT 360ms
// Firmware version
#define ESP8266_SDK_VERSION 2000000
@ -248,7 +251,9 @@ public:
* @return Number of entries in @a res, or if @a count was 0 number of available networks, negative on error
* see @a nsapi_error
*/
int scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned t_max, unsigned t_min);
int scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode,
std::chrono::duration<unsigned, std::milli> t_max,
std::chrono::duration<unsigned, std::milli> t_min);
/**Perform a dns query
*
@ -303,7 +308,7 @@ public:
* @param amount number of bytes to be received
* @return the number of bytes received
*/
int32_t recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
int32_t recv_udp(struct esp8266_socket *socket, void *data, uint32_t amount, mbed::chrono::milliseconds_u32 timeout = ESP8266_RECV_TIMEOUT);
/**
* Receives stream data from an open TCP socket
@ -313,7 +318,7 @@ public:
* @param amount number of bytes to be received
* @return the number of bytes received
*/
int32_t recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
int32_t recv_tcp(int id, void *data, uint32_t amount, mbed::chrono::milliseconds_u32 timeout = ESP8266_RECV_TIMEOUT);
/**
* Closes a socket
@ -328,7 +333,7 @@ public:
*
* @param timeout_ms timeout of the connection
*/
void set_timeout(uint32_t timeout_ms = ESP8266_MISC_TIMEOUT);
void set_timeout(mbed::chrono::milliseconds_u32 timeout = ESP8266_MISC_TIMEOUT);
/**
* Checks if data is available
@ -465,7 +470,7 @@ public:
* @param timeout AT parser receive timeout
* @param if TRUE, process all OOBs instead of only one
*/
void bg_process_oob(uint32_t timeout, bool all);
void bg_process_oob(std::chrono::duration<uint32_t, std::milli> timeout, bool all);
/**
* Flush the serial port input buffers.
@ -496,7 +501,7 @@ private:
// FW version specific settings and functionalities
bool _tcp_passive;
int32_t _recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t timeout);
int32_t _recv_tcp_passive(int id, void *data, uint32_t amount, std::chrono::duration<uint32_t, std::milli> timeout);
mbed::Callback<void()> _callback;
// UART settings
@ -529,7 +534,7 @@ private:
size_t _heap_usage; // (Socket data buffer usage)
// OOB processing
void _process_oob(uint32_t timeout, bool all);
void _process_oob(std::chrono::duration<uint32_t, std::milli> timeout, bool all);
// OOB message handlers
void _oob_packet_hdlr();

View File

@ -31,6 +31,8 @@
#include "platform/mbed_debug.h"
#include "rtos/ThisThread.h"
using namespace std::chrono;
#ifndef MBED_CONF_ESP8266_DEBUG
#define MBED_CONF_ESP8266_DEBUG false
#endif
@ -197,7 +199,7 @@ void ESP8266Interface::PowerPin::power_on()
if (_pwr_pin.is_connected()) {
_pwr_pin = MBED_CONF_ESP8266_POWER_ON_POLARITY;
tr_debug("power_on(): HW power-on.");
ThisThread::sleep_for(MBED_CONF_ESP8266_POWER_ON_TIME_MS);
ThisThread::sleep_for(milliseconds(MBED_CONF_ESP8266_POWER_ON_TIME_MS));
}
}
@ -206,7 +208,7 @@ void ESP8266Interface::PowerPin::power_off()
if (_pwr_pin.is_connected()) {
_pwr_pin = !MBED_CONF_ESP8266_POWER_ON_POLARITY;
tr_debug("power_off(): HW power-off.");
ThisThread::sleep_for(MBED_CONF_ESP8266_POWER_OFF_TIME_MS);
ThisThread::sleep_for(milliseconds(MBED_CONF_ESP8266_POWER_OFF_TIME_MS));
}
}
@ -261,14 +263,14 @@ void ESP8266Interface::_connect_async()
return;
}
_connect_retval = _esp.connect(ap_ssid, ap_pass);
int timeleft_ms = ESP8266_INTERFACE_CONNECT_TIMEOUT_MS - _conn_timer.read_ms();
auto timepassed = _conn_timer.elapsed_time();
if (_connect_retval == NSAPI_ERROR_OK
|| _connect_retval == NSAPI_ERROR_AUTH_FAILURE
|| _connect_retval == NSAPI_ERROR_NO_SSID
|| ((_if_blocking == true) && (timeleft_ms <= 0))) {
|| ((_if_blocking == true) && (timepassed >= ESP8266_INTERFACE_CONNECT_TIMEOUT))) {
_connect_event_id = 0;
_conn_timer.stop();
if (timeleft_ms <= 0 && _connect_retval != NSAPI_ERROR_OK) {
if (timepassed >= ESP8266_INTERFACE_CONNECT_TIMEOUT && _connect_retval != NSAPI_ERROR_OK) {
_connect_retval = NSAPI_ERROR_CONNECTION_TIMEOUT;
}
if (_connect_retval != NSAPI_ERROR_OK) {
@ -280,7 +282,7 @@ void ESP8266Interface::_connect_async()
#endif
} else {
// Postpone to give other stuff time to run
_connect_event_id = _global_event_queue->call_in(ESP8266_INTERFACE_CONNECT_INTERVAL_MS,
_connect_event_id = _global_event_queue->call_in(ESP8266_INTERFACE_CONNECT_INTERVAL,
callback(this, &ESP8266Interface::_connect_async));
if (!_connect_event_id) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
@ -442,11 +444,11 @@ void ESP8266Interface::_disconnect_async()
{
_cmutex.lock();
_disconnect_retval = _esp.disconnect() ? NSAPI_ERROR_OK : NSAPI_ERROR_DEVICE_ERROR;
int timeleft_ms = ESP8266_INTERFACE_CONNECT_TIMEOUT_MS - _conn_timer.read_ms();
auto timepassed = _conn_timer.elapsed_time();
if (_disconnect_retval == NSAPI_ERROR_OK || ((_if_blocking == true) && (timeleft_ms <= 0))) {
if (_disconnect_retval == NSAPI_ERROR_OK || ((_if_blocking == true) && (timepassed >= ESP8266_INTERFACE_CONNECT_TIMEOUT))) {
if (timeleft_ms <= 0 && _connect_retval != NSAPI_ERROR_OK) {
if (timepassed >= ESP8266_INTERFACE_CONNECT_TIMEOUT && _connect_retval != NSAPI_ERROR_OK) {
_disconnect_retval = NSAPI_ERROR_CONNECTION_TIMEOUT;
} else {
if (_conn_stat != NSAPI_STATUS_DISCONNECTED) {
@ -467,7 +469,7 @@ void ESP8266Interface::_disconnect_async()
} else {
// Postpone to give other stuff time to run
_disconnect_event_id = _global_event_queue->call_in(
ESP8266_INTERFACE_CONNECT_INTERVAL_MS,
ESP8266_INTERFACE_CONNECT_INTERVAL,
callback(this, &ESP8266Interface::_disconnect_async));
if (!_disconnect_event_id) {
MBED_ERROR(
@ -643,10 +645,10 @@ int8_t ESP8266Interface::get_rssi()
int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count)
{
return scan(res, count, SCANMODE_ACTIVE, 0, 0);
return scan(res, count, SCANMODE_ACTIVE);
}
int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count, scan_mode mode, unsigned t_max, unsigned t_min)
int ESP8266Interface::scan(WiFiAccessPoint *res, unsigned count, scan_mode mode, mbed::chrono::milliseconds_u32 t_max, mbed::chrono::milliseconds_u32 t_min)
{
if (t_max > ESP8266_SCAN_TIME_MAX) {
return NSAPI_ERROR_PARAMETER;
@ -766,7 +768,15 @@ nsapi_error_t ESP8266Interface::_reset()
_rst_pin.rst_assert();
// If you happen to use Pin7 CH_EN as reset pin, not needed otherwise
// https://www.espressif.com/sites/default/files/documentation/esp8266_hardware_design_guidelines_en.pdf
ThisThread::sleep_for(2); // Documentation says 200 us; need 2 ticks to get minimum 1 ms.
// First need to round up when converting to kernel ticks (eg 200us -> 1ms).
auto delay = duration_cast<Kernel::Clock::duration_u32>(200us);
if (delay < 200us) {
delay++;
}
// Then need to round the clock-resolution duration up; if we were at the end of a tick
// period, it might flip immediately.
delay++;
ThisThread::sleep_for(delay);
_esp.flush();
_rst_pin.rst_deassert();
} else {
@ -929,7 +939,7 @@ int ESP8266Interface::socket_send(void *handle, const void *data, unsigned size)
&& socket->proto == NSAPI_TCP
&& core_util_atomic_cas_u8(&_cbs[socket->id].deferred, &expect_false, true)) {
tr_debug("socket_send(...): Postponing SIGIO from the device.");
if (!_global_event_queue->call_in(50, callback(this, &ESP8266Interface::event_deferred))) {
if (!_global_event_queue->call_in(50ms, callback(this, &ESP8266Interface::event_deferred))) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
"socket_send(): unable to add event to queue. Increase \"events.shared-eventsize\"\n");
}
@ -1086,7 +1096,7 @@ void ESP8266Interface::event()
{
if (!_oob_event_id) {
// Throttles event creation by using arbitrary small delay
_oob_event_id = _global_event_queue->call_in(50, callback(this, &ESP8266Interface::proc_oob_evnt));
_oob_event_id = _global_event_queue->call_in(50ms, callback(this, &ESP8266Interface::proc_oob_evnt));
if (!_oob_event_id) {
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_DRIVER, MBED_ERROR_CODE_ENOMEM), \
"ESP8266Interface::event(): unable to add event to queue. Increase \"events.shared-eventsize\"\n");

View File

@ -31,6 +31,7 @@
#include "features/netsocket/WiFiAccessPoint.h"
#include "features/netsocket/WiFiInterface.h"
#include "platform/Callback.h"
#include "platform/mbed_chrono.h"
#if MBED_CONF_RTOS_PRESENT
#include "rtos/ConditionVariable.h"
#endif
@ -38,8 +39,8 @@
#define ESP8266_SOCKET_COUNT 5
#define ESP8266_INTERFACE_CONNECT_INTERVAL_MS (5000)
#define ESP8266_INTERFACE_CONNECT_TIMEOUT_MS (2 * ESP8266_CONNECT_TIMEOUT + ESP8266_INTERFACE_CONNECT_INTERVAL_MS)
#define ESP8266_INTERFACE_CONNECT_INTERVAL 5s
#define ESP8266_INTERFACE_CONNECT_TIMEOUT (2 * ESP8266_CONNECT_TIMEOUT + ESP8266_INTERFACE_CONNECT_INTERVAL)
#ifdef TARGET_FF_ARDUINO
#ifndef MBED_CONF_ESP8266_TX
@ -225,7 +226,8 @@ public:
* see @a nsapi_error
*/
virtual int scan(WiFiAccessPoint *res, unsigned count, scan_mode mode = SCANMODE_PASSIVE,
unsigned t_max = 0, unsigned t_min = 0);
mbed::chrono::milliseconds_u32 t_max = mbed::chrono::milliseconds_u32(0),
mbed::chrono::milliseconds_u32 t_min = mbed::chrono::milliseconds_u32(0));
/** Translates a hostname to an IP address with specific version
*