diff --git a/cores/esp8266/Arduino.h b/cores/esp8266/Arduino.h index 0a16645d22..c27259c4a9 100644 --- a/cores/esp8266/Arduino.h +++ b/cores/esp8266/Arduino.h @@ -177,11 +177,6 @@ void analogWriteFreq(uint32_t freq); void analogWriteResolution(int res); void analogWriteRange(uint32_t range); -unsigned long millis(void); -unsigned long micros(void); -uint64_t micros64(void); -void delay(unsigned long); -void delayMicroseconds(unsigned int us); unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout); unsigned long pulseInLong(uint8_t pin, uint8_t state, unsigned long timeout); diff --git a/cores/esp8266/Crypto.cpp b/cores/esp8266/Crypto.cpp index ae396b7d0b..6f9009d56d 100644 --- a/cores/esp8266/Crypto.cpp +++ b/cores/esp8266/Crypto.cpp @@ -100,6 +100,7 @@ void *createBearsslHmac(const br_hash_class *hashType, const void *data, const s String createBearsslHmac(const br_hash_class *hashType, const uint8_t hashTypeNaturalLength, const String &message, const void *hashKey, const size_t hashKeyLength, const size_t hmacLength) { + (void) hashTypeNaturalLength; assert(1 <= hmacLength && hmacLength <= hashTypeNaturalLength); uint8_t hmac[hmacLength]; @@ -152,6 +153,7 @@ void *createBearsslHmacCT(const br_hash_class *hashType, const void *data, const String createBearsslHmacCT(const br_hash_class *hashType, const uint8_t hashTypeNaturalLength, const String &message, const void *hashKey, const size_t hashKeyLength, const size_t hmacLength) { + (void) hashTypeNaturalLength; assert(1 <= hmacLength && hmacLength <= hashTypeNaturalLength); uint8_t hmac[hmacLength]; diff --git a/cores/esp8266/Esp.cpp b/cores/esp8266/Esp.cpp index 1127eef80e..80d969e40c 100644 --- a/cores/esp8266/Esp.cpp +++ b/cores/esp8266/Esp.cpp @@ -697,15 +697,16 @@ static SpiFlashOpResult spi_flash_write_puya(uint32_t offset, uint32_t *data, si } else { bytesLeft = 0; } - rc = spi_flash_read(pos, flash_write_puya_buf, bytesNow); + size_t bytesAligned = (bytesNow + 3) & ~3; + rc = spi_flash_read(pos, flash_write_puya_buf, bytesAligned); if (rc != SPI_FLASH_RESULT_OK) { return rc; } - for (size_t i = 0; i < bytesNow / 4; ++i) { + for (size_t i = 0; i < bytesAligned / 4; ++i) { flash_write_puya_buf[i] &= *ptr; ++ptr; } - rc = spi_flash_write(pos, flash_write_puya_buf, bytesNow); + rc = spi_flash_write(pos, flash_write_puya_buf, bytesAligned); pos += bytesNow; } return rc; diff --git a/cores/esp8266/Esp.h b/cores/esp8266/Esp.h index 4ad59e2237..b3e187fc52 100644 --- a/cores/esp8266/Esp.h +++ b/cores/esp8266/Esp.h @@ -124,10 +124,13 @@ class EspClass { #if defined(F_CPU) || defined(CORE_MOCK) constexpr uint8_t getCpuFreqMHz() const { - return clockCyclesPerMicrosecond(); + return esp_get_cpu_freq_mhz(); } #else - uint8_t getCpuFreqMHz(); + uint8_t getCpuFreqMHz() const + { + return esp_get_cpu_freq_mhz(); + } #endif uint32_t getFlashChipId(); diff --git a/cores/esp8266/HardwareSerial.cpp b/cores/esp8266/HardwareSerial.cpp index 5f7ea141c0..26383dd43e 100644 --- a/cores/esp8266/HardwareSerial.cpp +++ b/cores/esp8266/HardwareSerial.cpp @@ -32,6 +32,14 @@ #include "HardwareSerial.h" #include "Esp.h" + +// SerialEvent functions are weak, so when the user doesn't define them, +// the linker just sets their address to 0 (which is checked below). +// The Serialx_available is just a wrapper around Serialx.available(), +// but we can refer to it weakly so we don't pull in the entire +// HardwareSerial instance if the user doesn't also refer to it. +void serialEvent() __attribute__((weak)); + HardwareSerial::HardwareSerial(int uart_nr) : _uart_nr(uart_nr), _rx_size(256) {} @@ -162,6 +170,14 @@ size_t HardwareSerial::readBytes(char* buffer, size_t size) #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL) HardwareSerial Serial(UART0); + +// Executed at end of loop() processing when > 0 bytes available in the Serial port +void serialEventRun(void) +{ + if (serialEvent && Serial.available()) { + serialEvent(); + } +} #endif #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL1) HardwareSerial Serial1(UART1); diff --git a/cores/esp8266/HardwareSerial.h b/cores/esp8266/HardwareSerial.h index dd12e96d25..6b89f68007 100644 --- a/cores/esp8266/HardwareSerial.h +++ b/cores/esp8266/HardwareSerial.h @@ -207,4 +207,6 @@ class HardwareSerial: public Stream extern HardwareSerial Serial; extern HardwareSerial Serial1; +extern void serialEventRun(void) __attribute__((weak)); + #endif diff --git a/cores/esp8266/PolledTimeout.h b/cores/esp8266/PolledTimeout.h index 715564a8e7..7eec547e48 100644 --- a/cores/esp8266/PolledTimeout.h +++ b/cores/esp8266/PolledTimeout.h @@ -4,7 +4,7 @@ /* PolledTimeout.h - Encapsulation of a polled Timeout - + Copyright (c) 2018 Daniel Salazar. All rights reserved. This file is part of the esp8266 core for Arduino environment. @@ -23,9 +23,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include - -#include +#include // IRAM_ATTR +#include // std::numeric_limits +#include // std::is_unsigned +#include namespace esp8266 { @@ -70,13 +71,13 @@ struct TimeSourceMillis struct TimeSourceCycles { - // time policy based on ESP.getCycleCount() + // time policy based on esp_get_cycle_count() // this particular time measurement is intended to be called very often // (every loop, every yield) - using timeType = decltype(ESP.getCycleCount()); - static timeType time() {return ESP.getCycleCount();} - static constexpr timeType ticksPerSecond = ESP.getCpuFreqMHz() * 1000000UL; // 80'000'000 or 160'000'000 Hz + using timeType = decltype(esp_get_cycle_count()); + static timeType time() {return esp_get_cycle_count();} + static constexpr timeType ticksPerSecond = esp_get_cpu_freq_mhz() * 1000000UL; // 80'000'000 or 160'000'000 Hz static constexpr timeType ticksPerSecondMax = 160000000; // 160MHz }; @@ -161,13 +162,13 @@ class timeoutTemplate return expiredRetrigger(); return expiredOneShot(); } - + IRAM_ATTR // fast operator bool() { - return expired(); + return expired(); } - + bool canExpire () const { return !_neverExpires; @@ -178,6 +179,7 @@ class timeoutTemplate return _timeout != alwaysExpired; } + // Resets, will trigger after this new timeout. IRAM_ATTR // called from ISR void reset(const timeType newUserTimeout) { @@ -186,12 +188,30 @@ class timeoutTemplate _neverExpires = (newUserTimeout < 0) || (newUserTimeout > timeMax()); } + // Resets, will trigger after the timeout previously set. IRAM_ATTR // called from ISR void reset() { _start = TimePolicyT::time(); } + // Resets to just expired so that on next poll the check will immediately trigger for the user, + // also change timeout (after next immediate trigger). + IRAM_ATTR // called from ISR + void resetAndSetExpired (const timeType newUserTimeout) + { + reset(newUserTimeout); + _start -= _timeout; + } + + // Resets to just expired so that on next poll the check will immediately trigger for the user. + IRAM_ATTR // called from ISR + void resetAndSetExpired () + { + reset(); + _start -= _timeout; + } + void resetToNeverExpires () { _timeout = alwaysExpired + 1; // because canWait() has precedence @@ -202,7 +222,7 @@ class timeoutTemplate { return TimePolicyT::toUserUnit(_timeout); } - + static constexpr timeType timeMax() { return TimePolicyT::timeMax; @@ -235,14 +255,14 @@ class timeoutTemplate } return false; } - + IRAM_ATTR // fast bool expiredOneShot() const { // returns "always expired" or "has expired" return !canWait() || checkExpired(TimePolicyT::time()); } - + timeType _timeout; timeType _start; bool _neverExpires; @@ -259,14 +279,14 @@ using periodic = polledTimeout::timeoutTemplate /*__attribute__((deprecate using oneShotMs = polledTimeout::timeoutTemplate; using periodicMs = polledTimeout::timeoutTemplate; -// Time policy based on ESP.getCycleCount(), and intended to be called very often: +// Time policy based on esp_get_cycle_count(), and intended to be called very often: // "Fast" versions sacrifices time range for improved precision and reduced execution time (by 86%) -// (cpu cycles for ::expired(): 372 (millis()) vs 52 (ESP.getCycleCount())) +// (cpu cycles for ::expired(): 372 (millis()) vs 52 (esp_get_cycle_count())) // timeMax() values: // Ms: max is 26843 ms (26.8 s) // Us: max is 26843545 us (26.8 s) // Ns: max is 1073741823 ns ( 1.07 s) -// (time policy based on ESP.getCycleCount() is intended to be called very often) +// (time policy based on esp_get_cycle_count() is intended to be called very often) using oneShotFastMs = polledTimeout::timeoutTemplate; using periodicFastMs = polledTimeout::timeoutTemplate; diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index 03bc5c3f8f..e5224e3814 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -113,6 +113,8 @@ bool UpdaterClass::begin(size_t size, int command, int ledPin, uint8_t ledOn) { _reset(); clearError(); // _error = 0 + _target_md5 = emptyString; + _md5 = MD5Builder(); #ifndef HOST_MOCK wifi_set_sleep_type(NONE_SLEEP_T); diff --git a/cores/esp8266/base64.h b/cores/esp8266/base64.h index 20f00f81fd..49a6cdfb01 100644 --- a/cores/esp8266/base64.h +++ b/cores/esp8266/base64.h @@ -25,6 +25,8 @@ #ifndef CORE_BASE64_H_ #define CORE_BASE64_H_ +#include + class base64 { public: diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h index 5a2893a6ed..6d6edf0303 100644 --- a/cores/esp8266/core_esp8266_features.h +++ b/cores/esp8266/core_esp8266_features.h @@ -123,6 +123,29 @@ extern "C" { #endif void precache(void *f, uint32_t bytes); +unsigned long millis(void); +unsigned long micros(void); +uint64_t micros64(void); +void delay(unsigned long); +void delayMicroseconds(unsigned int us); + +#if defined(F_CPU) || defined(CORE_MOCK) +#ifdef __cplusplus +constexpr +#else +inline +#endif +int esp_get_cpu_freq_mhz() +{ + return F_CPU / 1000000L; +} +#else +inline int esp_get_cpu_freq_mhz() +{ + return system_get_cpu_freq(); +} +#endif + #ifdef __cplusplus } diff --git a/cores/esp8266/core_esp8266_main.cpp b/cores/esp8266/core_esp8266_main.cpp index 337686199d..21724e2eb4 100644 --- a/cores/esp8266/core_esp8266_main.cpp +++ b/cores/esp8266/core_esp8266_main.cpp @@ -195,6 +195,9 @@ static void loop_wrapper() { } loop(); loop_end(); + if (serialEventRun) { + serialEventRun(); + } esp_schedule(); } diff --git a/cores/esp8266/core_esp8266_postmortem.cpp b/cores/esp8266/core_esp8266_postmortem.cpp index db0b95ff22..f79ebace85 100644 --- a/cores/esp8266/core_esp8266_postmortem.cpp +++ b/cores/esp8266/core_esp8266_postmortem.cpp @@ -144,8 +144,11 @@ void __wrap_system_restart_local() { ets_printf_P(PSTR("\nAbort called\n")); } else if (rst_info.reason == REASON_EXCEPTION_RST) { + // The GCC divide routine in ROM jumps to the address below and executes ILL (00 00 00) on div-by-zero + // In that case, print the exception as (6) which is IntegerDivZero + bool div_zero = (rst_info.exccause == 0) && (rst_info.epc1 == 0x4000dce5); ets_printf_P(PSTR("\nException (%d):\nepc1=0x%08x epc2=0x%08x epc3=0x%08x excvaddr=0x%08x depc=0x%08x\n"), - rst_info.exccause, rst_info.epc1, rst_info.epc2, rst_info.epc3, rst_info.excvaddr, rst_info.depc); + div_zero ? 6 : rst_info.exccause, rst_info.epc1, rst_info.epc2, rst_info.epc3, rst_info.excvaddr, rst_info.depc); } else if (rst_info.reason == REASON_SOFT_WDT_RST) { ets_printf_P(PSTR("\nSoft WDT reset\n")); diff --git a/doc/boards.rst b/doc/boards.rst index 9c94b63120..73cc64f158 100644 --- a/doc/boards.rst +++ b/doc/boards.rst @@ -476,6 +476,6 @@ DOIT ESP-Mx DevKit (ESP8285) ---------------------------- DOIT ESP-Mx DevKit - This is a development board by DOIT, with a DOIT ESP-Mx module (`datasheet `__) using a ESP8285 Chip. With the DOIT ESP-Mx module, GPIO pins 9 and 10 are not available. The DOIT ESP-Mx DevKit board has a red power LED and a blue LED connected to GPIO16 and is active low to turn on. It uses a CH340C, USB to Serial converter chip. -ESP8285 (`datasheet `__) is a multi-chip package which contains ESP8266 and 1MB flash. +ESP8285 (`datasheet `__) is a multi-chip package which contains ESP8266 and 1MB flash. diff --git a/doc/esp8266wifi/bearssl-client-secure-class.rst b/doc/esp8266wifi/bearssl-client-secure-class.rst index b145e68a05..a8fb367e21 100644 --- a/doc/esp8266wifi/bearssl-client-secure-class.rst +++ b/doc/esp8266wifi/bearssl-client-secure-class.rst @@ -139,7 +139,7 @@ setFingerprint(const uint8_t fp[20]) / setFingerprint(const char \*fpStr) Verify the SHA1 fingerprint of the certificate returned matches this one. If the server certificate changes, it will fail. If an array of 20 bytes are sent in, it is assumed they are the binary SHA1 values. If a `char*` string is passed in, it is parsed as a series of human-readable hex values separated by spaces or colons (e.g. `setFingerprint("00:01:02:03:...:1f");`) -This fingerprint is calcuated on the raw X509 certificate served by the server. In very rare cases, these certificates have certain encodings which should be normalized before taking a fingerprint (but in order to preserve memory BearSSL does not do this normalization since it would need RAM for an entire copy of the cert), and the fingerprint BearSSL calculates will not match the fingerprint OpenSSL calculates. In this case, you can enable SSL debugging and get a dump of BearSSL's calculated fingerprint and use that one in your code, or use full certificate validation. See the `original issue and debug here `__. +This fingerprint is calculated on the raw X509 certificate served by the server. In very rare cases, these certificates have certain encodings which should be normalized before taking a fingerprint (but in order to preserve memory BearSSL does not do this normalization since it would need RAM for an entire copy of the cert), and the fingerprint BearSSL calculates will not match the fingerprint OpenSSL calculates. In this case, you can enable SSL debugging and get a dump of BearSSL's calculated fingerprint and use that one in your code, or use full certificate validation. See the `original issue and debug here `__. setTrustAnchors(BearSSL::X509List \*ta) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/esp8266wifi/client-class.rst b/doc/esp8266wifi/client-class.rst index dee85589a1..11e412181e 100644 --- a/doc/esp8266wifi/client-class.rst +++ b/doc/esp8266wifi/client-class.rst @@ -61,7 +61,7 @@ In this mode, every ``write()`` is flushed. It means that after a call to When set to ``true`` in ``WiFiClient`` implementation, -- It slows down transfers, and implicitely disable the Nagle algorithm. +- It slows down transfers, and implicitly disable the Nagle algorithm. - It also allows to avoid a temporary copy of data that otherwise consumes at most ``TCP_SND_BUF`` = (2 * ``MSS``) bytes per connection, diff --git a/doc/esp8266wifi/scan-class.rst b/doc/esp8266wifi/scan-class.rst index d2998a6e66..eb94de8aad 100644 --- a/doc/esp8266wifi/scan-class.rst +++ b/doc/esp8266wifi/scan-class.rst @@ -191,7 +191,7 @@ Return information if a network discovered during the scan is hidden or not. WiFi.isHidden(networkItem) -Returned value if the ``bolean`` type, and ``true`` means that network is hidden. The ``networkItem`` is a zero based index of network discovered during scan. +Returned value if the ``boolean`` type, and ``true`` means that network is hidden. The ``networkItem`` is a zero based index of network discovered during scan. getNetworkInfo ^^^^^^^^^^^^^^ diff --git a/doc/esp8266wifi/scan-examples.rst b/doc/esp8266wifi/scan-examples.rst index d4bf01e8bc..4ad4777507 100644 --- a/doc/esp8266wifi/scan-examples.rst +++ b/doc/esp8266wifi/scan-examples.rst @@ -206,7 +206,7 @@ Complete sketch is below. The code inside ``setup()`` is the same as described i lastScanMillis = currentMillis; } - // print out Wi-Fi network scan result uppon completion + // print out Wi-Fi network scan result upon completion int n = WiFi.scanComplete(); if(n >= 0) { diff --git a/doc/esp8266wifi/server-examples.rst b/doc/esp8266wifi/server-examples.rst index cf5ad51b84..fd8ad7d9c6 100644 --- a/doc/esp8266wifi/server-examples.rst +++ b/doc/esp8266wifi/server-examples.rst @@ -204,7 +204,7 @@ Complete sketch is presented below. // close the connection: client.stop(); - Serial.println("[Client disonnected]"); + Serial.println("[Client disconnected]"); } } @@ -236,7 +236,7 @@ The page would be refreshed every 5 seconds. Each time this happens, you should Host: 192.168.1.104 DNT: 1 Connection: Keep-Alive - [client disonnected] + [client disconnected] Conclusion ~~~~~~~~~~ diff --git a/doc/faq/a01-espcomm_sync-failed.rst b/doc/faq/a01-espcomm_sync-failed.rst index 699754ecf8..a0d575e8ed 100644 --- a/doc/faq/a01-espcomm_sync-failed.rst +++ b/doc/faq/a01-espcomm_sync-failed.rst @@ -313,14 +313,14 @@ example at 921600 baud, but with two reset retries. Reset Method: nodemcu, reset retries -If you are interested how noodemcu reset method is implemented, then +If you are interested how nodemcu reset method is implemented, then check circuit below. As indicated it does not pull to ground RTS and DTR lines once you open Serial Monitor in Arduino IDE. .. figure:: pictures/a01-nodemcu-reset-implementation.png - :alt: Implementation of noodemcu reset + :alt: Implementation of nodemcu reset - Implementation of noodemcu reset + Implementation of nodemcu reset It consists of two transistors and resistors that you can locate on NodeMCU board on right. On left you can see complete circuit and the diff --git a/doc/faq/a02-my-esp-crashes.rst b/doc/faq/a02-my-esp-crashes.rst index 838880ea87..aeedc8d5e2 100644 --- a/doc/faq/a02-my-esp-crashes.rst +++ b/doc/faq/a02-my-esp-crashes.rst @@ -187,7 +187,7 @@ If you don't have any code for troubleshooting, use the example below: Serial.println(); Serial.println("Let's provoke the s/w wdt firing..."); // - // provoke an OOM, will be recorded as the last occured one + // provoke an OOM, will be recorded as the last occurred one char* out_of_memory_failure = (char*)malloc(1000000); // // wait for s/w wdt in infinite loop below @@ -310,11 +310,11 @@ Memory, memory, memory * If you use std libs like std::vector, make sure to call its ::reserve() method before filling it. This allows allocating only once, which reduces mem fragmentation, and makes sure that there are no empty unused slots left over in the container at the end. Stack -   The amount of stack in the ESP is tiny at only 4KB. For normal developement in large systems, it +   The amount of stack in the ESP is tiny at only 4KB. For normal development in large systems, it is good practice to use and abuse the stack, because it is faster for allocation/deallocation, the scope of the object is well defined, and deallocation automatically happens in reverse order as allocation, which means no mem fragmentation. However, with the tiny amount of stack available in the ESP, that practice is not really viable, at least not for big objects. * Large objects that have internally managed memory, such as String, std::string, std::vector, etc, are ok on the stack, because they internally allocate their buffers on the heap. * Large arrays on the stack, such as uint8_t buffer[2048] should be avoided on the stack and be dynamically allocated (consider smart pointers). - * Objects that have large data members, such as large arrays, should be avoided on the stack, and be dynamicaly allocated (consider smart pointers). + * Objects that have large data members, such as large arrays, should be avoided on the stack, and be dynamically allocated (consider smart pointers). If at the Wall, Enter an Issue Report diff --git a/doc/faq/a05-board-generator.rst b/doc/faq/a05-board-generator.rst index 1e260fa3c3..279491355e 100644 --- a/doc/faq/a05-board-generator.rst +++ b/doc/faq/a05-board-generator.rst @@ -129,7 +129,7 @@ Additional Notes: 1. The boards.txt file will always contain the generic and esp8285 boards. -2. If boards.txt file exist and no backup copy named boards.txt.orig exist, the current boards.txt will be renamed to boards.txt.orig. Otherwise, the existing boards.txt is over-writen when you generate a new boards.txt file. Similar behavior for when generating a new boards.local.txt. +2. If boards.txt file exist and no backup copy named boards.txt.orig exist, the current boards.txt will be renamed to boards.txt.orig. Otherwise, the existing boards.txt is over-written when you generate a new boards.txt file. Similar behavior for when generating a new boards.local.txt. 3. The boards in the boards.txt file will be in the order they were listed in your favorites file, specified by option ``--filter ``. diff --git a/doc/faq/readme.rst b/doc/faq/readme.rst index cbfbdb270a..74e2211966 100644 --- a/doc/faq/readme.rst +++ b/doc/faq/readme.rst @@ -55,7 +55,7 @@ How can I get some extra KBs in flash ? About WPS ~~~~~~~~~ -From release 2.4.2 and ahead, not using WPS will give an exra ~4.5KB in +From release 2.4.2 and ahead, not using WPS will give an extra ~4.5KB in heap. In release 2.4.2 only, WPS is disabled by default and the board generator is diff --git a/doc/reference.rst b/doc/reference.rst index 6cb03d6928..9551d9d035 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -113,7 +113,7 @@ or ``bits`` may be from 4...16. 3.0, but this lead to incompatibility with external libraries which depended on the Arduino core default of 256. Existing applications which rely on the prior 1023 value may add a call to ``analogWriteRange(1023)`` -to their ``setup()`` routine to retrurn to their old behavior. Applications +to their ``setup()`` routine to return to their old behavior. Applications which already were calling ``analogWriteRange`` need no change. PWM frequency is 1kHz by default. Call @@ -151,12 +151,31 @@ milliseconds is not recommended. Serial ------ -``Serial`` object works much the same way as on a regular Arduino. Apart -from hardware FIFO (128 bytes for TX and RX) ``Serial`` has -additional 256-byte TX and RX buffers. Both transmit and receive is -interrupt-driven. Write and read functions only block the sketch -execution when the respective FIFO/buffers are full/empty. Note that -the length of additional 256-bit buffer can be customized. +The ``Serial`` object works much the same way as on a regular Arduino. Apart +from the hardware FIFO (128 bytes for TX and RX), ``Serial`` has an +additional customizable 256-byte RX buffer. The size of this software buffer can +be changed by the user. It is suggested to use a bigger size at higher receive speeds. + +The ``::setRxBufferSize(size_t size)`` method changes the RX buffer size as needed. This +should be called before ``::begin()``. The size argument should be at least large enough +to hold all data received before reading. + +For transmit-only operation, the 256-byte RX buffer can be switched off to save RAM by +passing mode SERIAL_TX_ONLY to Serial.begin(). Other modes are SERIAL_RX_ONLY and +SERIAL_FULL (the default). + +Receive is interrupt-driven, but transmit polls and busy-waits. Blocking behavior is as follows: +The ``::write()`` call does not block if the number of bytes fits in the current space available +in the TX FIFO. The call blocks if the TX FIFO is full and waits until there is room before +writing more bytes into it, until all bytes are written. In other words, when the call returns, +all bytes have been written to the TX FIFO, but that doesn't mean that all bytes have been sent +out through the serial line yet. +The ``::read()`` call doesn't block, not even if there are no bytes available for reading. +The ``::readBytes()`` call blocks until the number of bytes read complies with the number of +bytes required by the argument passed in. +The ``::flush()`` call blocks waiting for the TX FIFO to be empty before returning. It is +recommended to call this to make sure all bytes have been sent before doing configuration changes +on the serial port (e.g. changing baudrate) or doing a board reset. ``Serial`` uses UART0, which is mapped to pins GPIO1 (TX) and GPIO3 (RX). Serial may be remapped to GPIO15 (TX) and GPIO13 (RX) by calling @@ -180,14 +199,13 @@ instead, call ``Serial1.setDebugOutput(true)``. You also need to use ``Serial.setDebugOutput(true)`` to enable output from ``printf()`` function. -The method ``Serial.setRxBufferSize(size_t size)`` allows to define the -receiving buffer depth. The default value is 256. - Both ``Serial`` and ``Serial1`` objects support 5, 6, 7, 8 data bits, odd (O), even (E), and no (N) parity, and 1 or 2 stop bits. To set the desired mode, call ``Serial.begin(baudrate, SERIAL_8N1)``, ``Serial.begin(baudrate, SERIAL_6E2)``, etc. - +Default configuration mode is SERIAL_8N1. Possibilities are SERIAL_[5678][NEO][12]. +Example: ``SERIAL_8N1`` means 8bits No parity 1 stop bit. + A new method has been implemented on both ``Serial`` and ``Serial1`` to get current baud rate setting. To get the current baud rate, call ``Serial.baudRate()``, ``Serial1.baudRate()``. Return a ``int`` of @@ -206,7 +224,7 @@ current speed. For example | ``Serial`` and ``Serial1`` objects are both instances of the ``HardwareSerial`` class. -| I've done this also for official ESP8266 `Software +| This is also done for official ESP8266 `Software Serial `__ library, see this `pull request `__. @@ -229,12 +247,17 @@ Progmem The Program memory features work much the same way as on a regular Arduino; placing read only data and strings in read only memory and -freeing heap for your application. The important difference is that on -the ESP8266 the literal strings are not pooled. This means that the same -literal string defined inside a ``F("")`` and/or ``PSTR("")`` will take -up space for each instance in the code. So you will need to manage the +freeing heap for your application. + +In core versions prior to 2.7, the important difference is that on the +ESP8266 the literal strings are not pooled. This means that the same +literal string defined inside a ``F("")`` and/or ``PSTR("")`` will take up +space for each instance in the code. So you will need to manage the duplicate strings yourself. +Starting from v2.7, this is no longer true: duplicate literal strings within +r/o memory are now handled. + There is one additional helper macro to make it easier to pass ``const PROGMEM`` strings to methods that take a ``__FlashStringHelper`` called ``FPSTR()``. The use of this will help make it easier to pool diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 941be0b718..3d1a478d26 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -50,6 +50,8 @@ enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END, enum HTTPClientStatus { HC_NONE, HC_WAIT_READ, HC_WAIT_CLOSE }; enum HTTPAuthMethod { BASIC_AUTH, DIGEST_AUTH }; +#define WEBSERVER_HAS_HOOK 1 + #define HTTP_DOWNLOAD_UNIT_SIZE 1460 #ifndef HTTP_UPLOAD_BUFLEN diff --git a/libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py b/libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py index 556acb70fa..68881c709c 100755 --- a/libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py +++ b/libraries/ESP8266WiFi/examples/BearSSL_CertStore/certs-from-mozilla.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 # This script pulls the list of Mozilla trusted certificate authorities # from the web at the "mozurl" below, parses the file to grab the PEM @@ -14,11 +14,11 @@ from subprocess import Popen, PIPE, call try: from urllib.request import urlopen -except: +except Exception: from urllib2 import urlopen try: from StringIO import StringIO -except: +except Exception: from io import StringIO # Mozilla's URL for the CSV file with included PEM certs @@ -42,7 +42,7 @@ # Try and make ./data, skip if present try: os.mkdir("data") -except: +except Exception: pass derFiles = [] diff --git a/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino b/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino index 9e333fbcec..ef9016063b 100644 --- a/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino +++ b/libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient.ino @@ -44,6 +44,8 @@ void setup() { } void loop() { + static bool wait = false; + Serial.print("connecting to "); Serial.print(host); Serial.print(':'); @@ -87,5 +89,8 @@ void loop() { Serial.println("closing connection"); client.stop(); - delay(300000); // execute once every 5 minutes, don't flood remote service + if (wait) { + delay(300000); // execute once every 5 minutes, don't flood remote service + } + wait = true; } diff --git a/libraries/ESP8266httpUpdate/keywords.txt b/libraries/ESP8266httpUpdate/keywords.txt index 78be600d42..1c5b9f9588 100644 --- a/libraries/ESP8266httpUpdate/keywords.txt +++ b/libraries/ESP8266httpUpdate/keywords.txt @@ -24,6 +24,7 @@ update KEYWORD2 updateSpiffs KEYWORD2 getLastError KEYWORD2 getLastErrorString KEYWORD2 +setAuthorization KEYWORD2 ####################################### # Constants (LITERAL1) @@ -37,6 +38,7 @@ HTTP_UE_SERVER_WRONG_HTTP_CODE LITERAL1 RESERVED_WORD_2 HTTP_UE_SERVER_FAULTY_MD5 LITERAL1 RESERVED_WORD_2 HTTP_UE_BIN_VERIFY_HEADER_FAILED LITERAL1 RESERVED_WORD_2 HTTP_UE_BIN_FOR_WRONG_FLASH LITERAL1 RESERVED_WORD_2 +HTTP_UE_SERVER_UNAUTHORIZED LITERAL1 RESERVED_WORD_2 HTTP_UPDATE_FAILED LITERAL1 RESERVED_WORD_2 HTTP_UPDATE_NO_UPDATES LITERAL1 RESERVED_WORD_2 HTTP_UPDATE_OK LITERAL1 RESERVED_WORD_2 diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp index f481d79a69..618f5eaa34 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp @@ -43,6 +43,26 @@ ESP8266HTTPUpdate::~ESP8266HTTPUpdate(void) { } +/** + * set the Authorization for the http request + * @param user const String& + * @param password const String& + */ +void ESP8266HTTPUpdate::setAuthorization(const String &user, const String &password) +{ + _user = user; + _password = password; +} + +/** + * set the Authorization for the http request + * @param auth const String& base64 + */ +void ESP8266HTTPUpdate::setAuthorization(const String &auth) +{ + _auth = auth; +} + #if HTTPUPDATE_1_2_COMPATIBLE HTTPUpdateResult ESP8266HTTPUpdate::update(const String& url, const String& currentVersion, const String& httpsFingerprint, bool reboot) @@ -241,6 +261,8 @@ String ESP8266HTTPUpdate::getLastErrorString(void) return F("Verify Bin Header Failed"); case HTTP_UE_BIN_FOR_WRONG_FLASH: return F("New Binary Does Not Fit Flash Size"); + case HTTP_UE_SERVER_UNAUTHORIZED: + return F("Unauthorized (401)"); } return String(); @@ -282,6 +304,16 @@ HTTPUpdateResult ESP8266HTTPUpdate::handleUpdate(HTTPClient& http, const String& http.addHeader(F("x-ESP8266-version"), currentVersion); } + if (!_user.isEmpty() && !_password.isEmpty()) + { + http.setAuthorization(_user.c_str(), _password.c_str()); + } + + if (!_auth.isEmpty()) + { + http.setAuthorization(_auth.c_str()); + } + const char * headerkeys[] = { "x-MD5" }; size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*); @@ -432,6 +464,10 @@ HTTPUpdateResult ESP8266HTTPUpdate::handleUpdate(HTTPClient& http, const String& _setLastError(HTTP_UE_SERVER_FORBIDDEN); ret = HTTP_UPDATE_FAILED; break; + case HTTP_CODE_UNAUTHORIZED: + _setLastError(HTTP_UE_SERVER_UNAUTHORIZED); + ret = HTTP_UPDATE_FAILED; + break; default: _setLastError(HTTP_UE_SERVER_WRONG_HTTP_CODE); ret = HTTP_UPDATE_FAILED; diff --git a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h index f1565cd2c6..e8e7221526 100755 --- a/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h +++ b/libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.h @@ -56,6 +56,7 @@ constexpr int HTTP_UE_SERVER_WRONG_HTTP_CODE = (-104); constexpr int HTTP_UE_SERVER_FAULTY_MD5 = (-105); constexpr int HTTP_UE_BIN_VERIFY_HEADER_FAILED = (-106); constexpr int HTTP_UE_BIN_FOR_WRONG_FLASH = (-107); +constexpr int HTTP_UE_SERVER_UNAUTHORIZED = (-108); enum HTTPUpdateResult { HTTP_UPDATE_FAILED, @@ -111,6 +112,9 @@ class ESP8266HTTPUpdate _ledOn = ledOn; } + void setAuthorization(const String& user, const String& password); + void setAuthorization(const String& auth); + #if HTTPUPDATE_1_2_COMPATIBLE // This function is deprecated, use rebootOnUpdate and the next one instead t_httpUpdate_return update(const String& url, const String& currentVersion, @@ -174,6 +178,10 @@ class ESP8266HTTPUpdate int _lastError; bool _rebootOnUpdate = true; bool _closeConnectionsOnUpdate = true; + String _user; + String _password; + String _auth; + private: int _httpClientTimeout; followRedirects_t _followRedirects; diff --git a/package/upload_release.py b/package/upload_release.py old mode 100644 new mode 100755 index 20390c2b11..9f547f99db --- a/package/upload_release.py +++ b/package/upload_release.py @@ -2,11 +2,6 @@ from github import Github import argparse -import collections -import glob -import json -import mimetypes -import os parser = argparse.ArgumentParser(description='Upload a set of files to a new draft release') parser.add_argument('--user', help="Github username", type=str, required=True) diff --git a/tests/ci/host_test.sh b/tests/ci/host_test.sh index e20e23b331..ef143f90e1 100755 --- a/tests/ci/host_test.sh +++ b/tests/ci/host_test.sh @@ -6,5 +6,18 @@ set -ev cd $TRAVIS_BUILD_DIR/tests/host -make CI + +make -j2 FORCE32=0 ssl +for i in ../../libraries/ESP8266WiFi/examples/WiFiClient/WiFiClient \ + ../../libraries/ESP8266WiFi/examples/BearSSL_Validation/BearSSL_Validation \ + ../../libraries/ESP8266WebServer/examples/HelloServer/HelloServer \ + ../../libraries/SD/examples/Files/Files \ + ../../libraries/LittleFS/examples/LittleFS_Timestamp/LittleFS_Timestamp \ + ../../libraries/LittleFS/examples/SpeedTest/SpeedTest ; do + make -j2 D=1 FORCE32=0 $i + valgrind --leak-check=full --track-origins=yes --error-limit=no --show-leak-kinds=all --error-exitcode=999 bin/$(basename $i)/$(basename $i) -1 +done + +make -j2 CI + make clean-objects diff --git a/tests/host/common/ArduinoMain.cpp b/tests/host/common/ArduinoMain.cpp index fd7bd0a04a..a9d8d696f6 100644 --- a/tests/host/common/ArduinoMain.cpp +++ b/tests/host/common/ArduinoMain.cpp @@ -42,6 +42,7 @@ #define MOCK_PORT_SHIFTER 9000 bool user_exit = false; +bool run_once = false; const char* host_interface = nullptr; size_t spiffs_kb = 1024; size_t littlefs_kb = 1024; @@ -137,6 +138,7 @@ void help (const char* argv0, int exitcode) "\tgeneral:\n" "\t-c - ignore CTRL-C (send it via Serial)\n" "\t-f - no throttle (possibly 100%%CPU)\n" + "\t-1 - run loop once then exit (for host testing)\n" "\t-v - verbose\n" , argv0, MOCK_PORT_SHIFTER, argv0, spiffs_kb, littlefs_kb); exit(exitcode); @@ -152,10 +154,11 @@ static struct option options[] = { "verbose", no_argument, NULL, 'v' }, { "timestamp", no_argument, NULL, 'T' }, { "interface", required_argument, NULL, 'i' }, - { "fspath", required_argument, NULL, 'P' }, + { "fspath", required_argument, NULL, 'P' }, { "spiffskb", required_argument, NULL, 'S' }, { "littlefskb", required_argument, NULL, 'L' }, { "portshifter", required_argument, NULL, 's' }, + { "once", no_argument, NULL, '1' }, }; void cleanup () @@ -209,7 +212,7 @@ int main (int argc, char* const argv []) for (;;) { - int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:", options, NULL); + int n = getopt_long(argc, argv, "hlcfbvTi:S:s:L:P:1", options, NULL); if (n < 0) break; switch (n) @@ -250,6 +253,9 @@ int main (int argc, char* const argv []) case 'T': serial_timestamp = true; break; + case '1': + run_once = true; + break; default: help(argv[0], EXIT_FAILURE); } @@ -300,6 +306,9 @@ int main (int argc, char* const argv []) usleep(1000); // not 100% cpu, ~1000 loops per second loop(); check_incoming_udp(); + + if (run_once) + user_exit = true; } cleanup(); diff --git a/tests/host/common/MockEsp.cpp b/tests/host/common/MockEsp.cpp index 5d2289a5f3..2045523e82 100644 --- a/tests/host/common/MockEsp.cpp +++ b/tests/host/common/MockEsp.cpp @@ -208,7 +208,7 @@ uint32_t EspClass::getFlashChipSize(void) String EspClass::getFullVersion () { - return "host-emulation"; + return "emulation-on-host"; } uint32_t EspClass::getFreeContStack() @@ -221,6 +221,11 @@ void EspClass::resetFreeContStack() } uint32_t EspClass::getCycleCount() +{ + return esp_get_cycle_count(); +} + +uint32_t esp_get_cycle_count() { timeval t; gettimeofday(&t, NULL); diff --git a/tests/host/common/mock.h b/tests/host/common/mock.h index 4032d88933..eff32dd46a 100644 --- a/tests/host/common/mock.h +++ b/tests/host/common/mock.h @@ -31,6 +31,29 @@ #define CORE_MOCK 1 +// + +#define ARDUINO 267 +#define ESP8266 1 +#define A0 0 +#define LED_BUILTIN 0 +#define F_CPU 80000000 +#define LWIP_OPEN_SRC +#define TCP_MSS 536 +#define LWIP_FEATURES 1 + +// + +#define D0 0 +#define D1 1 +#define D2 3 +#define D3 3 +#define D4 4 +#define D5 5 +#define D6 6 +#define D7 7 +#define D8 8 + // include host's STL before any other include file // because core definition like max() is in the way @@ -61,28 +84,10 @@ typedef uint32_t uint32; // -#define ARDUINO 267 -#define ESP8266 1 -#define A0 0 -#define LED_BUILTIN 0 -#define F_CPU 80000000 -#define LWIP_OPEN_SRC -#define TCP_MSS 536 -#define LWIP_FEATURES 1 - -// - -#define D0 0 -#define D1 1 -#define D2 3 -#define D3 3 -#define D4 4 -#define D5 5 -#define D6 6 -#define D7 7 -#define D8 8 +#include +#include -// +uint32_t esp_get_cycle_count(); #include diff --git a/tests/platformio.sh b/tests/platformio.sh index 7e834fb6de..2aa81a656a 100755 --- a/tests/platformio.sh +++ b/tests/platformio.sh @@ -6,10 +6,10 @@ source "$TRAVIS_BUILD_DIR"/tests/common.sh function install_platformio() { - pip3 install --user -U https://github.com/platformio/platformio/archive/develop.zip + pip3 install -U platformio platformio platform install "https://github.com/platformio/platform-espressif8266.git" # Overwrite toolchain with this PR's toolset. Probably better way to do this - ( cd $TRAVIS_BUILD_DIR/tools && python3 get.py ) + ( cd $TRAVIS_BUILD_DIR/tools && python3 get.py -q ) mv ~/.platformio/packages/toolchain-xtensa/package.json .save rm -rf ~/.platformio/packages/toolchain-xtensa mv $TRAVIS_BUILD_DIR/tools/xtensa-lx106-elf ~/.platformio/packages/toolchain-xtensa diff --git a/tools/boards.txt.py b/tools/boards.txt.py index 789f75714c..7be8f695dc 100755 --- a/tools/boards.txt.py +++ b/tools/boards.txt.py @@ -907,23 +907,23 @@ '1M', ], 'desc': [ - 'ESP8266 based devices from ITEAD: Sonoff SV, Sonoff TH, Sonoff Basic, ' + 'ESP8266 based devices from ITEAD: Sonoff SV, Sonoff TH, Sonoff Basic, ' + 'and Sonoff S20', '', - 'These are not development boards. The development process is ' - 'inconvenient with these devices. When flashing firmware you will ' + 'These are not development boards. The development process is ' + + 'inconvenient with these devices. When flashing firmware you will ' + 'need a Serial Adapter to connect it to your computer.', '', - ' | Most of these devices, during normal operation, are connected to ' - '*wall power (AKA Mains Electricity)*. **NEVER** try to flash these ' - 'devices when connected to *wall power*. **ALWAYS** have them ' - 'disconnected from *wall power* when connecting them to your ' + ' | Most of these devices, during normal operation, are connected to ' + + '*wall power (AKA Mains Electricity)*. **NEVER** try to flash these ' + + 'devices when connected to *wall power*. **ALWAYS** have them ' + + 'disconnected from *wall power* when connecting them to your ' + 'computer. Your life may depend on it!', '', - 'When flashing you will need to hold down the push button connected ' - 'to the GPIO0 pin, while powering up with a safe 3.3 Volt source. Some USB ' - 'Serial Adapters may supply enough power to handle flashing; ' - 'however, it many may not supply enough power to handle the ' + 'When flashing you will need to hold down the push button connected ' + + 'to the GPIO0 pin, while powering up with a safe 3.3 Volt source. Some USB ' + + 'Serial Adapters may supply enough power to handle flashing; ' + + 'however, it many may not supply enough power to handle the ' + 'activities when the device reboots.', '', 'More product details at the bottom of https://www.itead.cc/wiki/Product/' @@ -943,15 +943,14 @@ '1M', ], 'desc': [ - 'DOIT ESP-Mx DevKit - This is a development board by DOIT, with a DOIT ESP-Mx module ' - '(`datasheet `__) ' - 'using a ESP8285 Chip. With the DOIT ESP-Mx module, GPIO pins 9 and 10 are not available. ' - 'The DOIT ESP-Mx DevKit board has a red power LED and a blue LED connected to GPIO16 ' - 'and is active low to turn on. It uses a CH340C, USB to Serial converter chip. ' - '', - 'ESP8285 (`datasheet `__) ' - 'is a multi-chip package which contains ESP8266 and 1MB flash. ', + 'DOIT ESP-Mx DevKit - This is a development board by DOIT, with a DOIT ESP-Mx module ' + + '(`datasheet `__) ' + + 'using a ESP8285 Chip. With the DOIT ESP-Mx module, GPIO pins 9 and 10 are not available. ' + + 'The DOIT ESP-Mx DevKit board has a red power LED and a blue LED connected to GPIO16 ' + + 'and is active low to turn on. It uses a CH340C, USB to Serial converter chip. ', '', + 'ESP8285 (`datasheet `__) ' + + 'is a multi-chip package which contains ESP8266 and 1MB flash. ' ], }) diff --git a/tools/elf2bin.py b/tools/elf2bin.py index 4fc407b908..ffc3a62088 100755 --- a/tools/elf2bin.py +++ b/tools/elf2bin.py @@ -57,7 +57,7 @@ def get_segment_size_addr(elf, segment, path): def read_segment(elf, segment, path): fd, tmpfile = tempfile.mkstemp() os.close(fd) - p = subprocess.check_call([path + "/xtensa-lx106-elf-objcopy", '-O', 'binary', '--only-section=' + segment, elf, tmpfile], stdout=subprocess.PIPE) + subprocess.check_call([path + "/xtensa-lx106-elf-objcopy", '-O', 'binary', '--only-section=' + segment, elf, tmpfile], stdout=subprocess.PIPE) with open(tmpfile, "rb") as f: raw = f.read() os.remove(tmpfile) @@ -85,7 +85,7 @@ def write_bin(out, args, elf, segments, to_addr): try: for data in raw: checksum = checksum ^ ord(data) - except: + except Exception: for data in raw: checksum = checksum ^ data total_size += 1 diff --git a/tools/espota.py b/tools/espota.py index d6b5a80860..fbba90d18d 100755 --- a/tools/espota.py +++ b/tools/espota.py @@ -77,7 +77,7 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm try: sock.bind(server_address) sock.listen(1) - except: + except Exception: logging.error("Listen Failed") return 1 @@ -100,11 +100,11 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm logging.info('Sending invitation to: %s', remoteAddr) sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) remote_address = (remoteAddr, int(remotePort)) - sent = sock2.sendto(message.encode(), remote_address) + sock2.sendto(message.encode(), remote_address) sock2.settimeout(10) try: data = sock2.recv(128).decode() - except: + except Exception: logging.error('No Answer') sock2.close() return 1 @@ -123,7 +123,7 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm sock2.settimeout(10) try: data = sock2.recv(32).decode() - except: + except Exception: sys.stderr.write('FAIL\n') logging.error('No Answer to our Authentication') sock2.close() @@ -147,7 +147,7 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm connection, client_address = sock.accept() sock.settimeout(None) connection.settimeout(None) - except: + except Exception: logging.error('No response from device') sock.close() return 1 @@ -173,7 +173,7 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm if connection.recv(32).decode().find('O') >= 0: # connection will receive only digits or 'OK' received_ok = True - except: + except Exception: sys.stderr.write('\n') logging.error('Error Uploading') connection.close() @@ -207,7 +207,7 @@ def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, comm if received_ok: return 0 return 1 - except: + except Exception: logging.error('No Result!') connection.close() f.close() diff --git a/tools/makecorever.py b/tools/makecorever.py index 3f1422b5d4..e7bd348686 100755 --- a/tools/makecorever.py +++ b/tools/makecorever.py @@ -32,7 +32,7 @@ def git(*args): try: git_ver = git("rev-parse", "--short=8", "HEAD") git_desc = git("describe", "--tags") - except: + except Exception: pass text = "#define ARDUINO_ESP8266_GIT_VER 0x{}\n".format(git_ver) @@ -43,7 +43,7 @@ def git(*args): old_text = inp.read() if old_text == text: return - except: + except Exception: pass with open(path, "w") as out: @@ -73,7 +73,7 @@ def git(*args): include_dir = os.path.join(args.build_path, args.include_dir) try: os.makedirs(include_dir) - except: + except Exception: pass generate( diff --git a/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h b/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h index c8c337aac9..9ba4447182 100644 --- a/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h +++ b/tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h @@ -61,42 +61,43 @@ extern "C" { // w1, w0 #define pgm_read_with_offset(addr, res) \ - __asm__("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ - "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \ - "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \ - "ssa8l %0\n" /* Prepare to shift by offset (in bits) */ \ - "src %0, %1, %1\n" /* Shift right; now the requested byte is the first one */ \ - :"=r"(res), "=r"(addr) \ - :"1"(addr) \ - :); + __asm__( \ + "extui\t%0, %1, 0, 2\n\t" /* Extract offset within word (in bytes) */ \ + "sub\t%1, %1, %0\n\t" /* Subtract offset from addr, yielding an aligned address */ \ + "l32i.n\t%1, %1, 0\n\t" /* Load word from aligned address */ \ + "ssa8l\t%0\n\t" /* Prepare to shift by offset (in bits) */ \ + "src\t%0, %1, %1" /* Shift right; now the requested byte is the first one */ \ + : "=r"(res), "+r"(addr)) #define pgm_read_dword_with_offset(addr, res) \ - __asm__("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \ - "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \ - "l32i a14, %1, 0\n" \ - "l32i %1, %1, 4\n" \ - "ssa8l %0\n" \ - "src %0, %1, a14\n" \ - :"=r"(res), "=r"(addr) \ - :"1"(addr) \ - :"a14"); + do { \ + uint32_t temp; \ + __asm__( \ + "extui\t%0, %1, 0, 2\n\t" /* Extract offset within word (in bytes) */ \ + "sub\t%1, %1, %0\n\t" /* Subtract offset from addr, yielding an aligned address */ \ + "l32i.n\t%2, %1, 0\n\t" /* Load 2 words */ \ + "l32i.n\t%1, %1, 4\n\t" /* from aligned address */ \ + "ssa8l\t%0\n\t" /* Prepare to shift by offset (in bits) */ \ + "src\t%0, %1, %2" /* Shift right in order to extract the requested dword */ \ + : "=r"(res), "+r"(addr), "=r"(temp)); \ + } while(0) static inline uint8_t pgm_read_byte_inlined(const void* addr) { uint32_t res; pgm_read_with_offset(addr, res); - return (uint8_t) res; /* This masks the lower byte from the returned word */ + return res; /* Implicit cast to uint8_t masks the lower byte from the returned word */ } /* Although this says "word", it's actually 16 bit, i.e. half word on Xtensa */ static inline uint16_t pgm_read_word_inlined(const void* addr) { uint32_t res; pgm_read_with_offset(addr, res); - return (uint16_t) res; /* This masks the lower half-word from the returned word */ + return res; /* Implicit cast to uint16_t masks the lower half-word from the returned word */ } /* Can't legally cast bits of uint32_t to a float w/o conversion or std::memcpy, which is inefficient. */ /* The ASM block doesn't care the type, so just pass in what C thinks is a float and return in custom fcn. */ -static inline float pgm_read_float_unaligned(const void *addr) { +static inline float pgm_read_float_unaligned(const void* addr) { float res; pgm_read_with_offset(addr, res); return res; @@ -121,7 +122,7 @@ static inline uint32_t pgm_read_dword_unaligned(const void *addr) { } #define pgm_read_ptr_unaligned(addr) ((void*)pgm_read_dword_unaligned(addr)) -#define pgm_read_word_unaligned(addr) ((uint16_t)(pgm_read_dword_unaligned(addr) & 0xffff)) +#define pgm_read_word_unaligned(addr) ((uint16_t)pgm_read_dword_unaligned(addr)) // Allow selection of _aligned or _unaligned, but default to _unaligned for Arduino compatibility diff --git a/tools/signing.py b/tools/signing.py index 8c58d8bbbc..8fef38a112 100755 --- a/tools/signing.py +++ b/tools/signing.py @@ -78,7 +78,6 @@ def main(): f.write(val) return 0 elif args.mode == "sign": - val = "" if not os.path.isfile(args.privatekey): return try: diff --git a/tools/upload.py b/tools/upload.py index 0d57a63c9c..48352de3a7 100755 --- a/tools/upload.py +++ b/tools/upload.py @@ -16,7 +16,7 @@ sys.path.insert(0, toolspath + "/pyserial") # Add pyserial dir to search path sys.path.insert(0, toolspath + "/esptool") # Add esptool dir to search path import esptool # If this fails, we can't continue and will bomb below -except: +except Exception: sys.stderr.write("pyserial or esptool directories not found next to this upload.py tool.\n") sys.exit(1)