Ошибка при загрузке файловой системы в ESP-12F

Алексей.

Active member
У sdk версии 2.6.1 отличается upload.py от того же upload.py что в версии 2.5.2
Кроме этого в 2.6.1 загрузчик esptool.py версии v2.8 а в 2.5.2 esptool.py версии v2.6
Плагин arduino-esp8266fs-plugin использует один и тот же код для выполнения загрузки.
Выполняет upload.py --chip esp8266 --port /dev/ttyUSB0 --baud 115200 write_flash 0x300000 FSBrowser.spiffs.bin --end
Для проверки загрузк на sdk версии 2.5.2 я создал файлик FSBrowser.spiffs.bin в 10килобайт
Код:
user@my-pc:~/Arduino/hardware/esp8266com/esp8266/tools$ dd if=/dev/zero of=FSBrowser.spiffs.bin bs=1000 count=10
10+0 records in
10+0 records out
10000 bytes (10 kB, 9.8 KiB) copied, 0.00020148 s, 49.6 MB/s
user@my-pc:~/Arduino/hardware/esp8266com/esp8266/tools$ ls -l FSBrowser.spiffs.bin
-rw-rw-r-- 1 user user 10000 Nov 22 09:41 FSBrowser.spiffs.bin
И попробовал выполнить загрузку без подключенного модуля, просто не оказалось под рукой.
Код:
user@my-pc:~/Arduino/hardware/esp8266com/esp8266/tools$ ./upload.py --chip esp8266 --port /dev/ttyUSB0 --baud 115200 write_flash 0x300000 FSBrowser.spiffs.bin --end
esptool.py v2.6
Serial port /dev/ttyUSB0
Connecting........^C
Traceback (most recent call last):
  File "./upload.py", line 25, in <module>
    esptool.main(fakeargs)
  File "/home/user/Arduino/hardware/esp8266com/esp8266/tools/esptool/esptool.py", line 2653, in main
    esp.connect(args.before)
  File "/home/user/Arduino/hardware/esp8266com/esp8266/tools/esptool/esptool.py", line 463, in connect
    last_error = self._connect_attempt(mode=mode, esp32r0_delay=True)
  File "/home/user/Arduino/hardware/esp8266com/esp8266/tools/esptool/esptool.py", line 425, in _connect_attempt
    time.sleep(1.2)
KeyboardInterrupt
Загрузчик пытался честно загрузить модуль, который не подключен, я его прервал.

Пытаюсь повторить опыт на sdk версии 2.6.1, тот же FSBrowser.spiffs.bin той же командой
Код:
user@my-pc:~/Arduino/hardware/esp8266com/esp8266/tools$ ./upload.py --chip esp8266 --port /dev/ttyUSB0 --baud 115200 write_flash 0x300000 FSBrowser.spiffs.bin --end
usage: esptool write_flash [-h] [--erase-all]
                           [--flash_freq {keep,40m,26m,20m,80m}]
                           [--flash_mode {keep,qio,qout,dio,dout}]
                           [--flash_size FLASH_SIZE]
                           [--spi-connection SPI_CONNECTION] [--no-progress]
                           [--verify] [--encrypt]
                           [--ignore-flash-encryption-efuse-setting]
                           [--compress | --no-compress]
                           <address> <filename> [<address> <filename> ...]
esptool write_flash: error: argument <address> <filename>: Must be pairs of an address and the binary filename to write there
Загрузка даже не началась.

Скажите, для чего вы используете sdk версии 2.6.1? Ведь прежде у вас всё загружалось.
 

Алексей.

Active member
На сдк 2.5.1 и 2.5.2 arduino-esp8266fs-plugin версии 0.4.0 (а свежее ещё небыло) работал, на 2.6.1 не работает и к чему эти рекомендации об устаревшем esptool-ck.exe, у @AllXXX в логах всяких .exe даже близко нет.
arduino-esp8266fs-plugin версия 0.4.0 дата выпуска 23 февраля 2019
ESP8266 core for Arduino версия 2.5.1 дата выпуска 11 мая 2019
Все рекомендации выполнены были с выходом 2.5.1 и загрузка работала.
 

CodeNameHawk

Moderator
Команда форума
Адрес 0x300000 откуда взялся? Ардуина заливает файловую по адресу 0x100000.
 

Алексей.

Active member
Видимо взялся из boards.txt
nodemcuv2.menu.eesz.4M1M=4MB (FS:1MB OTA:~1019KB)
nodemcuv2.menu.eesz.4M1M.build.flash_size=4M
nodemcuv2.menu.eesz.4M1M.build.flash_size_bytes=0x400000
nodemcuv2.menu.eesz.4M1M.build.flash_ld=eagle.flash.4m1m.ld
nodemcuv2.menu.eesz.4M1M.build.spiffs_pagesize=256
nodemcuv2.menu.eesz.4M1M.upload.maximum_size=1044464
nodemcuv2.menu.eesz.4M1M.build.rfcal_addr=0x3FC000
nodemcuv2.menu.eesz.4M1M.build.spiffs_start=0x300000
nodemcuv2.menu.eesz.4M1M.build.spiffs_end=0x3FA000
nodemcuv2.menu.eesz.4M1M.build.spiffs_blocksize=8192
 

