- Notifications
You must be signed in to change notification settings - Fork 13.3k
Closed
Labels
component: coretype: bugwaiting for feedbackWaiting on additional info. If it's not received, the issue may be closed.Waiting on additional info. If it's not received, the issue may be closed.
Milestone
Description
Basic Infos
- This issue complies with the issue POLICY doc.
- I have read the documentation at readthedocs and the issue is not addressed there.
- I have tested that the issue is present in current master branch (aka latest git).
- I have searched the issue tracker for a similar issue.
- If there is a stack dump, I have decoded it.
- I have filled out all fields below.
Platform
- Hardware: [ESP-WROOM-02]
- Core Version: [3.0.0 release]
- Development Env: [Arduino IDE]
- Operating System: [Linux]
Settings in IDE
- Module: [Generic ESP8266 Module]
- Flash Mode: [qio]
- Flash Size: [4MB]
- lwip Variant: [v2 Lower Memory]
- Reset Method: [nodemcu]
- Flash Frequency: [40Mhz]
- CPU Frequency: [80Mhz]
- Upload Using: [SERIAL]
- Upload Speed: [115200] (serial upload only)
Problem Description
digitalWrite() calls _stopPWM(), which lacks the IRAM_ATTR attribute.
When digitalWrite() is called inside an ISR handler, it may have to wait for the content get fetched from the external flash, which'd block the ISR handler, which may cause the system to crash.
Relevant code: https://github.com/esp8266/Arduino/blob/90f611f/cores/esp8266/core_esp8266_waveform_pwm.cpp#L263
This bug can be easily reproduced if you read the flash filesystem while running digitalWrite() in ISR frequently. For the ease of implementation, the MCVE uses the ESP8266TimerInterrupt library.
This bug is new in v3.0.0 and couldn't be reproduced in v2.7.4.
MCVE Sketch
#include <ESP8266TimerInterrupt.h> // https://github.com/khoih-prog/ESP8266TimerInterrupt #include <LittleFS.h> #define TEST_PIN (15) #define FILENAME "foobarbaz" #define FILE_CONTENT "foobarbaz" ESP8266Timer esp8266timer; static IRAM_ATTR void timer_isr_handler() { static int state = LOW; digitalWrite(TEST_PIN, state); state = !state; } void setup() { LittleFS.begin(); Serial.begin(115200); // Create a file in the LittleFS filesystem to be read in loop() File f = LittleFS.open(FILENAME, "w"); f.write(FILE_CONTENT, sizeof(FILE_CONTENT)); f.close(); // Initialization pinMode(TEST_PIN, OUTPUT); if (!esp8266timer.attachInterruptInterval(1 * 1000, timer_isr_handler)) { // Triggered once every millisecond Serial.println("Error: Failed to attach timer interrupt handler!"); delay(1000); ESP.restart(); } delay(5000); // Rate limiting: Prevent the flash from wearing out from frequent f.write() calls. Serial.println("ready!"); } void loop() { // Print the content from a file in the filesystem with Serial File f = LittleFS.open(FILENAME, "r"); if(f) { char buf[sizeof(FILE_CONTENT)]; f.read((uint8_t*)buf, sizeof(FILE_CONTENT)); Serial.print("File content read: "); Serial.println(buf); f.close(); } delay(100); }
Stack Dump
Exception 0: Illegal instruction PC: 0x40209884: _stopPWM(uint8_t) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_waveform_pwm.cpp line 264 EXCVADDR: 0x00000000 Decoding stack results 0x40100400: __digitalWrite(uint8_t, uint8_t) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_wiring_digital.cpp line 86 0x401001e0: timer1_isr_handler(void*, void*) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_timer.cpp line 37 0x4010011d: timer_isr_handler() at /home/username/Desktop/link to usb-7-segment/firmware/stoppwm_bug/stoppwm_bug.ino line 11 0x40100228: timer1_isr_handler(void*, void*) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_timer.cpp line 44 0x40100e86: __wrap_spi_flash_read(uint32_t, uint32_t*, size_t) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_phy.cpp line 309 0x40100e86: __wrap_spi_flash_read(uint32_t, uint32_t*, size_t) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_phy.cpp line 309 0x40209180: EspClass::flashRead(unsigned int, unsigned int*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/Esp.cpp line 954 0x40209207: EspClass::flashRead(unsigned int, unsigned char*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/Esp.cpp line 933 0x40100e86: __wrap_spi_flash_read(uint32_t, uint32_t*, size_t) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_phy.cpp line 309 0x40209180: EspClass::flashRead(unsigned int, unsigned int*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/Esp.cpp line 954 0x40209207: EspClass::flashRead(unsigned int, unsigned char*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/Esp.cpp line 933 0x40100e86: __wrap_spi_flash_read(uint32_t, uint32_t*, size_t) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_phy.cpp line 309 0x40209180: EspClass::flashRead(unsigned int, unsigned int*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/Esp.cpp line 954 0x40209207: EspClass::flashRead(unsigned int, unsigned char*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/Esp.cpp line 933 0x401001a8: ets_post(uint8, ETSSignal, ETSParam) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_main.cpp line 181 0x40100100: std::function ::operator()() const at /home/username/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.0-newlib4.0.0-gnu23-48f7b08/xtensa-lx106-elf/include/c++/10.2.0/bits/std_function.h line 617 0x402075fa: __yield() at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_main.cpp line 116 0x40208045: flash_hal_read(unsigned int, unsigned int, unsigned char*) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/flash_hal.cpp line 36 0x40205dba: littlefs_impl::LittleFSImpl::lfs_flash_read(lfs_config const*, unsigned int, unsigned int, void*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/LittleFS.cpp line 171 0x40201330: lfs_bd_read at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/../lib/littlefs/lfs.c line 101 0x402018a1: lfs_dir_fetchmatch at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/../lib/littlefs/lfs.c line 891 0x40205dba: littlefs_impl::LittleFSImpl::lfs_flash_read(lfs_config const*, unsigned int, unsigned int, void*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/LittleFS.cpp line 171 0x40201e94: lfs_dir_find at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/../lib/littlefs/lfs.c line 1238 0x402020f8: lfs_dir_find_match at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/../lib/littlefs/lfs.c line 1140 0x40204554: lfs_dir_commit_commit at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/../lib/littlefs/lfs.c line 1560 0x40204266: lfs_file_rawopencfg at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/../lib/littlefs/lfs.c line 2472 0x40204ced: lfs_file_open at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/libraries/LittleFS/src/../lib/littlefs/lfs.c line 5058 0x4020684f: littlefs_impl::LittleFSImpl::open(char const*, fs::OpenMode, fs::AccessMode) at /home/username/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.0-newlib4.0.0-gnu23-48f7b08/xtensa-lx106-elf/include/c++/10.2.0/bits/shared_ptr_base.h line 1324 0x401008a7: umm_free_core(umm_heap_context_t*, void*) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/umm_malloc/umm_malloc.cpp line 549 0x40206c33: fs::FS::open(char const*, char const*) at /home/username/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.0-newlib4.0.0-gnu23-48f7b08/xtensa-lx106-elf/include/c++/10.2.0/bits/shared_ptr_base.h line 1324 0x40206dd0: HardwareSerial::write(unsigned char const*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/HardwareSerial.h line 193 0x40206ddc: HardwareSerial::write(unsigned char const*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/HardwareSerial.h line 193 0x40206dd0: HardwareSerial::write(unsigned char const*, unsigned int) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/HardwareSerial.h line 193 0x40206f74: Print::write(char const*) at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/Print.h line 59 0x40206fc0: Print::println() at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/Print.h line 57 0x4020549f: loop() at /home/username/Desktop/link to usb-7-segment/firmware/stoppwm_bug/stoppwm_bug.ino line 31 0x402055b5: setup() at /home/username/.arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.0-newlib4.0.0-gnu23-48f7b08/xtensa-lx106-elf/include/c++/10.2.0/bits/shared_ptr_base.h line 1183 0x40205f48: fs::FS::_defaultTimeCB() at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/FS.h line 249 0x4020767c: loop_wrapper() at /home/username/.arduino15/packages/esp8266/hardware/esp8266/3.0.0/cores/esp8266/core_esp8266_main.cpp line 201
Metadata
Metadata
Assignees
Labels
component: coretype: bugwaiting for feedbackWaiting on additional info. If it's not received, the issue may be closed.Waiting on additional info. If it's not received, the issue may be closed.