• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Разработка ‘библиотеки’ малого webсервера на esp8266.

pvvx

Активный участник сообщества
pvvx, возможно как-то откатить самому, чтобы вернулась поддержка ESP-01? У меня пока только эта модель(везде в магазинах только такие), а с алиэкспресса посылка может идти 50 дней, сами знаете )
Всё работает на ESP-01. Последние дополнения как раз писал и тестил на ESP-01.
Увидел, что закомментирована функция os_strcat, она приводит к проблемам? У меня она пока работает...
Для поддержки os_strcat надо подключать ещё либу типа libmicroc.a или совсем толстую libc.a. Потом раскоментить //#define os_strcat strcat в osapi.h и описать прототип strcat()...
А это включение отжирает килобайты, просто так, на какие-то никому не нужные заголовки и иниты для данных либ ... и процедуры из данных либ не могут работать с данными в IRAM или FLASH. Остальное необходимое, кроме этой strcat(), всё есть уже. Проще написать свою strcat() - меньше отожрет RAM + IRAM + FLASH.
Код:
char *strcat(char *dest, const char *src)
{
os_strcpy(dest + os_strlen(dest), src);
return dest;
}
Но скорее всего у вас это: :)

Если увеличиваете объем кода и данных в проекте, то необходимо:

Странслировать проект и посмотреть полученный размер esp8266web\bin\0x00000.bin. Если он больше 0x06000, тогда вычислить и изменить:
[inline]SizeSeg0 = ((размер 0x00000.bin)+0xFFF)&0x7F000[/inline]
В файле eagle.app.v6.ld вычислить и заменить:
[inline]irom0_0_seg : org = (0x40200000 + SizeSeg0), len = (0x79000 - SizeSeg0)[/inline]
В корневом файле проекта Makefile заменить на вычисленное значение:
[inline]ADDR_FW2 = (SizeSeg0)[/inline]
Далее, для вычисления нового стартового адреса файловой системы на 512к Flash, только если используете прошивку его в Eclipse, то проще снова странслировать проект и посмотреть конечный адрес irom0_text в консоли транслятора:
[inline]irom0_text| Cached Code (SPI)| 40206000| 40238700| 206592[/inline]
к нему (0x38700) прибавить 4096 и обнулить 12 бит:
[inline]addr_webfs = (addr+0x1000)&7F000[/inline]
После этого, в корневом файле проекта Makefile исправить:
[inline]USERFADDR=(addr_webfs)[/inline]
 
Последнее редактирование:

codavr

New member
в один прекрасный момент перестала работать заливка файловой системы.
с таким вот логом:
srv[80] 192.168.4.2:50544 [1] read: 2912 ...
srv[80] 192.168.4.2:50544 [1] read: 2324 ...
srv[80] 192.168.4.2:50544 [1] read: 1736 ...
srv[80] 192.168.4.2:50544 [1] read: 3196 ...
srv[80] 192.168.4.2:50544 [1] read: 2204
Disk init: 58 files, addr = 0x00080000

Disk init: 58 files, addr = 0x00080000
head[82]:302 dis
mac 599

и всё. модуль висит, ни на что не откликается.
после передёргивания питания работает. в файловой системе протёрта дыра по адресам 8b800-90000. похоже стирал и записывал, да до конца не дошёл.

ладно, думаю, щас [HASHTAG]#define[/HASHTAG] DEBUGSOO 6 пропишу и на чистую воду тебя выведу.
но после прописывания заливка проходит отлично. в терминале, понятно, флуд...
после прописывания обратно DEBUGSOO 2, глюк возвращается.
мысли пока кончились...

и ещё один момент с первым вопросом не связанный:
прочитал allflash.bin и обнаружил:
Код:
003FD0A0: FF FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF  │         .     
003FD0B0: 0A 00 00 00 45 53 50 5F 46 43 41 33 35 30 00 00  │...ESP_FCA350..
003FD0C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  │................
003FD0D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  │................
раньше там было чисто. как ей (sdk) это удалось?
т.е. эту память тоже можно как-то видеть через окно в адресном пространстве, а не лазить через регистры.
 
Последнее редактирование:

pvvx

Активный участник сообщества
после передёргивания питания работает. в файловой системе протёрта дыра по адресам 8b800-90000. похоже стирал и записывал, да до конца не дошёл.