Swaggaboy6537

New member
Добрый день @AllXXX @Алексей., я по-моему нашел решение, но не могу его на данный момент протестировать.
В пул-реквесте здесь: Make upload.py compatible with existing FS upload by earlephilhower · Pull Request #6788 · esp8266/Arduino были изменены параметры загрузки данных по SPIFFS так, чтобы все вновь работало. [off](я до конца не понял, возможно буду говорить чушь)[/off]

При рассмотрении пул-реквестов, владельцы и модераторы репозитория не заметили багу. Все одобренные пул-реквесты они добавили в обновление 2.6.0, позже, был еще фикс 2.6.1, в минорной версии они, как я понял, переписали uploader скетчей и данных для Arduino IDE под Python 3 (в связи с тем, что он с 01.01.2020 не будет поддерживаться).
И допустили ошибку, где перед аргументом "filename".bin не ставился дефолтный адрес загрузки 0x0.

Судя по пул-реквесту выше, они добавили эти изменения в будущее обновление 2.6.2, которое будет около 30 ноября.

На самом деле это, возможно, несовместимость с текущей версией arduino-esp8266fs-plugin.
Судя по этому обсуждению: Pull (#6765) breaks arduino-esp8266fs-plugin functionality · Issue #6777 · esp8266/Arduino; можно удалить "--end" в параметрах загрузчика (upload.py), либо пересобрать arduino-esp8266fs-plugin на Java.


Ваше и мое решение: применить изменения в 3 коммитах, или 2 измененных файлах в этом пул-реквесте Make upload.py compatible with existing FS upload by earlephilhower · Pull Request #6788 · esp8266/Arduino, пересобрать плагин на Java, или же удалить "--end" в upload.py и будет счастье :)
 

AllXXX

New member
пересобрать плагин на Java - не знаю как
или же удалить "--end" в upload.py нет в нем такого:
Код:
#!/usr/bin/env python3

# Wrapper for Arduino core / others that can call esptool.py possibly multiple times
# Adds pyserial to sys.path automatically based on the path of the current file

# First parameter is pyserial path, second is esptool path, then a series of command arguments separated with --end
# i.e. upload.py tools/pyserial tools/esptool erase_flash --end write_flash file 0x0 --end

import sys
import os
import tempfile

sys.argv.pop(0) # Remove executable name
toolspath = os.path.dirname(os.path.realpath(__file__)).replace('\\', '/') # CWD in UNIX format
try:
    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:
    sys.stderr.write("pyserial or esptool directories not found next to this upload.py tool.\n")
    sys.exit(1)

cmdline = []
write_option = ''
erase_addr = ''
erase_len = ''

while len(sys.argv):
    thisarg = sys.argv.pop(0)

    # We silently replace the 921kbaud setting with 460k to enable backward
    # compatibility with the old esptool-ck.exe.  Esptool.py doesn't seem
    # work reliably at 921k, but is still significantly faster at 460kbaud.
    if thisarg == "921600":
        thisarg = "460800"

    # 'erase_flash' command is translated to the write_flash --erase-all option
    # https://github.com/esp8266/Arduino/issues/6755#issuecomment-553208688
    if thisarg == "erase_flash":
        write_option = '--erase-all'
        thisarg = ''

    if thisarg == 'erase_region':
        erase_addr = sys.argv.pop(0)
        erase_len = sys.argv.pop(0)
        thisarg = ''

    if os.path.isfile(thisarg):
        binary = thisarg
        thisarg = ''

    if len(thisarg):
        cmdline = cmdline + [thisarg]

cmdline = cmdline + ['write_flash']
if len(write_option):
    cmdline = cmdline + [write_option]
cmdline = cmdline + ['0x0', binary]

erase_file = ''
if len(erase_addr):
    # generate temporary empty (0xff) file
    eraser = tempfile.mkstemp()
    erase_file = eraser[1]
    os.write(eraser[0], bytearray([255] * int(erase_len, 0)))
    os.close(eraser[0])
    cmdline = cmdline + [ erase_addr, erase_file ]

esptool.main(cmdline)

if len(erase_file):
    os.remove(erase_file)
буду ждать
 

Алексей.

Active member
Я отказался от загрузки данных в spiffs через плагин, точнее, отказался от загрузки в spiffs используя какие-либо инструменты, позволяющие грузить в spiffs не из кода, в spiffs если необходимо держу только конфигурационные параметры.
Статические данные, такие как html страницы, стили скрипты, держу в коде в массивах байтов с атрибутом PROGMEM.
В исходниках они (статические данные) как прежде в директории data, а при сборке "налету" преобразую их в си-шные исходники.
Для платформы настраиваю хук для скетч-пребилд например:
Код:
recipe.hooks.sketch.prebuild.0.pattern = {runtime.platform.path}/prebuild.local {build.source.path} {build.path} {build.project_name}
runtime.platform.path - это путь до директории в которой живет платформа
prebuild.local - это скрипт, который я создал для запуска других скриптов в директориях со скетчами, которые могут и отсутствовать если prebuild не требуется
Bash:
#!/bin/bash
# проверяем наличие файла prebuild в исходной директории со скетчем
if [ -e "$1/prebuild" ]
then
  # переходим в исходную директорию со скетчем
  cd $1
  # выполняем prebuild передавая путь ко временной директории созданной ардуиной для билда и название проекта
  ./prebuild $2 $3
fi
build.source.path - это путь до директории где живет скетч
build.path - это путь до временной директории куда ардуина-иде скопировала скетч перед сборкой
build.project_name - это название проекта
 

Swaggaboy6537

New member
@AllXXX
Вчера подготовил файлы для тестирования на компьютере друга, сегодня залил, все работает вновь.

Фикс сработает, если вы используете библиотеку ESP8266 (менеджер плат) версии 2.6.1

Прикладываю 2 измененных файла из этого пул-реквеста: Make upload.py compatible with existing FS upload by earlephilhower · Pull Request #6788 · esp8266/Arduino
  1. Заменить файл "C:\Users\<Имя пользователя>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\platform.txt"
  2. Заменить файл "C:\Users\<Имя пользователя>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\tools\upload.py"
Было изменено:
upload_2019-11-25_19-38-54.png
upload_2019-11-25_19-39-43.png
upload_2019-11-25_19-41-23.png
 

Вложения

Swaggaboy6537

New member
@Алексей.
Я просто думал, что это единственный вариант хранить статические данные, для того же веб-сервера (просто не особо знаком с разработкой под девайсы, да и вообще с C/C++ знаком только на уровне лабораторных из ИТМО)

А есть какие-то минусы от записи непосредственно во flash память, в отличие от использования для этого файловой системы SPIFFS?
Судя по определению PROGMEM, это чистая flash-память, а SPIFFS - попытка в файловую систему с дикими ограничениями, в которой также используется flash-память. Следовательно, ваш вариант будет даже лучше и быстрее для работы с памятью, или доступа к статическим данным.
[off]Кстати, в 2.6.1 они пофиксили багу с расширениями index-файла страницы, ибо по запросу к корню '/' искался по-умолчанию .htm файл, и .html таким образом пролетал мимо[/off]
 

garimas

New member
@AllXXX
Вчера подготовил файлы для тестирования на компьютере друга, сегодня залил, все работает вновь.

Фикс сработает, если вы используете библиотеку ESP8266 (менеджер плат) версии 2.6.1

Прикладываю 2 измененных файла из этого пул-реквеста: Make upload.py compatible with existing FS upload by earlephilhower · Pull Request #6788 · esp8266/Arduino
  1. Заменить файл "C:\Users\<Имя пользователя>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\platform.txt"
  2. Заменить файл "C:\Users\<Имя пользователя>\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.1\tools\upload.py"
Было изменено:
всё работает!!!
 

Алексей.

Active member
Судя по определению PROGMEM, это чистая flash-память, а SPIFFS - попытка в файловую систему с дикими ограничениями,
Модификатором переменной PROGMEM говорим компилятору, не копировать эту переменную в оперативную память, оставлять её во флеше.
В реализации ESP8266WebServer есть возможность выполнять отправку контента как из переменных в оперативной памяти
Код:
sendContent(const String& content)
sendContent(const char *content)
Так и непосредственно из флеша
Код:
sendContent_P(PGM_P content)
Что касается SPIFFS - это раздел на флеше, в котором построена файловая система. Минус - скорость доступа.
Если данные не предполагается модифицировать совсем, то смысла держать их отдельно от кода нет.
Если данные иногда нужно менять, например для веб-интерфейса меняете внешний вид, а код оставляете прежний, то можно данные в файлах держать на SPIFFS.
Ещё один минус, на мой взгляд.
Код периодически приходится обновлять, исправление ошибок, добавление нового функционала и т.п.
Если обновление выполняете по воздуху и кроме обновления кода требуется выполнить обновления данных, то обновление выполняется в два этапа, код и spiffs.
 

Oleg_M

New member
Swaggaboy6537: Прикладываю 2 измененных файла из этого пул-реквеста....

Мне помогло. Спасибо.
 

Витёк

New member
Здраствуйте! Не удается подключится к ФС NodeMcu через браузер - вечная загрузка... Прошивается всё без ошибок.
Arduino 1.8.13
ESP8266 Boards 2.6.1
Плагин esp8266fs 0.5.0
OS:Linux
 

Витёк

New member
Если залить скетч: "FSBrowser", в браузере загружается страничка с текстом "FS INIT ERROR"
 
Сверху Снизу