Import Mbed OS hard-float snapshot

This commit is contained in:
Beslan
2026-06-01 20:15:04 +03:00
commit d3738e2f89
16278 changed files with 10628036 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,600 @@
/* ESP8266Interface Example
* Copyright (c) 2015 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ESP8266_H
#define ESP8266_H
#if DEVICE_SERIAL && DEVICE_INTERRUPTIN && defined(MBED_CONF_EVENTS_PRESENT) && defined(MBED_CONF_NSAPI_PRESENT) && defined(MBED_CONF_RTOS_API_PRESENT)
#include <stdint.h>
#include <ctime>
#include "drivers/BufferedSerial.h"
#include "netsocket/nsapi_types.h"
#include "netsocket/WiFiAccessPoint.h"
#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 "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 15s
#endif
#ifndef ESP8266_SEND_TIMEOUT
#define ESP8266_SEND_TIMEOUT 2s
#endif
#ifndef ESP8266_RECV_TIMEOUT
#define ESP8266_RECV_TIMEOUT std::chrono::seconds(2)
#endif
#ifndef ESP8266_MISC_TIMEOUT
#define ESP8266_MISC_TIMEOUT std::chrono::seconds(2)
#endif
#ifndef ESP8266_DNS_TIMEOUT
#define ESP8266_DNS_TIMEOUT 15s
#endif
#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
#define ESP8266_SDK_VERSION_MAJOR ESP8266_SDK_VERSION/1000000
#define ESP8266_AT_VERSION 1000000
#define ESP8266_AT_VERSION_MAJOR ESP8266_AT_VERSION/1000000
#define ESP8266_AT_VERSION_TCP_PASSIVE_MODE 1070000
#define ESP8266_AT_VERSION_WIFI_SCAN_CHANGE 1060000
#define FW_AT_LEAST_VERSION(MAJOR,MINOR,PATCH,NUSED/*Not used*/,REF) \
(((MAJOR)*1000000+(MINOR)*10000+(PATCH)*100) >= REF ? true : false)
struct esp8266_socket {
int id;
nsapi_protocol_t proto;
bool connected;
bool bound;
SocketAddress addr;
int keepalive; // TCP
};
/** ESP8266Interface class.
This is an interface to a ESP8266 radio.
*/
class ESP8266 {
public:
ESP8266(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC);
/**
* ESP8266 firmware SDK version
*
* @param major Major version number
* @param minor Minor version number
* @param patch Patch version number
*/
struct fw_sdk_version {
int major;
int minor;
int patch;
fw_sdk_version(int major, int minor, int patch) : major(major), minor(minor), patch(patch) {}
};
/**
* ESP8266 firmware AT version
*
* @param major Major version number
* @param minor Minor version number
* @param patch Patch version number
*/
struct fw_at_version {
int major;
int minor;
int patch;
fw_at_version(int major, int minor, int patch) : major(major), minor(minor), patch(patch) {}
};
/**
* Check AT command interface of ESP8266
*
* @return true if ready to respond on AT commands
*/
bool at_available(void);
/**
* Disable echo - required for OOB processing to work
*
* @return true if echo was successfully disabled
*/
bool echo_off(void);
/**
* Check sdk version from which firmware is created
*
* @return fw_sdk_version which tells major, minor and patch version
*/
struct fw_sdk_version sdk_version(void);
/**
* Check AT instruction set version from which firmware is created
*
* @return fw_at_version which tells major, minor and patch version
*/
struct fw_at_version at_version(void);
/**
* Startup the ESP8266
*
* @param mode mode of WIFI 1-client, 2-host, 3-both
* @return true only if ESP8266 was setup correctly
*/
bool startup(int mode);
/**
* Reset ESP8266
*
* @return true only if ESP8266 resets successfully
*/
bool reset(void);
/**
* Enable/Disable DHCP
*
* @param enabled DHCP enabled when true
* @param mode mode of DHCP 0-softAP, 1-station, 2-both
* @return true only if ESP8266 enables/disables DHCP successfully
*/
bool dhcp(bool enabled, int mode);
/**
* Connect ESP8266 to AP
*
* @param ap the name of the AP
* @param passPhrase the password of AP
* @return NSAPI_ERROR_OK in success, negative error code in failure
*/
nsapi_error_t connect(const char *ap, const char *passPhrase);
/**
* Disconnect ESP8266 from AP
*
* @return true only if ESP8266 is disconnected successfully
*/
bool disconnect(void);
/**
* Enable or disable Remote IP and Port printing with +IPD
*
* @param enable, 1 on, 0 off
* @return true only if ESP8266 is disconnected successfully
*/
bool ip_info_print(int enable);
/**
* Get the IP address of ESP8266
*
* @return null-teriminated IP address or null if no IP address is assigned
*/
const char *ip_addr(void);
/**
* Set static IP address, gateway and netmask
*
* @param ip IP address to set
* @param gateway (optional) gateway to set
* @param netmask (optional) netmask to set
*
* @return true if operation was successful and flase otherwise
*/
bool set_ip_addr(const char *ip, const char *gateway, const char *netmask);
/**
* Get the MAC address of ESP8266
*
* @return null-terminated MAC address or null if no MAC address is assigned
*/
const char *mac_addr(void);
/** Get the local gateway
*
* @return Null-terminated representation of the local gateway
* or null if no network mask has been recieved
*/
const char *gateway();
/** Get the local network mask
*
* @return Null-terminated representation of the local network mask
* or null if no network mask has been recieved
*/
const char *netmask();
/* Return RSSI for active connection
*
* @return Measured RSSI
*/
int8_t rssi();
/** Scan mode
*/
enum scan_mode {
SCANMODE_ACTIVE = 0, /*!< active mode */
SCANMODE_PASSIVE = 1 /*!< passive mode */
};
/** Scan for available networks
*
* @param ap Pointer to allocated array to store discovered AP
* @param limit Size of allocated @a res array, or 0 to only count available AP
* @param t_max Maximum scan time per channel
* @param t_min Minimum scan time per channel in active mode, can be omitted in passive mode
* @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,
std::chrono::duration<unsigned, std::milli> t_max,
std::chrono::duration<unsigned, std::milli> t_min);
/**Perform a dns query
*
* @param name Hostname to resolve
* @param ip Buffer to store IP address
* @return 0 true on success, false on failure
*/
bool dns_lookup(const char *name, char *ip);
/**
* Open a socketed connection
*
* @param type the type of socket to open "UDP" or "TCP"
* @param id id to give the new socket, valid 0-4
* @param port port to open connection with
* @param addr the IP address of the destination
* @param port the port on the destination
* @param local_port UDP socket's local port, zero means any
* @param udp_mode UDP socket's mode, zero means can't change remote, 1 can change once, 2 can change multiple times
* @return NSAPI_ERROR_OK in success, negative error code in failure
*/
nsapi_error_t open_udp(int id, const char *addr, int port, int local_port = 0, int udp_mode = 0);
/**
* Open a socketed connection
*
* @param type the type of socket to open "UDP" or "TCP"
* @param id id to give the new socket, valid 0-4
* @param port port to open connection with
* @param addr the IP address of the destination
* @param port the port on the destination
* @param tcp_keepalive TCP connection's keep alive time, zero means disabled
* @return NSAPI_ERROR_OK in success, negative error code in failure
*/
nsapi_error_t open_tcp(int id, const char *addr, int port, int keepalive = 0);
/**
* Sends data to an open socket
*
* @param id id of socket to send to
* @param data data to be sent
* @param amount amount of data to be sent - max 2048
* @return number of bytes on success, negative error code in failure
*/
nsapi_size_or_error_t send(int id, const void *data, uint32_t amount);
/**
* Receives datagram from an open UDP socket
*
* @param id id to receive from
* @param data placeholder for returned information
* @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, mbed::chrono::milliseconds_u32 timeout = ESP8266_RECV_TIMEOUT);
/**
* Receives stream data from an open TCP socket
*
* @param id id to receive from
* @param data placeholder for returned information
* @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, mbed::chrono::milliseconds_u32 timeout = ESP8266_RECV_TIMEOUT);
/**
* Closes a socket
*
* @param id id of socket to close, valid only 0-4
* @return true only if socket is closed successfully
*/
bool close(int id);
/**
* Allows timeout to be changed between commands
*
* @param timeout_ms timeout of the connection
*/
void set_timeout(mbed::chrono::milliseconds_u32 timeout = ESP8266_MISC_TIMEOUT);
/**
* Checks if data is available
*/
bool readable();
/**
* Checks if data can be written
*/
bool writeable();
/**
* Attach a function to call whenever sigio happens in the serial
*
* @param func A pointer to a void function, or 0 to set as none
*/
void sigio(mbed::Callback<void()> func);
/**
* Attach a function to call whenever sigio happens in the serial
*
* @param obj pointer to the object to call the member function on
* @param method pointer to the member function to call
*/
template <typename T, typename M>
void sigio(T *obj, M method)
{
sigio(mbed::Callback<void()>(obj, method));
}
/**
* Attach a function to call whenever network state has changed.
*
* @param func A pointer to a void function, or 0 to set as none
*/
void attach(mbed::Callback<void()> status_cb);
/**
* Configure SNTP (Simple Network Time Protocol)
*
* @param enable true to enable SNTP or false to disable it
* @param timezone timezone offset [-11,13] (0 by default)
* @param server0 optional parameter indicating the first SNTP server ("cn.ntp.org.cn" by default)
* @param server1 optional parameter indicating the second SNTP server ("ntp.sjtu.edu.cn" by default)
* @param server2 optional parameter indicating the third SNTP server ("us.pool.ntp.org" by default)
*
* @retval true if successful, false otherwise
*/
bool set_sntp_config(bool enable, int timezone = 0, const char *server0 = nullptr,
const char *server1 = nullptr, const char *server2 = nullptr);
/**
* Read out the configuration of SNTP (Simple Network Time Protocol)
*
* @param enable true if SNTP is enabled
* @param timezone timezone offset [-11,13]
* @param server0 name of the first SNTP server
* @param server1 name of the second SNTP server (optional, nullptr if not set)
* @param server2 name of the third SNTP server (optional, nullptr if not set)
*
* @retval true if successful, false otherwise
*/
bool get_sntp_config(bool *enable, int *timezone, char *server0,
char *server1, char *server2);
/**
* Read out SNTP time from ESP8266.
*
* @param t std::tm structure to be filled in
* @retval true on success, false otherwise
*
* @note ESP8266 must be connected and needs a couple of seconds
* before returning correct time. It may return 1 Jan 1970 if it is not ready.
*
* @note esp8266.sntp-enable must be set to true in mbed_app.json file.
*/
bool get_sntp_time(std::tm *t);
template <typename T, typename M>
void attach(T *obj, M method)
{
attach(mbed::Callback<void()>(obj, method));
}
/**
* Read default Wifi mode from flash
*
* return Station, SoftAP or SoftAP+Station - 0 on failure
*/
int8_t default_wifi_mode();
/**
* Default Wifi mode written to flash only if changes
*/
bool set_default_wifi_mode(const int8_t mode);
/**
* @param track_ap if TRUE, sets the county code to be the same as the AP's that ESP is connected to,
* if FALSE the code will not change
* @param country_code ISO 3166-1 Alpha-2 coded country code
* @param channel_start the channel number to start at
* @param channels number of channels
*/
bool set_country_code_policy(bool track_ap, const char *country_code, int channel_start, int channels);
/** Get the connection status
*
* @return The connection status according to ConnectionStatusType
*/
nsapi_connection_status_t connection_status() const;
/**
* Start board's and ESP8266's UART flow control
*
* @return true if started
*/
bool start_uart_hw_flow_ctrl();
/**
* Stop board's and ESP8266's UART flow control
*
* @return true if started
*/
bool stop_uart_hw_flow_ctrl();
/*
* From AT firmware v1.7.0.0 onwards enables TCP passive mode
*/
bool cond_enable_tcp_passive_mode();
/**
* For executing OOB processing on background
*
* @param timeout AT parser receive timeout
* @param if TRUE, process all OOBs instead of only one
*/
void bg_process_oob(std::chrono::duration<uint32_t, std::milli> timeout, bool all);
/**
* Flush the serial port input buffers.
*
* If you do HW reset for ESP module, you should
* flush the input buffers from existing responses
* from the device.
*/
void flush();
static const int8_t WIFIMODE_STATION = 1;
static const int8_t WIFIMODE_SOFTAP = 2;
static const int8_t WIFIMODE_STATION_SOFTAP = 3;
static const int8_t SOCKET_COUNT = 5;
/**
* Enables or disables uart input and deep sleep
*
* @param lock if TRUE, uart input is enabled and deep sleep is locked
* if FALSE, uart input is disabled and deep sleep is unlocked
*/
int uart_enable_input(bool lock);
private:
// FW version
struct fw_sdk_version _sdk_v;
struct fw_at_version _at_v;
// FW version specific settings and functionalities
bool _tcp_passive;
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
mbed::BufferedSerial _serial;
PinName _serial_rts;
PinName _serial_cts;
rtos::Mutex _smutex; // Protect serial port access
// AT Command Parser
mbed::ATCmdParser _parser;
// Wifi scan result handling
bool _recv_ap(nsapi_wifi_ap_t *ap);
// Socket data buffer
struct packet {
struct packet *next;
int id;
char remote_ip[16];
int remote_port;
uint32_t len; // Remaining length
uint32_t alloc_len; // Original length
// data follows
} *_packets, * *_packets_end;
void _clear_socket_packets(int id);
void _clear_socket_sending(int id);
int _sock_active_id;
// Memory statistics
size_t _heap_usage; // (Socket data buffer usage)
// OOB processing
void _process_oob(std::chrono::duration<uint32_t, std::milli> timeout, bool all);
// OOB message handlers
void _oob_packet_hdlr();
void _oob_connect_err();
void _oob_conn_already();
void _oob_err();
void _oob_socket0_closed();
void _oob_socket1_closed();
void _oob_socket2_closed();
void _oob_socket3_closed();
void _oob_socket4_closed();
void _oob_connection_status();
void _oob_socket_close_err();
void _oob_watchdog_reset();
void _oob_busy();
void _oob_tcp_data_hdlr();
void _oob_ready();
void _oob_scan_results();
void _oob_send_ok_received();
void _oob_send_fail_received();
// OOB state variables
int _connect_error;
bool _disconnect;
bool _fail;
bool _sock_already;
bool _closed;
bool _error;
bool _busy;
bool _reset_done;
int _sock_sending_id;
// Modem's address info
char _ip_buffer[16];
char _gateway_buffer[16];
char _netmask_buffer[16];
char _mac_buffer[18];
// Modem's socket info
struct _sock_info {
bool open;
nsapi_protocol_t proto;
char *tcp_data;
int32_t tcp_data_avbl; // Data waiting on modem
int32_t tcp_data_rcvd;
bool send_fail; // Received 'SEND FAIL'. Expect user will close the socket.
};
struct _sock_info _sock_i[SOCKET_COUNT];
// Scan results
struct _scan_results {
WiFiAccessPoint *res;
unsigned limit;
unsigned cnt;
};
struct _scan_results _scan_r;
// Connection state reporting
nsapi_connection_status_t _conn_status;
mbed::Callback<void()> _conn_stat_cb; // ESP8266Interface registered
};
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,534 @@
/* ESP8266 implementation of NetworkInterfaceAPI
* Copyright (c) 2015 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ESP8266_INTERFACE_H
#define ESP8266_INTERFACE_H
#if DEVICE_SERIAL && DEVICE_INTERRUPTIN && defined(MBED_CONF_EVENTS_PRESENT) && defined(MBED_CONF_NSAPI_PRESENT) && defined(MBED_CONF_RTOS_API_PRESENT)
#include "drivers/DigitalOut.h"
#include "drivers/Timer.h"
#include "ESP8266/ESP8266.h"
#include "events/EventQueue.h"
#include "events/mbed_shared_queues.h"
#include "netsocket/NetworkInterface.h"
#include "netsocket/NetworkStack.h"
#include "netsocket/nsapi_types.h"
#include "netsocket/SocketAddress.h"
#include "netsocket/WiFiAccessPoint.h"
#include "netsocket/WiFiInterface.h"
#include "platform/Callback.h"
#include "platform/mbed_chrono.h"
#if MBED_CONF_RTOS_PRESENT
#include "rtos/ConditionVariable.h"
#endif
#include "rtos/Mutex.h"
#define ESP8266_SOCKET_COUNT 5
#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
#define MBED_CONF_ESP8266_TX D1
#endif
#ifndef MBED_CONF_ESP8266_RX
#define MBED_CONF_ESP8266_RX D0
#endif
#endif /* TARGET_FF_ARDUINO */
#ifndef MBED_CONF_ESP8266_COUNTRY_CODE
#define MBED_CONF_ESP8266_COUNTRY_CODE "CN"
#endif
#ifndef MBED_CONF_ESP8266_CHANNEL_START
#define MBED_CONF_ESP8266_CHANNEL_START 1
#endif
#ifndef MBED_CONF_ESP8266_CHANNELS
#define MBED_CONF_ESP8266_CHANNELS 13
#endif
/** ESP8266Interface class
* Implementation of the NetworkStack for the ESP8266
*/
class ESP8266Interface : public NetworkStack, public WiFiInterface {
public:
#if defined MBED_CONF_ESP8266_TX && defined MBED_CONF_ESP8266_RX
/**
* @brief ESP8266Interface default constructor
* Will use values defined in mbed_lib.json
*/
ESP8266Interface();
#endif
/** ESP8266Interface lifetime
* @param tx TX pin
* @param rx RX pin
* @param debug Enable debugging
*/
ESP8266Interface(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC, PinName rst = NC, PinName pwr = NC);
/**
* @brief ESP8266Interface default destructor
*/
virtual ~ESP8266Interface();
/** Start the interface
*
* Attempts to connect to a WiFi network. Requires ssid and passphrase to be set.
* If passphrase is invalid, NSAPI_ERROR_AUTH_ERROR is returned.
*
* @return 0 on success, negative error code on failure
*/
virtual int connect();
/** Start the interface
*
* Attempts to connect to a WiFi network.
*
* If interface is configured blocking it will timeout after up to
* ESP8266_INTERFACE_CONNECT_TIMEOUT_MS + ESP8266_CONNECT_TIMEOUT ms.
*
* @param ssid Name of the network to connect to
* @param pass Security passphrase to connect to the network
* @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE)
* @param channel This parameter is not supported, setting it to anything else than 0 will result in NSAPI_ERROR_UNSUPPORTED
* @return 0 on success, or error code on failure
*/
virtual int connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE,
uint8_t channel = 0);
/** Set the WiFi network credentials
*
* @param ssid Name of the network to connect to
* @param pass Security passphrase to connect to the network
* @param security Type of encryption for connection
* (defaults to NSAPI_SECURITY_NONE)
* @return 0 on success, or error code on failure
*/
virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE);
/** Set the WiFi network channel - NOT SUPPORTED
*
* This function is not supported and will return NSAPI_ERROR_UNSUPPORTED
*
* @param channel Channel on which the connection is to be made, or 0 for any (Default: 0)
* @return Not supported, returns NSAPI_ERROR_UNSUPPORTED
*/
virtual int set_channel(uint8_t channel);
/** @copydoc NetworkInterface::set_network */
virtual nsapi_error_t set_network(const SocketAddress &ip_address, const SocketAddress &netmask, const SocketAddress &gateway);
/** @copydoc NetworkInterface::dhcp */
virtual nsapi_error_t set_dhcp(bool dhcp);
/** Stop the interface
* @return 0 on success, negative on failure
*/
virtual int disconnect();
/** Get the internally stored IP address
* @return IP address of the interface or null if not yet connected
*/
virtual nsapi_error_t get_ip_address(SocketAddress *address);
/** Get the internally stored MAC address
* @return MAC address of the interface
*/
virtual const char *get_mac_address();
/** Get the local gateway
*
* @return Null-terminated representation of the local gateway
* or null if no network mask has been recieved
*/
virtual nsapi_error_t get_gateway(SocketAddress *address);
MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated")
virtual const char *get_gateway();
/** Get the local network mask
*
* @return Null-terminated representation of the local network mask
* or null if no network mask has been recieved
*/
virtual nsapi_error_t get_netmask(SocketAddress *address);
MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated")
virtual const char *get_netmask();
/** Get the current time.
*
* @retval NSAPI_ERROR_UNSUPPORTED if the function is not supported
* @retval NSAPI_ERROR_OK on success
*
* @note esp8266.sntp-enable must be set to true in mbed_app.json.
*/
nsapi_error_t get_time(std::tm *t);
/** Get the network interface name
*
* @return Null-terminated representation of the network interface name
* or null if interface not exists
*/
virtual char *get_interface_name(char *interface_name);
/** Gets the current radio signal strength for active connection
*
* @return Connection strength in dBm (negative value)
*/
virtual int8_t get_rssi();
/** Scan mode
*/
enum scan_mode {
SCANMODE_ACTIVE, /*!< active mode */
SCANMODE_PASSIVE /*!< passive mode */
};
/** Scan for available networks
*
* This function will block.
*
* @param ap Pointer to allocated array to store discovered AP
* @param count Size of allocated @a res array, or 0 to only count available AP
* @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error
* see @a nsapi_error
*/
virtual int scan(WiFiAccessPoint *res, unsigned count);
/** Scan for available networks
*
* This function will block.
*
* @param ap Pointer to allocated array to store discovered AP
* @param count Size of allocated @a res array, or 0 to only count available AP
* @param t_max Scan time for each channel - 0-1500ms. If 0 - uses default value
* @param t_min Minimum for each channel in active mode - 0-1500ms. If 0 - uses default value. Omit in passive mode
* @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error
* see @a nsapi_error
*/
virtual int scan(WiFiAccessPoint *res, unsigned count, scan_mode mode = SCANMODE_PASSIVE,
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
*
* The hostname may be either a domain name or an IP address. If the
* hostname is an IP address, no network transactions will be performed.
*
* If no stack-specific DNS resolution is provided, the hostname
* will be resolve using a UDP socket on the stack.
*
* @param address Destination for the host SocketAddress
* @param host Hostname to resolve
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates
* version is chosen by the stack (defaults to NSAPI_UNSPEC)
* @return 0 on success, negative error code on failure
*/
#if MBED_CONF_ESP8266_BUILT_IN_DNS
nsapi_error_t gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name);
#else
using NetworkInterface::gethostbyname;
#endif
using NetworkInterface::gethostbyname_async;
using NetworkInterface::gethostbyname_async_cancel;
/** Add a domain name server to list of servers to query
*
* @param addr Destination for the host address
* @return 0 on success, negative error code on failure
*/
#if MBED_CONF_ESP8266_BUILT_IN_DNS
nsapi_error_t add_dns_server(const SocketAddress &address, const char *interface_name);
#else
using NetworkInterface::add_dns_server;
#endif
/** @copydoc NetworkStack::setsockopt
*/
virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level,
int optname, const void *optval, unsigned optlen);
/** @copydoc NetworkStack::getsockopt
*/
virtual nsapi_error_t getsockopt(nsapi_socket_t handle, int level, int optname,
void *optval, unsigned *optlen);
/** Register callback for status reporting
*
* The specified status callback function will be called on status changes
* on the network. The parameters on the callback are the event type and
* event-type dependent reason parameter.
*
* In ESP8266 the callback will be called when processing OOB-messages via
* AT-parser. Do NOT call any ESP8266Interface -functions or do extensive
* processing in the callback.
*
* @param status_cb The callback for status changes
*/
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
/** Get the connection status
*
* @return The connection status according to ConnectionStatusType
*/
virtual nsapi_connection_status_t get_connection_status() const;
protected:
/** Open a socket
* @param handle Handle in which to store new socket
* @param proto Type of socket to open, NSAPI_TCP or NSAPI_UDP
* @return 0 on success, negative on failure
*/
virtual int socket_open(void **handle, nsapi_protocol_t proto);
/** Close the socket
* @param handle Socket handle
* @return 0 on success, negative on failure
* @note On failure, any memory associated with the socket must still
* be cleaned up
*/
virtual int socket_close(void *handle);
/** Bind a server socket to a specific port
* @param handle Socket handle
* @param address Local address to listen for incoming connections on
* @return 0 on success, negative on failure.
*/
virtual int socket_bind(void *handle, const SocketAddress &address);
/** Start listening for incoming connections
* @param handle Socket handle
* @param backlog Number of pending connections that can be queued up at any
* one time [Default: 1]
* @return 0 on success, negative on failure
*/
virtual int socket_listen(void *handle, int backlog);
/** Connects this TCP socket to the server
* @param handle Socket handle
* @param address SocketAddress to connect to
* @return 0 on success, negative on failure
*/
virtual int socket_connect(void *handle, const SocketAddress &address);
/** Accept a new connection.
* @param handle Handle in which to store new socket
* @param server Socket handle to server to accept from
* @return 0 on success, negative on failure
* @note This call is not-blocking, if this call would block, must
* immediately return NSAPI_ERROR_WOULD_WAIT
*/
virtual int socket_accept(void *handle, void **socket, SocketAddress *address);
/** Send data to the remote host
* @param handle Socket handle
* @param data The buffer to send to the host
* @param size The length of the buffer to send
* @return Number of written bytes on success, negative on failure
* @note This call is not-blocking, if this call would block, must
* immediately return NSAPI_ERROR_WOULD_WAIT
*/
virtual int socket_send(void *handle, const void *data, unsigned size);
/** Receive data from the remote host
* @param handle Socket handle
* @param data The buffer in which to store the data received from the host
* @param size The maximum length of the buffer
* @return Number of received bytes on success, negative on failure
* @note This call is not-blocking, if this call would block, must
* immediately return NSAPI_ERROR_WOULD_WAIT
*/
virtual int socket_recv(void *handle, void *data, unsigned size);
/** Send a packet to a remote endpoint
* @param handle Socket handle
* @param address The remote SocketAddress
* @param data The packet to be sent
* @param size The length of the packet to be sent
* @return The number of written bytes on success, negative on failure
* @note This call is not-blocking, if this call would block, must
* immediately return NSAPI_ERROR_WOULD_WAIT
*/
virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size);
/** Receive a packet from a remote endpoint
* @param handle Socket handle
* @param address Destination for the remote SocketAddress or null
* @param buffer The buffer for storing the incoming packet data
* If a packet is too long to fit in the supplied buffer,
* excess bytes are discarded
* @param size The length of the buffer
* @return The number of received bytes on success, negative on failure
* @note This call is not-blocking, if this call would block, must
* immediately return NSAPI_ERROR_WOULD_WAIT
*/
virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size);
/** Register a callback on state change of the socket
* @param handle Socket handle
* @param callback Function to call on state change
* @param data Argument to pass to callback
* @note Callback may be called in an interrupt context.
*/
virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
/** Provide access to the NetworkStack object
*
* @return The underlying NetworkStack object
*/
virtual NetworkStack *get_stack()
{
return this;
}
/** Set blocking status of connect() which by default should be blocking.
*
* @param blocking Use true to make connect() blocking.
* @return NSAPI_ERROR_OK on success, negative error code on failure.
*/
virtual nsapi_error_t set_blocking(bool blocking);
/** Set country code
*
* @param track_ap if TRUE, use country code used by the AP ESP is connected to,
* otherwise uses country_code always
* @param country_code ISO 3166-1 coded, 2 character alphanumeric country code assumed
* @param len Length of the country code
* @param channel_start The channel number to start at
* @param channel Number of channels
* @return NSAPI_ERROR_OK on success, negative error code on failure.
*/
nsapi_error_t set_country_code(bool track_ap, const char *country_code, int len, int channel_start, int channels);
private:
// AT layer
ESP8266 _esp;
void refresh_conn_state_cb();
/** Status of software connection
*/
typedef enum esp_connection_software_status {
IFACE_STATUS_DISCONNECTED = 0,
IFACE_STATUS_CONNECTING = 1,
IFACE_STATUS_CONNECTED = 2,
IFACE_STATUS_DISCONNECTING = 3
} esp_connection_software_status_t;
// HW reset pin
class ResetPin {
public:
ResetPin(PinName rst_pin);
void rst_assert();
void rst_deassert();
bool is_connected();
private:
mbed::DigitalOut _rst_pin;
} _rst_pin;
// HW power pin
class PowerPin {
public:
PowerPin(PinName pwr_pin);
void power_on();
void power_off();
bool is_connected();
private:
mbed::DigitalOut _pwr_pin;
} _pwr_pin;
/** Assert the reset and power pins
* ESP8266 has two pins serving similar purpose and this function asserts them both
* if they are configured in mbed_app.json.
*/
void _power_off();
// Credentials
static const int ESP8266_SSID_MAX_LENGTH = 32; /* 32 is what 802.11 defines as longest possible name */
char ap_ssid[ESP8266_SSID_MAX_LENGTH + 1]; /* The longest possible name; +1 for the \0 */
static const int ESP8266_PASSPHRASE_MAX_LENGTH = 63; /* The longest allowed passphrase */
static const int ESP8266_PASSPHRASE_MIN_LENGTH = 8; /* The shortest allowed passphrase */
char ap_pass[ESP8266_PASSPHRASE_MAX_LENGTH + 1]; /* The longest possible passphrase; +1 for the \0 */
nsapi_security_t _ap_sec;
// Country code
struct _channel_info {
bool track_ap; // Set country code based on the AP ESP is connected to
char country_code[4]; // ISO 3166-1 coded, 2-3 character alphanumeric country code - +1 for the '\0' - assumed. Documentation doesn't tell.
int channel_start;
int channels;
};
struct _channel_info _ch_info;
bool _if_blocking; // NetworkInterface, blocking or not
#if MBED_CONF_RTOS_PRESENT
rtos::ConditionVariable _if_connected;
#endif
// connect status reporting
nsapi_error_t _conn_status_to_error();
mbed::Timer _conn_timer;
// Drivers's socket info
struct _sock_info {
bool open;
uint16_t sport;
};
struct _sock_info _sock_i[ESP8266_SOCKET_COUNT];
// Driver's state
int _initialized;
nsapi_error_t _connect_retval;
nsapi_error_t _disconnect_retval;
bool _get_firmware_ok();
nsapi_error_t _init(void);
nsapi_error_t _reset();
//sigio
struct {
void (*callback)(void *);
void *data;
uint8_t deferred;
} _cbs[ESP8266_SOCKET_COUNT];
void event();
void event_deferred();
// Connection state reporting to application
nsapi_connection_status_t _conn_stat;
mbed::Callback<void(nsapi_event_t, intptr_t)> _conn_stat_cb;
// Background OOB processing
// Use global EventQueue
events::EventQueue *_global_event_queue;
int _oob_event_id;
int _connect_event_id;
int _disconnect_event_id;
void proc_oob_evnt();
void _connect_async();
void _disconnect_async();
rtos::Mutex _cmutex; // Protect asynchronous connection logic
esp_connection_software_status_t _software_conn_stat;
bool _dhcp;
};
#endif
#endif