ладно, думаю, щас [HASHTAG]#define[/HASHTAG] DEBUGSOO 6 пропишу и на чистую воду тебя выведу.
но после прописывания заливка проходит отлично. в терминале, понятно, флуд...
после прописывания обратно DEBUGSOO 2, глюк возвращается.
мысли пока кончились...
Есть намек - выключить sleep у WiFi на NONE :) Данный китай алго пашет за счет десятикратных и стократных увеличений периодов таймера распределяющего задачи у LwIP...
Глюк по поводу работы WiFi при стирании Flash китаё уже 2 раза чинили. Не думаю, что оно опять вылезло... Ранее данный глюк устранялся вставкой задержек где не попадя, чтоб размылить паузы между занятой Flash... Включение доп.дебаг соо дает эти паузы между записью и стиранием flash и наверно успевает обратывать какие прерывания от WiFi части....

и ещё один момент с первым вопросом не связанный:
прочитал allflash.bin и обнаружил:
Код:
003FD0A0: FF FF FF FF FF FF FF FF FF 00 FF FF FF FF FF FF  │         .
003FD0B0: 0A 00 00 00 45 53 50 5F 46 43 41 33 35 30 00 00  │...ESP_FCA350..
003FD0C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  │................
003FD0D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  │................
раньше там было чисто. как ей (sdk) это удалось?
т.е. эту память тоже можно как-то видеть через окно в адресном пространстве, а не лазить через регистры.
Оно-китаё пишет это через wifi_param_save_protect_with_check() путем обычной тормозной работы с SPI. + Возможно ставили опцию большего размера Flash и заливали туда чаго-то, отличное от web-свалки. Т.к. в web-свалке для китаё-SDK flashchip->chip_size (размер flash в байтах) всегда 512k и она не может прыгнуть больше :)
В вашем дампе наблюдаем стандартное сохранение 888 байт (в SDK 1.3.0) struct s_wifi_store:
uint32 ap_ssid_len; //+176 //+0x0B0
uint8 ap_ssid[32]; //+180 // +0x0B4

flashchip->chip_size можно задать и в 32 кило, тогда SDK будет сохранять свои настройки начиная с 16 килобайт отступа от начала Flash. Больше это число в flashchip->chip_size ни на что не влияет. Пока, не влияет, а далее наверно уже близок конец этим китаё процедурам в моё web-свалке - ещё немного "пореверсил" недавно и эту часть пора переписывать на свой код...
 
Последнее редактирование:

Tomahawk

New member
pvvx, спасибо за помощь :) файл 0x00000.bin меньше 0x06000.bin в 8 раз, поэтому дело не в этом оказалось. Мне помог пересчёт адреса USERFADDR по вашей методике, он стал 0x38000 вместо 0x39000.
 

codavr

New member
выключить sleep у WiFi на NONE
на страничке wifi settings опция sleep mode значится NONE. или где её выключать?


наваял в качестве пробы пера вывод списка файлов в браузер:
Код:
     442 0002 404.htm
     262 0002 adc.htm
      10 0000 adc.wav
      61 0002 adc.xml
     109 0002 disk_er1.htm
      99 0002 disk_er2.htm
      87 0002 disk_er3.htm
      93 0002 disk_ok.htm
    6571 0000 esp.gif
     810 0001 favicon.ico
     296 0000 footer.inc
    5094 0001 grf.js
    2003 0000 grfx1.inc
     341 0000 grfx2.inc
     282 0002 heap.htm
      68 0002 heap.xml
     721 0002 index.htm
     162 0002 led.xml
     393 0000 logo.gif
     881 0000 menu.inc
    1104 0002 sample.htm
     495 0001 scripts.js
    1318 0001 site.js
    1210 0001 style.css
    3865 0002 system.xml
     195 0000 time.inc
     540 0002 timeout.htm
     433 0000 timer.inc
     266 0002 tst.htm
      91 0002 tst.xml
     266 0002 vdd.htm
     232 0000 vdd.inc
     105 0002 vdd.xml
      79 0002 protect/chiprams.xml
     888 0001 protect/cookie.js
    2135 0002 protect/debug.htm
    1857 0002 protect/dsleep.htm
      17 0002 protect/esp_init_data_default.bin
      10 0002 protect/filelist.txt
      15 0002 protect/fullflash.bin
    2452 0002 protect/gpio.htm
    1268 0002 protect/gpio.xml
    1678 0002 protect/hexdmpb.htm
       9 0002 protect/hexdmpb.txt
    1726 0002 protect/hexdmpd.htm
       9 0002 protect/hexdmpd.txt
       9 0002 protect/ram.bin
    6666 0002 protect/rfinit1.htm
    7106 0002 protect/rfinit2.htm
    4908 0002 protect/rfinit3.htm
    3276 0002 protect/scan.htm
      78 0002 protect/scan.xml
    4151 0002 protect/setup.htm
    2633 0002 protect/tstfuncs.htm
    4133 0002 protect/uart.htm
    1352 0002 protect/udpwave.htm
     862 0002 protect/upload.htm
    6214 0002 protect/wifi.htm
