8000 Merge branch 'master' into pr-dns-forwarder · esp8266/Arduino@7178c2e · GitHub
[go: up one dir, main page]

Skip to content

Commit 7178c2e

Browse files
authored
Merge branch 'master' into pr-dns-forwarder
2 parents 64a8191 + 8b662ed commit 7178c2e

File tree

107 files changed

+6053
-1102
lines changed

Some content is hidden

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

107 files changed

+6053
-1102
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Starting with 1.6.4, Arduino allows installation of third-party platform package
3030

3131
- Install the current upstream Arduino IDE at the 1.8.9 level or later. The current version is on the [Arduino website](https://www.arduino.cc/en/main/software).
3232
- Start Arduino and open the Preferences window.
33-
- Enter ```https://arduino.esp8266.com/stable/package_esp8266com_index.json``` into the *Additional Board Manager URLs* field. You can add multiple URLs, separating them with commas.
33+
- Enter ```https://arduino.esp8266.com/stable/package_esp8266com_index.json``` into the *File>Preferences>Additional Boards Manager URLs* field of the Arduino IDE. You can add multiple URLs, separating them with commas.
3434
- Open Boards Manager from Tools > Board menu and install *esp8266* platform (and don't forget to select your ESP8266 board from Tools > Board menu after installation).
3535

3636
#### Latest release [![Latest release](https://img.shields.io/github/release/esp8266/Arduino.svg)](https://github.com/esp8266/Arduino/releases/latest/)

boards.txt

Lines changed: 547 additions & 0 deletions
Large diffs are not rendered by default.

bootloaders/eboot/eboot.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ int load_app_from_flash_raw(const uint32_t flash_addr)
6868
load = true;
6969
}
7070

71-
if (address >= 0x40100000 && address < 0x40108000) {
71+
// The final IRAM size, once boot has completed, can be either 32K or 48K.
72+
// Allow for the higher in range testing.
73+
if (address >= 0x40100000 && address < 0x4010C000) {
7274
load = true;
7375
}
7476

bootloaders/eboot/eboot.elf

-72 Bytes
Binary file not shown.

cores/esp8266/Arduino.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ void optimistic_yield(uint32_t interval_us);
225225
#include <cstdlib>
226226
#include <cmath>
227227

228+
229+
#include "mmu_iram.h"
230+
231+
228232
using std::min;
229233
using std::max;
230234
using std::round;

cores/esp8266/Esp-frag.cpp

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@ void EspClass::getHeapStats(uint32_t* hfree, uint16_t* hmax, uint8_t* hfrag)
3030
// 100 * (1 - sqrt(sum(hole-size²)) / sum(hole-size))
3131

3232
umm_info(NULL, false);
33-
uint8_t block_size = umm_block_size();
33+
34+
uint32_t free_size = umm_free_heap_size_core(umm_get_current_heap());
3435
if (hfree)
35-
*hfree = ummHeapInfo.freeBlocks * block_size;
36+
*hfree = free_size;
3637
if (hmax)
37-
*hmax = (uint16_t)ummHeapInfo.maxFreeContiguousBlocks * block_size;
38+
*hmax = (uint16_t)umm_max_block_size_core(umm_get_current_heap());
3839
if (hfrag) {
39-
if (ummHeapInfo.freeBlocks) {
40-
*hfrag = 100 - (sqrt32(ummHeapInfo.freeBlocksSquared) * 100) / ummHeapInfo.freeBlocks;
40+
if (free_size) {
41+
*hfrag = umm_fragmentation_metric_core(umm_get_current_heap());
4142
} else {
4243
*hfrag = 0;
4344
}
@@ -46,11 +47,5 @@ void EspClass::getHeapStats(uint32_t* hfree, uint16_t* hmax, uint8_t* hfrag)
4647

4748
uint8_t EspClass::getHeapFragmentation()
4849
{
49-
#ifdef UMM_INLINE_METRICS
50-
return (uint8_t)umm_fragmentation_metric();
51-
#else
52-
uint8_t hfrag;
53-
getHeapStats(nullptr, nullptr, &hfrag);
54-
return hfrag;
55-
#endif
50+
return (uint8_t)umm_fragmentation_metric();
5651
}

cores/esp8266/Esp.cpp

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "cont.h"
2929

3030
#include "coredecls.h"
31+
#include "umm_malloc/umm_malloc.h"
32+
// #include "core_esp8266_vm.h"
3133
#include <pgmspace.h>
3234

3335
extern "C" {
@@ -516,45 +518,45 @@ uint8_t *EspClass::random(uint8_t *resultArray, const size_t outputSizeBytes) co
516518
{
517519
/**
518520
* The ESP32 Technical Reference Manual v4.1 chapter 24 has the following to say about random number generation (no information found for ESP8266):
519-
*
521+
*
520522
* "When used correctly, every 32-bit value the system reads from the RNG_DATA_REG register of the random number generator is a true random number.
521523
* These true random numbers are generated based on the noise in the Wi-Fi/BT RF system.
522524
* When Wi-Fi and BT are disabled, the random number generator will give out pseudo-random numbers.
523-
*
525+
*
524526
* When Wi-Fi or BT is enabled, the random number generator is fed two bits of entropy every APB clock cycle (normally 80 MHz).
525527
* Thus, for the maximum amount of entropy, it is advisable to read the random register at a maximum rate of 5 MHz.
526528
* A data sample of 2 GB, read from the random number generator with Wi-Fi enabled and the random register read at 5 MHz,
527529
* has been tested using the Dieharder Random Number Testsuite (version 3.31.1).
528530
* The sample passed all tests."
529-
*
531+
*
530532
* Since ESP32 is the sequal to ESP8266 it is unlikely that the ESP8266 is able to generate random numbers more quickly than 5 MHz when run at a 80 MHz frequency.
531533
* A maximum random number frequency of 0.5 MHz is used here to leave some margin for possibly inferior components in the ESP8266.
532534
* It should be noted that the ESP8266 has no Bluetooth functionality, so turning the WiFi off is likely to cause RANDOM_REG32 to use pseudo-random numbers.
533-
*
534-
* It is possible that yield() must be called on the ESP8266 to properly feed the hardware random number generator new bits, since there is only one processor core available.
535+
*
536+
* It is possible that yield() must be called on the ESP8266 to properly feed the hardware random number generator new bits, since there is only one processor core available.
535537
* However, no feeding requirements are mentioned in the ESP32 documentation, and using yield() could possibly cause extended delays during number generation.
536538
* Thus only delayMicroseconds() is used below.
537-
*/
539+
*/
538540

539541
constexpr uint8_t cooldownMicros = 2;
540542
static uint32_t lastCalledMicros = micros() - cooldownMicros;
541543

542544
uint32_t randomNumber = 0;
543-
545+
544546
for(size_t byteIndex = 0; byteIndex < outputSizeBytes; ++byteIndex)
545547
{
546548
if(byteIndex % 4 == 0)
547549
{
548550
// Old random number has been used up (random number could be exactly 0, so we can't check for that)
549-
551+
550552
uint32_t timeSinceLastCall = micros() - lastCalledMicros;
551553
if(timeSinceLastCall < cooldownMicros)
552554
delayMicroseconds(cooldownMicros - timeSinceLastCall);
553-
555+
554556
randomNumber = RANDOM_REG32;
555557
lastCalledMicros = micros();
556558
}
557-
559+
558560
resultArray[byteIndex] = randomNumber;
559561
randomNumber >>= 8;
560562
}
@@ -969,3 +971,57 @@ String EspClass::getSketchMD5()
969971
result = md5.toString();
970972
return result;
971973
}
974+
975+
void EspClass::enableVM()
976+
{
977+
#ifdef UMM_HEAP_EXTERNAL
978+
if (!vmEnabled)
979+
install_vm_exception_handler();
980+
vmEnabled = true;
981+
#endif
982+
}
983+
984+
void EspClass::setExternalHeap()
985+
{
986+
#ifdef UMM_HEAP_EXTERNAL
987+
if (vmEnabled)
988+
umm_push_heap(UMM_HEAP_EXTERNAL);
989+
#endif
990+
}
991+
992+
void EspClass::setIramHeap()
993+
{
994+
#ifdef UMM_HEAP_IRAM
995+
umm_push_heap(UMM_HEAP_IRAM);
996+
#endif
997+
}
998+
999+
void EspClass::setDramHeap()
1000+
{
1001+
#if defined(UMM_HEAP_EXTERNAL) && !defined(UMM_HEAP_IRAM)
1002+
if (vmEnabled) {
1003+
if (!umm_push_heap(UMM_HEAP_DRAM)) {
1004+
panic();
1005+
}
1006+
}
1007+
#elif defined(UMM_HEAP_IRAM)
1008+
if (!umm_push_heap(UMM_HEAP_DRAM)) {
1009+
panic();
1010+
}
1011+
#endif
1012+
}
1013+
1014+
void EspClass::resetHeap()
1015+
{
1016+
#if defined(UMM_HEAP_EXTERNAL) && !defined(UMM_HEAP_IRAM)
1017+
if (vmEnabled) {
1018+
if (!umm_pop_heap()) {
1019+
panic();
1020+
}
1021+
}
1022+
#elif defined(UMM_HEAP_IRAM)
1023+
if (!umm_pop_heap()) {
1024+
panic();
1025+
}
1026+
#endif
1027+
}

cores/esp8266/Esp.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ class EspClass {
123123
uint8_t getBootMode();
124124

125125
#if defined(F_CPU) || defined(CORE_MOCK)
126-
constexpr
126+
constexpr
127127
#endif
128128
inline uint8_t getCpuFreqMHz() const __attribute__((always_inline))
129129
{
@@ -215,7 +215,15 @@ class EspClass {
215215
#else
216216
uint32_t getCycleCount();
217217
#endif // !defined(CORE_MOCK)
218+
void enableVM();
219+
void setDramHeap();
220+
void setIramHeap();
221+
void setExternalHeap();
222+
void resetHeap();
218223
private:
224+
#ifdef UMM_HEAP_EXTERNAL
225+
bool vmEnabled = false;
226+
#endif
219227
/**
220228
* @brief Replaces @a byteCount bytes of a 4 byte block on flash
221229
*

cores/esp8266/Schedule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ bool schedule_function(const std::function<void(void)>& fn)
102102
return true;
103103
}
104104

105+
IRAM_ATTR // (not only) called from ISR
105106
bool schedule_recurrent_function_us(const std::function<bool(void)>& fn,
106107
uint32_t repeat_us, const std::function<bool(void)>& alarm)
107108
{

cores/esp8266/StackThunk.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include "debug.h"
3232
#include "StackThunk.h"
3333
#include <ets_sys.h>
34+
#include <umm_malloc/umm_malloc.h>
35+
#include <umm_malloc/umm_heap_select.h>
3436

3537
extern "C" {
3638

@@ -48,7 +50,14 @@ void stack_thunk_add_ref()
4850
{
4951
stack_thunk_refcnt++;
5052
if (stack_thunk_refcnt == 1) {
53+
DBG_MMU_PRINTF("\nStackThunk malloc(%u)\n", _stackSize * sizeof(uint32_t));
54+
// The stack must be in DRAM, or an Soft WDT will follow. Not sure why,
55+
// maybe too much time is consumed with the non32-bit exception handler.
56+
// Also, interrupt handling on an IRAM stack would be very slow.
57+
// Strings on the stack would be very slow to access as well.
58+
HeapSelectDram ephemeral;
5159
stack_thunk_ptr = (uint32_t *)malloc(_stackSize * sizeof(uint32_t));
60+
DBG_MMU_PRINTF("StackThunk stack_thunk_ptr: %p\n", stack_thunk_ptr);
5261
if (!stack_thunk_ptr) {
5362
// This is a fatal error, stop the sketch
5463
DEBUGV("Unable to allocate BearSSL stack\n");

cores/esp8266/Tone.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,18 @@
2525
#include "core_esp8266_waveform.h"
2626
#include "user_interface.h"
2727

28-
// Which pins have a tone running on them?
29-
static uint32_t _toneMap = 0;
30-
31-
3228
static void _startTone(uint8_t _pin, uint32_t high, uint32_t low, uint32_t duration) {
3329
if (_pin > 16) {
3430
return;
3531
}
3632

33+
#ifndef WAVEFORM_LOCKED_PHASE
34+
// Stop any analogWrites (PWM) because they are a different generator
35+
_stopPWM(_pin);
36+
#endif
37+
// If there's another Tone or startWaveform on this pin
38+
// it will be changed on-the-fly (no need to stop it)
39+
3740
pinMode(_pin, OUTPUT);
3841

3942
high = std::max(high, (uint32_t)microsecondsToClockCycles(25)); // new 20KHz maximum tone frequency,
@@ -42,9 +45,7 @@ static void _startTone(uint8_t _pin, uint32_t high, uint32_t low, uint32_t durat
4245
duration = microsecondsToClockCycles(duration * 1000UL);
4346
duration += high + low - 1;
4447
duration -= duration % (high + low);
45-
if (startWaveformClockCycles(_pin, high, low, duration)) {
46-
_toneMap |= 1 << _pin;
47-
}
48+
startWaveformClockCycles(_pin, high, low, duration);
4849
}
4950

5051

@@ -86,6 +87,5 @@ void noTone(uint8_t _pin) {
8687
return;
8788
}
8889
stopWaveform(_pin);
89-
_toneMap &= ~(1 << _pin);
9090
digitalWrite(_pin, 0);
9191
}

cores/esp8266/Updater.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ bool UpdaterClass::end(bool evenIfRemaining){
203203
return false;
204204
}
205205

206+
// Updating w/o any data is an error we detect here
207+
if (!progress()) {
208+
_setError(UPDATE_ERROR_NO_DATA);
209+
}
210+
206211
if(hasError() || (!isFinished() && !evenIfRemaining)){
207212
#ifdef DEBUG_UPDATER
208213
DEBUG_UPDATER.printf_P(PSTR("premature end: res:%u, pos:%zu/%zu\n"), getError(), progress(), _size);
@@ -551,6 +556,8 @@ void UpdaterClass::printError(Print &out){
551556
out.println(F("Bad Size Given"));
552557
} else if(_error == UPDATE_ERROR_STREAM){
553558
out.println(F("Stream Read Timeout"));
559+
} else if(_error == UPDATE_ERROR_NO_DATA){
560+
out.println(F("No data supplied"));
554561
} else if(_error == UPDATE_ERROR_MD5){
555562
out.printf_P(PSTR("MD5 Failed: expected:%s, calculated:%s\n"), _target_md5.c_str(), _md5.toString().c_str());
556563
} else if(_error == UPDATE_ERROR_SIGN){

cores/esp8266/Updater.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define UPDATE_ERROR_MAGIC_BYTE (10)
2020
#define UPDATE_ERROR_BOOTSTRAP (11)
2121
#define UPDATE_ERROR_SIGN (12)
22+
#define UPDATE_ERROR_NO_DATA (13)
2223

2324
#define U_FLASH 0
2425
#define U_FS 100

cores/esp8266/WString.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
String::String(const char *cstr) {
3333
init();
3434
if (cstr)
35-
copy(cstr, strlen(cstr));
35+
copy(cstr, strlen_P(cstr));
3636
}
3737

3838
String::String(const String &value) {

cores/esp8266/core_esp8266_main.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ extern "C" {
3535
#include <core_version.h>
3636
#include "gdb_hooks.h"
3737
#include "flash_quirks.h"
38+
#include <umm_malloc/umm_malloc.h>
39+
#include <core_esp8266_non32xfer.h>
40+
3841

3942
#define LOOP_TASK_PRIORITY 1
4043
#define LOOP_QUEUE_SIZE 1
@@ -204,7 +207,9 @@ static void loop_wrapper() {
204207
static void loop_task(os_event_t *events) {
205208
(void) events;
206209
s_cycles_at_yield_start = ESP.getCycleCount();
210+
ESP.resetHeap();
207211
cont_run(g_pcont, &loop_wrapper);
212+
ESP.setDramHeap();
208213
if (cont_check(g_pcont) != 0) {
209214
panic();
210215
}
@@ -256,6 +261,7 @@ void init_done() {
256261
std::set_terminate(__unhandled_exception_cpp);
257262
do_global_ctors();
258263
esp_schedule();
264+
ESP.setDramHeap();
259265
}
260266

261267
/* This is the entry point of the application.
@@ -311,14 +317,22 @@ extern "C" void app_entry_redefinable(void)
311317
cont_t s_cont __attribute__((aligned(16)));
312318
g_pcont = &s_cont;
313319

320+
#ifdef DEV_DEBUG_MMU_IRAM
321+
DBG_MMU_PRINT_STATUS();
322+
323+
DBG_MMU_PRINT_IRAM_BANK_REG(0, "");
324+
325+
DBG_MMU_PRINTF("\nCall call_user_start()\n");
326+
#endif
327+
314328
/* Call the entry point of the SDK code. */
315329
call_user_start();
316330
}
317-
318331
static void app_entry_custom (void) __attribute__((weakref("app_entry_redefinable")));
319332

320333
extern "C" void app_entry (void)
321334
{
335+
umm_init();
322336
return app_entry_custom();
323337
}
324338

@@ -342,6 +356,12 @@ extern "C" void user_init(void) {
342356

343357
cont_init(g_pcont);
344358

359+
#if defined(NON32XFER_HANDLER) || defined(MMU_IRAM_HEAP)
360+
install_non32xfer_exception_handler();
361+
#endif
362+
#if defined(MMU_IRAM_HEAP)
363+
umm_init_iram();
364+
#endif
345365
preinit(); // Prior to C++ Dynamic Init (not related to above init() ). Meant to be user redefinable.
346366

347367
ets_task(loop_task,

0 commit comments

Comments
 (0)
0