View File

@@ -0,0 +1,100 @@
# ESP8266 WiFi driver for Mbed OS
The Mbed OS driver for the ESP8266 WiFi module.
## Firmware version
ESP8266 modules come in different shapes and formats, but the firmware version is the most important factor. To
make sure that the firmware in your module is compatible with Mbed OS, follow the
[Update guide](https://developer.mbed.org/teams/ESP8266/wiki/Firmware-Update).
This driver supports AT firmware versions 1.3.0 to 1.7.0. We advise updating the
[AT firmware](https://www.espressif.com/en/support/download/at?keys=) to at least version 1.7.0.
## Restrictions
* The ESP8266 Wi-Fi module does not allow the TCP client to bind to a specific port.
* Setting up a UDP server is not possible.
* The serial port does not have hardware flow control enabled by default. Additionally, the AT command set does not have a method for limiting the download rate. Therefore, downloading anything larger than the serial port input buffer is unreliable
unless you use [AT firmware](https://www.espressif.com/en/support/download/at?keys=) version 1.7.0 or later. With older
firmware, an application should be able to read fast enough to stay ahead of the network. This applies mostly to TCP
protocol, where data would be lost without notification. On UDP using all firmware versions, the higher-layer protocol should recover from packet loss.
## Mandatory configuration
[mbed_lib.json](mbed_lib.json) configuration assumes Arduino form factor. Please adjust according to your board. You can override parameters from your app config file.
At minimum, check the following configuration parameters:
```javascript
{
"name": "esp8266",
"config": {
"tx": {
"help": "TX pin for serial connection",
"value": null <- 'D1' by default if Arduino, adjust based on your board
},
"rx": {
"help": "RX pin for serial connection",
"value": null <- 'D0' by default if Arduino, adjust based on your board
},
"provide-default": {
"help": "Provide default WifiInterface. [true/false]",
"value": false <- Set to 'true' if this is the interface you are using
},
"socket-bufsize": {
"help": "Max socket data heap usage",
"value": 8192 <- Without HW flow control more is better. Once the limit is reached packets are
dropped - does not matter is it TCP or UDP.
}
}
}
```
## UART HW flow control
UART HW flow control requires you to additionally wire the CTS and RTS flow control pins between your board and your
ESP8266 module. After this, remember to add the configuration option for flow control to your app configuration file. This example uses the [ST NUCLEO-F429ZI](https://os.mbed.com/platforms/ST-Nucleo-F429ZI/) board and
[ESPBee XBee Module](https://www.cascologix.com/product/espbee/).
**Note:** Not all modules expose ESP8266's RTS and CTS pins, so choose modules carefully.
Once you have your hardware set up, add a configuration like the following to your app configuration file. Arduino pins D1 and D0 are used as TX and RX:
``` javascript
"target_overrides": {
"NUCLEO_F429ZI": {
"esp8266.rts": "PG_12",
"esp8266.cts": "PG_15"
}
```
### Example board pins
* TX: D1 (Arduino Uno Revision 3 connectivity headers)
* RX: D0 (Arduino Uno Revision 3 connectivity headers)
* RTS: PG_12 (STMicroelectronics Morpho extension pin headers)
* CTS: PG_15 (STMicroelectronics Morpho extension pin headers)
### Example ESP8266 pins
* TX: D1 (Arduino Wireless Protoshield headers)/ TX (ESPBee XBee headers)
* RX: D0 (Arduino Wireless Protoshield headers)/ RX (ESPBee XBee headers)
* RTS: RTS (ESPBee XBee headers)
* CTS: CTS (ESPBee XBee headers)
### Connections
With these pictures only consider the green and yellow wires which are connected to ESP8266. The pink wire is for reset and
the rest are for firmware update. TX and RX go through Arduino pins D1 and D0.
**Note:** Pull down GPIO15(ESPBee RTS) during startup to **boot from flash**, instead of **firmware update** or
**boot from SD card**. Once the software is running, the same pin is used as the RTS pin:
* Board TX: ESP8266 RX
* Board RX: ESP8266 TX
* Board RTS (grey): ESP8266 CTS(yellow)
* Board CTS (white): ESP8266 RTS(green)
![RTS,CTS](nucleo_esp8266_hw_fc1.jpg)
![RTS,CTS](nucleo_esp8266_hw_fc2.jpg)

View File

@@ -0,0 +1,108 @@
{
"name": "esp8266",
"config": {
"tx": {
"help": "TX pin for serial connection. D1 assumed if Arduino Form Factor, needs to be set/overwritten otherwise",
"value": null
},
"rx": {
"help": "RX pin for serial connection. D0 assumed if Arduino Form Factor, needs to be set/overwritten otherwise",
"value": null
},
"rts": {
"help": "RTS pin for serial connection, defaults to Not Connected",
"value": null
},
"cts": {
"help": "CTS pin for serial connection, defaults to Not Connected",
"value": null
},
"serial-baudrate": {
"help": "Serial baudrate for ESP8266, defaults to 115200",
"value": 115200
},
"rst": {
"help": "RESET pin for the modem, defaults to Not Connected",
"value": null
},
"pwr": {
"help": "POWER pin for the modem, defaults to Not Connected",
"value": null
},
"power-on-polarity": {
"help": "Polarity of power-on for the modem. 0 means 0/1 for power on/off; 1 means 1/0 for power on/off.",
"options": [0, 1],
"value": 0
},
"power-on-time-ms": {
"help": "Delay after powering on the modem in ms",
"value": 3
},
"power-off-time-ms": {
"help": "Delay after powering off the modem in ms",
"value": 3
},
"debug": {
"help": "Enable debug logs. [true/false]",
"value": false
},
"provide-default": {
"help": "Provide default WifiInterface. [true/false]",
"value": false
},
"socket-bufsize": {
"help": "Max socket data heap usage",
"value": 8192
},
"country-code": {
"help": "ISO 3166-1 coded, 2 character alphanumeric country code, 'CN' by default",
"value": null
},
"channel-start": {
"help": "The channel number to start at, 1 by default",
"value": null
},
"channels": {
"help": "Channel count, 13 by default",
"value": null
},
"built-in-dns": {
"help": "use built-in CIPDOMAIN AT command to resolve address to IP",
"value": false
},
"sntp-enable": {
"help": "Enable SNTP. This allows application to use get_sntp_time(). Only available from ESP8266 AT v1.5. This driver supports v1.7 and higher.",
"value": false
},
"sntp-timezone": {
"help": "SNTP timezone",
"value": 0
},
"sntp-server0": {
"help": "First SNTP server. Empty string will let ESP8266 use its default.",
"value": "\"\""
},
"sntp-server1": {
"help": "Second SNTP server. Empty string will let ESP8266 use its default.",
"value": "\"\""
},
"sntp-server2": {
"help": "Third SNTP server. Empty string will let ESP8266 use its default.",
"value": "\"\""
}
},
"target_overrides": {
"HEXIWEAR": {
"tx": "PTD3",
"rx": "PTD2"
},
"NUCLEO_F401RE": {
"tx": "D8",
"rx": "D2"
},
"NUCLEO_F411RE": {
"tx": "D8",
"rx": "D2"
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB