Скрыть объявление
На нашем форуме недоступен просмотр изображений для неавторизованных пользователей. Если Вы уже зарегистрированы на нашем форуме, то можете войти. Если у Вас еще нет аккаунта, мы будем рады, если Вы к нам присоединитесь. Зарегистрироваться Вы можете здесь.

Делюсь опытом Новые ревизии модулей на базе ESP8266 не умеют писать в SPI Flash...

Тема в разделе "Железные вопросы по esp8266", создана пользователем Paul_B, 9 окт 2018.

  1. Paul_B

    Paul_B Новичок

    Сообщения:
    149
    Симпатии:
    3
    Сам столкнулся с проблемой описанной здесь: Новые ревизии модулей на базе ESP8266 не умеют писать в SPI Flash
    Отлаженный проект, работающий на 10 модулях вдруг перестает работать на новом модуле, достал еще один - тот же эффект.
    Китайские поставщики начали использовать микросхему flash-памяти производства PUYA. Это привело к поломке драйверов SPIFFS, которые обычно используюся для сохранения настроек в модулях ESP8266.
    Лечиться заменой функции в файле Esp.cpp вот функция, на которую надо поменять. Она универсальная, работает на любых ревизиях модулей. Правда на модулях с памятью puya работает, понятно, медленнее, но работает.
    Код (Text):
    1. bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
    2.     static uint32_t flash_chip_id = 0;
    3.         uint32_t *read_buf=NULL;
    4.     if (flash_chip_id == 0)
    5.         flash_chip_id = getFlashChipId();
    6.     ets_isr_mask(FLASH_INT_MASK);
    7.     int rc;
    8.     uint32_t* ptr = data;
    9.     if ((flash_chip_id & 0x000000ff) == 0x85) { // 0x146085 PUYA
    10.         read_buf=new uint32_t [SPI_FLASH_SEC_SIZE / 4];
    11.         if(!read_buf) return false;
    12.         rc = spi_flash_read(offset, read_buf, size);
    13.         if (rc != 0) {
    14.             delete read_buf;
    15.             ets_isr_unmask(FLASH_INT_MASK);
    16.             return false;
    17.         }
    18.         for (size_t i = 0; i < size / 4; ++i) {
    19.             read_buf[i] &= data[i];
    20.         }
    21.         ptr = read_buf;
    22.     }
    23.     rc = spi_flash_write(offset, ptr, size);
    24.         if(read_buf!=NULL) delete read_buf;
    25.     ets_isr_unmask(FLASH_INT_MASK);
    26.     return rc == 0;
    27. }
     
    Последнее редактирование: 9 окт 2018
  2. Paul_B

    Paul_B Новичок

    Сообщения:
    149
    Симпатии:
    3
    Не работала конкретно запись из скетча в SPIFFS. Файлы читались, если заливать bin-образ SPIFFS вначале.
     
  3. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    543
    Симпатии:
    63
    Paul_B,
    Забавный код, на строке 10 выделяем буфер, на строке 22 освобождаем, а если не смогли успешно выполнить вызов spi_flash_read на строке 11, то про выделенный буфер забываем и выходим из метода на строке 14.
    Типа у нас и так всё работает, а те у кого лики вдруг повалятся, сами пусть ищут где память течет.
    Узнаю стиль примеров из MSDN
     
  4. Paul_B

    Paul_B Новичок

    Сообщения:
    149
    Симпатии:
    3
    Подправил.
    Нет, они изначально предложили static массив. Который у меня жрал лишних 4К памяти, что было непомерно много.
     
  5. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    543
    Симпатии:
    63
    Если память не puya то код работает быстрее прежнего?:)
    Непонятно почему не под #ifdef - ом, ведь когда собираем - точно знаем зачем это делаем.
     
  6. Paul_B

    Paul_B Новичок

    Сообщения:
    149
    Симпатии:
    3
    Если не puya, работает так же, вот оригинальная функция:
    Код (Text):
    1. bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
    2.     ets_isr_mask(FLASH_INT_MASK);
    3.     int rc = spi_flash_write(offset, (uint32_t*) data, size);
    4.     ets_isr_unmask(FLASH_INT_MASK);
    5.     return rc == 0;
    6. }
    7.  
    Дело в том, что у меня универсальный код, который заливается при обновлении bin-фалом через http. Как показала практика, модуль с puya может встретиться на ровном месте, не хочу каждый раз править файл ручками и потом компилировать.
    Я купил партию ESP-7 где-то полгода назад, вот сейчас начал ставить их в нетребовательные устройства, когда не заработал, ночь просидел, хотел уже все выбросить, ан нет, заработало. Медленно, но заработало.
     
  7. Алексей.

    Алексей. Авторитетный участник сообщества

    Сообщения:
    543
    Симпатии:
    63
    Прежде чем выполнить обновление чего-то нужно сначала инициализировать чем-то. Иначе как то не получается.
    У вас начальная загрузка отсутствует? Тогда понятно, модули приходят уже с памятью разного типа и уже готовые к обновлению.
    У меня задача по проще (не те объемы чтоб прогруженные модули заказывать), на производстве модули сначала должны пройти диагностику и после отправятся на сборку, чтоб не залить чего лишнего, сначала определяем что за зверь, а уж потом заливаем. Типа попался 'Manufacturer: E0 85' - значит память puya
     
    Последнее редактирование: 9 окт 2018

Поделиться этой страницей