|
28 | 28 | #include "cont.h"
|
29 | 29 |
|
30 | 30 | #include "coredecls.h"
|
| 31 | +#include "umm_malloc/umm_malloc.h" |
| 32 | +// #include "core_esp8266_vm.h" |
31 | 33 | #include <pgmspace.h>
|
32 | 34 |
|
33 | 35 | extern "C" {
|
@@ -516,45 +518,45 @@ uint8_t *EspClass::random(uint8_t *resultArray, const size_t outputSizeBytes) co
|
516 | 518 | {
|
517 | 519 | /**
|
518 | 520 | * 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 | + * |
520 | 522 | * "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.
|
521 | 523 | * These true random numbers are generated based on the noise in the Wi-Fi/BT RF system.
|
522 | 524 | * When Wi-Fi and BT are disabled, the random number generator will give out pseudo-random numbers.
|
523 |
| - * |
| 525 | + * |
524 | 526 | * When Wi-Fi or BT is enabled, the random number generator is fed two bits of entropy every APB clock cycle (normally 80 MHz).
|
525 | 527 | * Thus, for the maximum amount of entropy, it is advisable to read the random register at a maximum rate of 5 MHz.
|
526 | 528 | * A data sample of 2 GB, read from the random number generator with Wi-Fi enabled and the random register read at 5 MHz,
|
527 | 529 | * has been tested using the Dieharder Random Number Testsuite (version 3.31.1).
|
528 | 530 | * The sample passed all tests."
|
529 |
| - * |
| 531 | + * |
530 | 532 | * 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.
|
531 | 533 | * A maximum random number frequency of 0.5 MHz is used here to leave some margin for possibly inferior components in the ESP8266.
|
532 | 534 | * 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. |
535 | 537 | * However, no feeding requirements are mentioned in the ESP32 documentation, and using yield() could possibly cause extended delays during number generation.
|
536 | 538 | * Thus only delayMicroseconds() is used below.
|
537 |
| - */ |
| 539 | + */ |
538 | 540 |
|
539 | 541 | constexpr uint8_t cooldownMicros = 2;
|
540 | 542 | static uint32_t lastCalledMicros = micros() - cooldownMicros;
|
541 | 543 |
|
542 | 544 | uint32_t randomNumber = 0;
|
543 |
| - |
| 545 | + |
544 | 546 | for(size_t byteIndex = 0; byteIndex < outputSizeBytes; ++byteIndex)
|
545 | 547 | {
|
546 | 548 | if(byteIndex % 4 == 0)
|
547 | 549 | {
|
548 | 550 | // Old random number has been used up (random number could be exactly 0, so we can't check for that)
|
549 |
| - |
| 551 | + |
550 | 552 | uint32_t timeSinceLastCall = micros() - lastCalledMicros;
|
551 | 553 | if(timeSinceLastCall < cooldownMicros)
|
552 | 554 | delayMicroseconds(cooldownMicros - timeSinceLastCall);
|
553 |
| - |
| 555 | + |
554 | 556 | randomNumber = RANDOM_REG32;
|
555 | 557 | lastCalledMicros = micros();
|
556 | 558 | }
|
557 |
| - |
| 559 | + |
558 | 560 | resultArray[byteIndex] = randomNumber;
|
559 | 561 | randomNumber >>= 8;
|
560 | 562 | }
|
@@ -969,3 +971,57 @@ String EspClass::getSketchMD5()
|
969 | 971 | result = md5.toString();
|
970 | 972 | return result;
|
971 | 973 | }
|
| 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 | +} |
0 commit comments