Files: 58
надо кому-нибудь?
также есть дамп флеш-памяти туда же (вместо обычного адресного пространства по адресам от 0 до 0x20000000, всё равно там ресет при чтении)
 
Последнее редактирование:

pvvx

Активный участник сообщества
pvvx, спасибо за помощь :) файл 0x00000.bin меньше 0x06000.bin в 8 раз, поэтому дело не в этом оказалось. Мне помог пересчёт адреса USERFADDR по вашей методике, он стал 0x38000 вместо 0x39000.
Надо сделать как-то, чтоб автоматически исправлялось. Но пока не знаю как это сделать без громадных и путанных скриптов...
также есть дамп флеш-памяти туда же (вместо обычного адресного пространства по адресам от 0 до 0x20000000, всё равно там ресет при чтении)
Проверка на чтение адресов вызывающих ошибку защиты не доделана в области 0x600xxxxx и выше.
Да и все эти функции не для пользователей, а для отладки и изучения ESP8266.
 
Последнее редактирование:

pvvx

Активный участник сообщества
ага. я заметил.. но пока тоже не стал доделывать :)
Там непонятная область (типа "темной материи" :) ) в 0x60009800..0x6000A000...
Немного обновил меню Download Bin в последнем git.
И вывел счетчик стирания для перезаписи секторов сохранения настроек китай-частью в Debug and Test
Народ пишет, что у некоторых тех, кто делал системы передающие значения с датчиков и использующие deep-sleep, после нескольких месяцев непрерывной работы модуля он приходит в негодность. Возможно это всё связано с протиранием дырки в области сохранения настроек WiFi по алго от горе-китай-программистов или сделано специально, чтобы покупали новые модули :) В последних SDK каждый рестарт модуля вызывает два стирания и записи сектора в области 0x7F000 и двух ниже... При изменение настроек WiFi и переключения модуля к другой AP тоже стираются и пишутся эти сектора. Подробнее там
 
Последнее редактирование:

pvvx

Активный участник сообщества
100тыс стираний должна выдерживать?
если неск. месяцев, то получается каждые 3 минуты трёт?
Чаше - deep-sleep обычно ставят на промежуток менее 3-х минут, а Flash в модули китаё-продаваны ставят самую отстойную :)
В этих последних 16 кило (для SDK 1.3.0 в 20 кило) сохраняется всего 888 байт конфига и лежит 128 esp_init_data_default.bin. Проверки на то, что пишется одно и то-же в эти 888 байт так-же нет, а просто стирают 2 сектора и переписывают.
Espressif! - этим всё сказано :) В Дуринах для ESP8266 эмуляция EEPROM сделана аналогично :)

Пока приходится всё это терпеть, т.к. выдрать user_interface.o из libmain.a с заменой его сотни процедур на свои не выходит. Слишком много обращений к ещё не "реверснутым" функциям и данным, и каждая новая SDK имеет там изменения.
 
Последнее редактирование:

codavr

New member
т.е. это бы решило проблему?
Код:
void wifi_param_save_protect_with_check(uint16 startsector, int sectorsize, void *pdata, uint16 len)
{
    uint8 * pbuf = pvPortMalloc(len);
    int i;
    if(pbuf == NULL) return;
                      spi_flash_read(startsector*sectorsize, pbuf, len);  
                      i = ets_memcmp(pdata, pbuf, len);
                      if (i)
    do {
        spi_flash_erase_sector(startsector);
        spi_flash_write(startsector*sectorsize, pdata, len);
        spi_flash_read(startsector*sectorsize, pbuf, len);
        i = ets_memcmp(pdata, pbuf, len);
        if(i) {
            os_printf("[W]sec %x error\n", startsector);
        }
    } while(i != 0);
    vPortFree(pbuf);
}
настройки каждые 3 мин не меняются?
 

pvvx

Активный участник сообщества
т.е. это бы решило проблему?
Код:
void wifi_param_save_protect_with_check(uint16 startsector, int sectorsize, void *pdata, uint16 len)
{
    uint8 * pbuf = pvPortMalloc(len);
    int i;
    if(pbuf == NULL) return;
                      spi_flash_read(startsector*sectorsize, pbuf, len); 
                      i = ets_memcmp(pdata, pbuf, len);
                      if (i)
    do {
        spi_flash_erase_sector(startsector);
        spi_flash_write(startsector*sectorsize, pdata, len);
        spi_flash_read(startsector*sectorsize, pbuf, len);
        i = ets_memcmp(pdata, pbuf, len);
        if(i) {
            os_printf("[W]sec %x error\n", startsector);
        }
    } while(i != 0);
    vPortFree(pbuf);
}
настройки каждые 3 мин не меняются?
Частично бы решило, т.к. во ввсех используемых Flash сектор имеет размер 4096 байт и поддерживает дозапись. Т.е. в один сектор можно сохранить 4096/888 = 4 раза, не стирая его.
 

