Provides a transparently accessible additional block of RAM of 128K to
8MB by using an external SPI SRAM. This memory is managed using the UMM
memory manager and can be used by the core as if it were internal RAM
(albeit much slower to read or write).
The use case would be for things which are quite large but not
particularly frequently used or compute intensive. For example, the SSL
buffers of 16K++ are a good fit for this, as are the contents of Strings
(both to avoid main heap fragmentation as well as allowing Strings of
>30KB).
A fully associative LRU cache is used to limit the SPI bus bottleneck,
and background writeback is supported.
Uses a define in boards.txt to enable. If this value is not defined,
then the entire VM routines should not be linked in to user apps
so there should be no space penalty w/o it.
UMM `malloc` and `new` are modified to support internal and external
heap regions. By default, everything comes from the standard heap, but
a call to `ESP.setExternalHeap()` before the allocation (followed by a
call to `ESP.resetHeap()` will make the allocation come from external
RAM. See the `virtualmem.ino` example for use.
If there is no external RAM installed, the `setExternalHeap` call is a
no-op.
The String and BearSSL libraries have been modified to use this external
RAM automatically.
Theory of Operation:
The Xtensa core generates a hardware exception (unrelated to C++
exceptions) when an address that's defined as invalid for load or store.
The XTOS ROM routines capture the machine state and call a standard C
exception handler routine (or the default one which resets the system).
We hook into this exception callback and decode the EXCVADDR (the
address being accessed) and use the exception PC to read out the
faulting instruction. We decode that instruction and simulate it's
behavior (i.e. either loading or storing some data to a
register/external memory) and then return to the calling application.
We use the hardware SPI interface to talk to an external SRAM/PSRAM,
and implement a simple cache to minimize the amount of times we need
to go out over the (slow) SPI bus. The SPI is set up in a DIO mode
which uses no more pins than normal SPI, but provides for ~2X faster
transfers. SIO mode is also supported.
NOTE: This works fine for processor accesses, but cannot be used by
any of the peripherals' DMA. For that, we'd need a real MMU.
Hardware Configuration (only use 3.3V compatible SRAMs!):
SPI byte-addressible SRAM/PSRAM: 23LC1024 or smaller
CS -> GPIO15
SCK -> GPIO14
MOSI -> GPIO13
MISO -> GPIO12
(note these are GPIO numbers, not the Arduino Dxx pin names. Refer
to your ESP8266 board schematic for the mapping of GPIO to pin.)
Higher density PSRAM (ESP-PSRAM64H/etc.) should work as well, but
I'm still waiting on my chips so haven't done any testing. Biggest
concern is their command set and functionality in DIO mode. If DIO
mode isn't supported, then a fallback to SIO is possible.
This PR originated with code from @pvvx's esp8266web server at
https://github.com/pvvx/esp8266web (licensed in the public domain)
but doesn't resemble it much any more. Thanks, @pvvx!
Keep a list of the last 8 lines in RAM (~.5KB of RAM) and use that to
speed up things like memcpys and other operations where the source and
destination addresses are inside VM RAM.
A custom set of SPI routines is used in the VM system for speed and code
size (and because the core cannot be dependent on a library).
Because UMM manages RAM in 8 byte chunks, attempting to manage the
entire 1M available space on a 1M PSRAM causes the block IDs to
overflow, crashing things at some point. Limit the UMM allocation to
only 256K in this case. The remaining space can manually be assigned to
buffers/etc. managed by the application, not malloc()/free().
Fixes#427
Adds a basic I2S class based off of the Arduino-SAMD core. The raw
i2s_xxx functions are still a better way to use I2S due to their
flexibility, but this will allow basic Arduino sketches to work.
without any external wiring.
This patch introduces the new method
Esp.rebootIntoUartDownloadMode()
When the user calls this method the ESP8266 reboots into the UART
download mode. In this mode the user can use esptool.py to flash a new
firmware file. The following command was used to test it:
$ esptool.py --before no_reset --after soft_reset --chip esp8266 \
--port /dev/ttyUSB0 --baud 460800 write_flash 0x0 firmware.bin
The implementation is based on the original implementation in the
boot ROM. Some parts of the original implementation can be found in
[1]. This patch is a squashed and simplified version of [2]. The non
squashed version might be helpful in case of debugging issues.
[1] https://github.com/twischer/xtensa-subjects/blob/master/reversed/bootrom.c
[2] https://github.com/twischer/Arduino/tree/reboot_uart_download_full
Signed-off-by: Timo Wischer <twischer@freenet.de>
Improve resume speed by passing in last known BSSID
Provide a simpler example for WIFI_SHUTDOWN/WIFI_RESUME
Add documentation for WIFI_SHUTDOWN and WIFI_RESUME.
* Fix ESP8266SdFat architecture
Avoid problems reported in
https://forum.arduino.cc/index.php?topic=726897.msg4889319
* Fix Windows CI, python3 now *maybe* exists
Python3 used to be called "python.exe" on earlier VMs, but it looks like
the image has been updated and a "python3.exe" does now exist. Update
the CI script to first check it "python3" exists, and if not then do the
copy hack, OTW do nothing.
RODATA can be copied automatically by the bootrom, so no reason not to
allow its use for strings and constants in eboot.c
Revert to pfalcon's original uzlib since the single patch to remove
RODATA is not required.
Rationalize eboot.ld linker script, clean up BSS and init it in code.
Saves 112 bytes of space in the bootloader sector by removing the
extra code associated with literal loads.
* Move CRC out of bootload sector
We added protection to only erase the bootload sector when flashing an
image when the new sector != the old sector. This was intended to
minimize the chance of bricking (i.e. if there was a powerfail during
flashing of the boot sector the chip would be dead).
Unfortunately, by placing the CRC inside the eboot sector *every*
application will have a unique eboot sector (due to the crc/len), so
this protection doesn't work.
Move the CRC into the first 8 bytes of IROM itself. This frees up extra
space in the boot sector and ensures that eboot won't be reflashed
unless there really is an eboot change.
Update newlib to enable the __ieee754_remainder(f) calls required by
std::remainder and others.
Add device test for std::remainder variants.
Fixes#7845
Fatfingered the 32-bit Windows pointer to the Python interpreter. Our
CI and my own testing missed due to being on 64-bit Windows.
For 2.7.4 release, I'll add a file of the appropriate name to the
release for now, but this will correct things for 3.0.0 and forward.
A couple board types reported ESP8266_GENERIC instead of their proper
types in boards.txt (and in defined generated therefrom/etc.).
Give them proper board types based on their names, like other modules.
* allow to set pin to OUTPUT_OPEN_DRAIN in analogWrite
* remove parameter with default value
* Update core_esp8266_wiring_pwm.cpp
* update documentation accordingly
Add basic 24 bit mode to the I2S API with a i2s_set_bits() call.
By default 16b mode is still used, but if i2s_set_bits(24) is run
before i2s_begin() then the HW will drive 24-bits of data. This
data must be left-aligned (i.e. bits 31..8) in 4-byte samples.
Fixes#5244 (the HW doesn't support 8 or 32 bits, only 16 or 24).
* Allow specifying waveform generator in source code
Allows code to explicitly specify which waveform generator it wants,
without needing to use one of the 100 IDE menus or adding a `-D`
compile-time define.
Uses weakrefs to allow for apps to call `enablePhaseLockedWaveform();`
within their `setup()` (or anywhere, really) and have the phase locked
versions override the default waveform generators automatically.
For example:
````
void setup() {
// Uncomment following line to use phase-locked waveform generator
// enablePhaseLockedWaveform();
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
analogWriteRange(1000);
}
void loop() {
analogWrite(LED_BUILTIN, 100);
delay(1000); // Wait for a second
analogWrite(LED_BUILTIN, 900);
delay(2000); // Wait for two seconds (to demonstrate the active low LED)
}
````
Also adds an example showing it's use.
Address @dok-net's comments and also remove the _weak/_bound version of
startWaveform() since it's invariant of the actual waveform generator.
* Add inline always option to HeapSelect
* Add option to force DRAM for pvPort... APIs
* revert print_loc premature change
* Renamed macro to be more specific, FORCE_ALWAYS_INLINE to FORCE_ALWAYS_INLINE_HEAP_SELECT
Added replacement for the Boot ROM `_xtos_set_exception_handler`
to handle installing our replacement `_xtos_c_wrapper_handler`.
Simplified install in the non 32-bit exception module to make use of the
improved `_xtos_set_exception_handler`
Reorganized and improved comments.
If a server returns "HTTP/1.x -8 OK", for example, it can misguide an application developer into freeing less-important memory so the request can be retried and succeed, when the problem is in the server.
_returnCode is never used anywhere else, but it could still contain a negative value returned by a broken server and therefore could cause troubles in the future (if _returnCode is in fact used)