8000 Merge branch 'master' into WIP-upstream-umm_malloc · esp8266/Arduino@da47a79 · GitHub
[go: up one dir, main page]

Skip to content

Commit da47a79

Browse files
authored
Merge branch 'master' into WIP-upstream-umm_malloc
2 parents 57b65ab + 85f1ea7 commit da47a79

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1118
-217
lines changed

boards.txt

Lines changed: 166 additions & 76 deletions
Large diffs are not rendered by default.

cores/esp8266/Print.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ size_t Print::write(const uint8_t *buffer, size_t size) {
4545

4646
size_t n = 0;
4747
while (size--) {
48-
size_t ret = write(*buffer++);
48+
size_t ret = write(pgm_read_byte(buffer++));
4949
if (ret == 0) {
5050
// Write of last byte didn't complete, abort additional processing
5151
break;

cores/esp8266/Print.h

Lines changed: 1 addition & 1 deletion
< 6377 tr class="diff-line-row">
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class Print {
5656
size_t write(const char *str) {
5757
if(str == NULL)
5858
return 0;
59-
return write((const uint8_t *) str, strlen(str));
59+
return write((const uint8_t *) str, strlen_P(str));
6060
}
6161
virtual size_t write(const uint8_t *buffer, size_t size);
6262
size_t write(const char *buffer, size_t size) {

cores/esp8266/Updater.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include "Updater.h"
2-
#include "Arduino.h"
32
#include "eboot_command.h"
43
#include <esp8266_peri.h>
54

@@ -11,10 +10,10 @@
1110
#endif
1211

1312
#if ARDUINO_SIGNING
14-
#include "../../libraries/ESP8266WiFi/src/BearSSLHelpers.h"
15-
static BearSSL::PublicKey signPubKey(signing_pubkey);
16-
static BearSSL::HashSHA256 hash;
17-
static BearSSL::SigningVerifier sign(&signPubKey);
13+
namespace esp8266 {
14+
extern UpdaterHashClass& updaterSigningHash;
15+
extern UpdaterVerifyClass& updaterSigningVerifier;
16+
}
1817
#endif
1918

2019
extern "C" {
@@ -39,7 +38,7 @@ UpdaterClass::UpdaterClass()
3938
, _progress_callback(nullptr)
4039
{
4140
#if ARDUINO_SIGNING
42-
installSignature(&hash, &sign);
41+
installSignature(&esp8266::updaterSigningHash, &esp8266::updaterSigningVerifier);
4342
#endif
4443
}
4544

cores/esp8266/abi.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
3232
extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
3333

3434

35-
#ifndef __cpp_exceptions
35+
#if !defined(__cpp_exceptions) && !defined(NEW_OOM_ABORT)
3636
void *operator new(size_t size)
3737
{
3838
void *ret = malloc(size);
@@ -52,7 +52,7 @@ void *operator new[](size_t size)
5252
}
5353
return ret;
5454
}
55-
#endif
55+
#endif // arduino's std::new legacy
5656

5757
void __cxa_pure_virtual(void)
5858
{

cores/esp8266/core_esp8266_features.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,37 @@
3232

3333
#define WIFI_HAS_EVENT_CALLBACK
3434

35+
#ifdef __cplusplus
36+
37+
#include <stdlib.h> // malloc()
38+
#include <stddef.h> // size_t
39+
40+
namespace arduino
41+
{
42+
extern "C++"
43+
template <typename T, typename ...TConstructorArgs>
44+
T* new0 (size_t n, TConstructorArgs... TconstructorArgs)
45+
{
46+
// n==0: single allocation, otherwise it is an array
47+
size_t offset = n? sizeof(size_t): 0;
48+
size_t arraysize = n? n: 1;
49+
T* ptr = (T*)malloc(offset + (arraysize * sizeof(T)));
50+
if (ptr)
51+
{
52+
if (n)
53+
*(size_t*)(ptr) = n;
54+
for (size_t i = 0; i < arraysize; i++)
55+
new (ptr + offset + i * sizeof(T)) T(TconstructorArgs...);
56+
return ptr + offset;
57+
}
58+
return nullptr;
59+
}
60+
}
61+
62+
#define arduino_new(Type, ...) arduino::new0<Type>(0, ##__VA_ARGS__)
63+
#define arduino_newarray(Type, n, ...) arduino::new0<Type>(n, ##__VA_ARGS__)
64+
65+
#endif // __cplusplus
3566

3667
#ifndef __STRINGIFY
3768
#define __STRINGIFY(a) #a
@@ -61,4 +92,4 @@ inline uint32_t esp_get_cycle_count() {
6192
}
6293
#endif // not CORE_MOCK
6394

64-
#endif
95+
#endif // CORE_ESP8266_FEATURES_H

cores/esp8266/uart.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ uart_write(uart_t* uart, const char* buf, size_t size)
495495
size_t ret = size;
496496
const int uart_nr = uart->uart_nr;
497497
while (size--)
498-
uart_do_write_char(uart_nr, *buf++);
498+
uart_do_write_char(uart_nr, pgm_read_byte(buf++));
499499

500500
return ret;
501501
}

doc/eclipse/makefile.init

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ ESP8266_BASE = $(ARDUINO_BASE)/hardware/esp8266com/esp8266
1414
ESP8266_TOOLS = $(ESP8266_BASE)/tools
1515
XTENSA_TOOLS_ROOT = $(ESP8266_TOOLS)/xtensa-lx106-elf/bin
1616

17-
PYTHON_BIN = python
17+
PYTHON_BIN = python3
1818
ESPTOOL_PY_BIN = $(ESP8266_TOOLS)/esptool.py
1919
ESPOTA_PY_BIN = $(ESP8266_TOOLS)/espota.py
2020
ESPTOOL_BIN = $(ESP8266_TOOLS)/esptool/esptool.exe

doc/installing.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Prerequisites
4343

4444
- Arduino 1.6.8 (or newer, current working version is 1.8.5)
4545
- git
46-
- Python 2.7 (https://python.org)
46+
- Python 3.x (https://python.org)
4747
- terminal, console, or command prompt (depending on your OS)
4848
- Internet connection
4949

@@ -110,7 +110,7 @@ Instructions - Windows 10
110110
.. code:: bash
111111
112112
cd esp8266/tools
113-
python get.py
113+
python3 get.py
114114
115115
- Restart Arduino
116116
@@ -184,7 +184,7 @@ Instructions - Other OS
184184
.. code:: bash
185185
186186
cd esp8266/tools
187-
python get.py
187+
python3 get.py
188188
189189
- Restart Arduino
190190

doc/ota_updates/readme.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ Instructions below show configuration of OTA on NodeMCU 1.0 (ESP-12E Module) boa
193193
- esp8266/Arduino platform package 2.0.0 or newer - for instructions
194194
follow
195195
https://github.com/esp8266/Arduino#installing-with-boards-manager
196-
- Python 2.7 - https://www.python.org/
196+
- Python 3.x - https://www.python.org/
197197

198198
**Note:** Windows users should select “Add python.exe to Path”
199199
(see below – this option is not selected by default).

doc/reference.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,75 @@ using FPSTR would become...
215215
String response2;
216216
response2 += FPSTR(HTTP);
217217
}
218+
219+
C++
220+
----
221+
222+
- About C++ exceptions, ``operator new``, and Exceptions menu option
223+
224+
The C++ standard says the following about the ``new`` operator behavior when encountering heap shortage (memory full):
225+
226+
- has to throw a ``std::bad_alloc`` C++ exception when they are enabled
227+
228+
- will ``abort()`` otherwise
229+
230+
There are several reasons for the first point above, among which are:
231+
232+
- guarantee that the return of new is never a ``nullptr``
233+
234+
- guarantee full construction of the top level object plus all member subobjects
235+
236+
- guarantee that any subobjects partially constructed get destroyed, and in the correct order, if oom is encountered midway through construction
237+
238+
When C++ exceptions are disabled, or when using ``new(nothrow)``, the above guarantees can't be upheld, so the second point (``abort()``) above is the only ``std::c++`` viable solution.
239+
240+
Historically in Arduino environments, ``new`` is overloaded to simply return the equivalent ``malloc()`` which in turn can return ``nullptr``.
241+
242+
This behavior is not C++ standard, and there is good reason for that: there are hidden and very bad side effects. The *class and member constructors are always called, even when memory is full* (``this == nullptr``).
243+
In addition, the memory allocation for the top object could succeed, but allocation required for some member object could fail, leaving construction in an undefined state.
244+
So the historical behavior of Ardudino's ``new``, when faced with insufficient memory, will lead to bad crashes sooner or later, sometimes unexplainable, generally due to memory corruption even when the returned value is checked and managed.
245+
Luckily on esp8266, trying to update RAM near address 0 will immediately raise an hardware exception, unlike on other uC like avr on which that memory can be accessible.
246+
247+
As of core 2.6.0, there are 3 options: legacy (default) and two clear cases when ``new`` encounters oom:
248+
249+
- ``new`` returns ``nullptr``, with possible bad effects or immediate crash when constructors (called anyway) initialize members (exceptions are disabled in this case)
250+
251+
- C++ exceptions are disabled: ``new`` calls ``abort()`` and will "cleanly" crash, because there is no way to honor memory allocation or to recover gracefully.
252+
253+
- C++ exceptions are enabled: ``new`` throws a ``std::bad_alloc`` C++ exception, which can be caught and handled gracefully.
254+
This assures correct behavior, including handling of all subobjects, which guarantees stability.
255+
256+
History: `#6269 <https://github.com/esp8266/Arduino/issues/6269>`__ `#6309 <https://github.com/esp8266/Arduino/pull/6309>`__ `#6312 <https://github.com/esp8266/Arduino/pull/6312>`__
257+
258+
- New optional allocator ``arduino_new``
259+
260+
A new optional global allocator is introduced with a different semantic:
261+
262+
- never throws exceptions on oom
263+
264+
- never calls constructors on oom
265+
266+
- returns nullptr on oom
267+
268+
It is similar to arduino ``new`` semantic without side effects
269+
(except when parent constructors, or member constructors use ``new``).
270+
271+
Syntax is slightly different, the following shows the different usages:
272+
273+
.. code:: cpp
274+
275+
// with new:
276+
277+
SomeClass* sc = new SomeClass(arg1, arg2, ...);
278+
delete sc;
279+
280+
SomeClass* scs = new SomeClass[42];
281+
delete [] scs;
282+
283+
// with arduino_new:
284+
285+
SomeClass* sc = arduino_new(SomeClass, arg1, arg2, ...);
286+
delete sc;
287+
288+
SomeClass* scs = arduino_newarray(SomeClass, 42);
289+
delete [] scs;

libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
#include <ESP8266HTTPClient.h>
1414

1515
#include <WiFiClientSecureBearSSL.h>
16-
// Fingerprint for demo URL, expires on June 2, 2019, needs to be updated well before this date
17-
const uint8_t fingerprint[20] = {0x5A, 0xCF, 0xFE, 0xF0, 0xF1, 0xA6, 0xF4, 0x5F, 0xD2, 0x11, 0x11, 0xC6, 0x1D, 0x2F, 0x0E, 0xBC, 0x39, 0x8D, 0x50, 0xE0};
16+
// Fingerprint for demo URL, expires on June 2, 2021, needs to be updated well before this date
17+
const uint8_t fingerprint[20] = {0x40, 0xaf, 0x00, 0x6b, 0xec, 0x90, 0x22, 0x41, 0x8e, 0xa3, 0xad, 0xfa, 0x1a, 0xe8, 0x25, 0x41, 0x1d, 0x1a, 0x54, 0xb3};
1818

1919
ESP8266WiFiMulti WiFiMulti;
2020

libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ bool HTTPClient::begin(String url, String httpsFingerprint)
225225
return false;
226226
}
227227
_transportTraits = TransportTraitsPtr(new TLSTraits(httpsFingerprint));
228+
if(!_transportTraits) {
229+
DEBUG_HTTPCLIENT("[HTTP-Client][begin] could not create transport traits\n");
230+
return false;
231+
}
232+
228233
DEBUG_HTTPCLIENT("[HTTP-Client][begin] httpsFingerprint: %s\n", httpsFingerprint.c_str());
229234
return true;
230235
}
@@ -242,6 +247,11 @@ bool HTTPClient::begin(String url, const uint8_t httpsFingerprint[20])
242247
return false;
243248
}
244249
_transportTraits = TransportTraitsPtr(new BearSSLTraits(httpsFingerprint));
250+
if(!_transportTraits) {
251+
DEBUG_HTTPCLIENT("[HTTP-Client][begin] could not create transport traits\n");
252+
return false;
253+
}
254+
245255
DEBUG_HTTPCLIENT("[HTTP-Client][begin] BearSSL-httpsFingerprint:");
246256
for (size_t i=0; i < 20; i++) {
247257
DEBUG_HTTPCLIENT(" %02x", httpsFingerprint[i]);
@@ -409,7 +419,7 @@ bool HTTPClient::begin(String host, uint16_t port, String uri, const uint8_t htt
409419
*/
410420
void HTTPClient::end(void)
411421
{
412-
disconnect();
422+
disconnect(false);
413423
clear();
414424
_redirectCount = 0;
415425
}
@@ -563,6 +573,7 @@ void HTTPClient::setRedirectLimit(uint16_t limit)
563573
void HTTPClient::useHTTP10(bool useHTTP10)
564574
{
565575
_useHTTP10 = useHTTP10;
576+
_reuse = !useHTTP10;
566577
}
567578

568579
/**
@@ -980,7 +991,7 @@ int HTTPClient::writeToStream(Stream * stream)
980991
return returnError(HTTPC_ERROR_ENCODING);
981992
}
982993

983-
disconnect();
994+
disconnect(true);
984995
return ret;
985996
}
986997

@@ -1139,7 +1150,11 @@ bool HTTPClient::hasHeader(const char* name)
11391150
bool HTTPClient::connect(void)
11401151
{
11411152
if(connected()) {
1142-
DEBUG_HTTPCLIENT("[HTTP-Client] connect. already connected, try reuse!\n");
1153+
if(_reuse) {
1154+
DEBUG_HTTPCLIENT("[HTTP-Client] connect: already connected, reusing connection\n");
1155+
} else {
1156+
DEBUG_HTTPCLIENT("[HTTP-Client] connect: already connected, try reuse!\n");
1157+
}
11431158
while(_client->available() > 0) {
11441159
_client->read();
11451160
}
@@ -1149,6 +1164,10 @@ bool HTTPClient::connect(void)
11491164
#if HTTPCLIENT_1_1_COMPATIBLE
11501165
if(!_client && _transportTraits) {
11511166
_tcpDeprecated = _transportTraits->create();
1167+
if(!_tcpDeprecated) {
1168+
DEBUG_HTTPCLIENT("[HTTP-Client] connect: could not create tcp\n");
1169+
return false;
1170+
}
11521171
_client = _tcpDeprecated.get();
11531172
}
11541173
#endif
@@ -1246,9 +1265,12 @@ int HTTPClient::handleHeaderResponse()
12461265
return HTTPC_ERROR_NOT_CONNECTED;
12471266
}
12481267

1268+
clear();
1269+
1270+
_canReuse = _reuse;
1271+
12491272
String transferEncoding;
1250-
_returnCode = -1;
1251-
_size = -1;
1273+
12521274
_transferEncoding = HTTPC_TE_IDENTITY;
12531275
unsigned long lastDataTime = millis();
12541276

@@ -1263,6 +1285,9 @@ int HTTPClient::handleHeaderResponse()
12631285
DEBUG_HTTPCLIENT("[HTTP-Client][handleHeaderResponse] RX: '%s'\n", headerLine.c_str());
12641286

12651287
if(headerLine.startsWith("HTTP/1.")) {
1288+
if(_canReuse) {
1289+
_canReuse = (headerLine[sizeof "HTTP/1." - 1] != '0');
1290+
}
12661291
_returnCode = headerLine.substring(9, headerLine.indexOf(' ', 9)).toInt();
12671292
} else if(headerLine.indexOf(':')) {
12681293
String headerName = headerLine.substring(0, headerLine.indexOf(':'));
@@ -1273,8 +1298,10 @@ int HTTPClient::handleHeaderResponse()
12731298
_size = headerValue.toInt();
12741299
}
12751300

1276-
if(headerName.equalsIgnoreCase("Connection")) {
1277-
_canReuse = headerValue.equalsIgnoreCase("keep-alive");
1301+
if(_canReuse && headerName.equalsIgnoreCase("Connection")) {
1302+
if(headerValue.indexOf("close") >= 0 && headerValue.indexOf("keep-alive") < 0) {
1303+
_canReuse = false;
1304+
}
12781305
}
12791306

12801307
if(headerName.equalsIgnoreCase("Transfer-Encoding")) {

libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ class HTTPClient
235235
/// request handling
236236
String _host;
237237
uint16_t _port = 0;
238-
bool _reuse = false;
238+
bool _reuse = true;
239239
uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT;
240240
bool _useHTTP10 = false;
241241

0 commit comments

Comments
 (0)
0