codavr

New member
ну значит так:

Код:
void wifi_param_save_protect_with_check(uint16 startsector, int sectorsize, void *pdata, uint16 len)
{
    uint8 * pbuf = pvPortMalloc(len);
    int i;
    if(pbuf == NULL) return;
                     spi_flash_write(startsector*sectorsize, pdata, len);
                     spi_flash_read(startsector*sectorsize, pbuf, len);
                     i = ets_memcmp(pdata, pbuf, len);
                     if(i)
    do {
        spi_flash_erase_sector(startsector);
        spi_flash_write(startsector*sectorsize, pdata, len);
        spi_flash_read(startsector*sectorsize, pbuf, len);
        i = ets_memcmp(pdata, pbuf, len);
        if(i) {
            os_printf("[W]sec %x error\n", startsector);
        }
    } while(i != 0);
    vPortFree(pbuf);
}
выдрать user_interface.o из libmain.a с заменой его сотни процедур на свои
а нельзя в бинарной либе испортить имя и пусть линковщик найдёт это имя в другой либе?
т.е. заменить только избранные функции.
 
Последнее редактирование:

pvvx

Активный участник сообщества
а нельзя в бинарной либе испортить имя и пусть линковщик найдёт это имя в другой либе?
т.е. заменить только избранные функции.
Можно, но зачем лишний код в Fash занимающий место? В энтой user_interface.o - 75% ненужного никому с простой переадресацией на другие либы. Это последний .obj в libmain.a чтобы вообще выкинуть libmain.a. Тогда останутся только куски от libphy.a, libwpa.a, libnet80211.a, libpp.a от всего китай-SDK.
 

codavr

New member
ну как я понимаю, лишний код во флеш пока не столь критичен, как отказ модулей через полгода. нет?

Это последний .obj в libmain.a чтобы вообще выкинуть libmain.a
так я не понял, там мало или слишком много незаменимого кода? :)

(поставил на всякий случай иду....)
 
Последнее редактирование:

pvvx

Активный участник сообщества
ну как я понимаю, лишний код во флеш пока не столь критичен, как отказ модулей через полгода. нет?
Это происходит только у Дуринщинков и всяких Lua-шников. Загрузчик SDK полностью есть, а грузить функционал WiFi каждый раз при просыпании для опроса датчика нет никакого смыслу, тем более это стократно увеличивает потребление в модели автономного устройства...
Да и патчить для замены функций ничего не надо
Есть опции линковщику: -Wl,--wrap=имя_функции
Далее в СИ пишите
тип __wrap_имя_функции(аргументы)
{
а обращение к старой выглядит так __real_имя_функции(аргументы);
}
 
Последнее редактирование:

pvvx

Активный участник сообщества
И ещё раз - нет никакого смысла плодить такие китай-оптимизированные процедуры и их алгоритмы, к примеру как wifi_get_opmode_default(). Там для чтения одного байта в памяти создается буфер на килобайт и он считывается тормозным обращением через SPI к Flash, не проверяя даже ошибку выделения памяти и т.д. :)

PS: С полностью открытым SDK всего одна проблема - с данным вопросом работаю один. Как показала практика за почти год - другим это не требуется. У них у всех один ответ - "дешево-сердито" и предпочитают питание кака...ми :)
 
Последнее редактирование:

codavr

New member
всего одна проблема - с данным вопросом работаю один
могу сказать спасибо :) но что это изменит?
кто-то вроде даже материально помочь хотел...



модуль при старте выдаёт такую строчку:
UDP Test port 1025 init... Ok
в начале функции
udp_test_port_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port)
прописано:
os_printf("udp " IPSTR ":%u [%d]\n", IP2STR(addr), port, p->tot_len);

я отправляю модулю udp-пакеты, но в терминале тишина....
 
Последнее редактирование:

pvvx

Активный участник сообщества
я отправляю модулю udp-пакеты, но в терминале тишина....
Надо засылать запросы с "буква" + "?". Список в app\user\udp_test_port.c
Например 'A?' - тогда ответит :)
Это просто пример UDP и иногда используется для отладки... в последних версиях он отключен в user_config.h:
// [HASHTAG]#define[/HASHTAG] UDP_TEST_PORT 1025 // включить контрольный порт UDP
 
Сверху Снизу