• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

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

Paul_B

Member
Сам столкнулся с проблемой описанной здесь: Новые ревизии модулей на базе ESP8266 не умеют писать в SPI Flash
Отлаженный проект, работающий на 10 модулях вдруг перестает работать на новом модуле, достал еще один - тот же эффект.
Китайские поставщики начали использовать микросхему flash-памяти производства PUYA. Это привело к поломке драйверов SPIFFS, которые обычно используюся для сохранения настроек в модулях ESP8266.
Лечиться заменой функции в файле Esp.cpp вот функция, на которую надо поменять. Она универсальная, работает на любых ревизиях модулей. Правда на модулях с памятью puya работает, понятно, медленнее, но работает.
Код:
bool EspClass::flashWrite(uint32_t offset, uint32_t *data, size_t size) {
    static uint32_t flash_chip_id = 0;
        uint32_t *read_buf=NULL;
    if (flash_chip_id == 0)
        flash_chip_id = getFlashChipId();
    ets_isr_mask(FLASH_INT_MASK);
    int rc;
    uint32_t* ptr = data;
    if ((flash_chip_id & 0x000000ff) == 0x85) { // 0x146085 PUYA
        read_buf=new uint32_t [SPI_FLASH_SEC_SIZE / 4];
        if(!read_buf) return false;
        rc = spi_flash_read(offset, read_buf, size);
        if (rc != 0) {
            delete read_buf;
            ets_isr_unmask(FLASH_INT_MASK);
            return false;
        }
        for (size_t i = 0; i < size / 4; ++i) {
            read_buf[i] &= data[i];
        }
        ptr = read_buf;
    }
    rc = spi_flash_write(offset, ptr, size);
        if(read_buf!=NULL) delete read_buf;
    ets_isr_unmask(FLASH_INT_MASK);
    return rc == 0;
}
 
Последнее редактирование:

Алексей.

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

Алексей.

Active member
Лечиться заменой функции в файле Esp.cpp вот функция, на которую надо поменять. Она универсальная, работает на любых ревизиях модулей. Правда на модулях с памятью puya работает, понятно, медленнее, но работает.
Если память не puya то код работает быстрее прежнего?:)
Непонятно почему не под #ifdef - ом, ведь когда собираем - точно знаем зачем это делаем.
 

Paul_B

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

Алексей.

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