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

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

aloika

Active member
Pvvx, подскажите пожалуйста.

Ситуация такая:
Ваша сборка-свалка, SDK 1.5.2. Но проявляется также и на 2.0.0.

При работе AP подключаюсь к ESP8266 телефоном и компьютером, потом отключаюсь и тем и тем, потом снова подключаюсь телефоном. Иногда (не всегда) вместо WEB: init port 80 в логе появляется tcpsrv: not new tcp! . Естественно, web не работает.
(Как будто бы что-то не успевает закрыться, а я открываю новое)

Через некоторое время нормальная работа восстанавливается (иногда нужно переподключиться).

Я вижу в коде фразу эту tcpsrv: not new tcp! . Судя по коду, она тогда появляется, когда не получается выделить память под новый tcp_pcb.

Почему такое происходит? И как с этим бороться?
Если отключить модбас (он мне не нужен) - лучше будет?

И не может это быть оттого, что я поставил esp8266web\app\sdklib\lwip\core\init.c MEMP_NUM_TCP_PCB = 40; ?
 
Последнее редактирование:

pvvx

Активный участник сообщества
При работе AP подключаюсь к ESP8266 телефоном и компьютером, потом отключаюсь и тем и тем, потом снова подключаюсь телефоном. Иногда (не всегда) вместо WEB: init port 80 в логе появляется tcpsrv: not new tcp! .
Это вроде исправлено было тут:
esp8266web/tcp_srv_conn.c at master · pvvx/esp8266web · GitHub
 

aloika

Active member
Да, я вижу, что по сравнению с SDK 1.5.2. там многое изменилось и попытки исправить были, но, к сожалению - проблема присутствует.

Проще всего проблему можно повторить так:

- Подключаем к АР телефон (андроид)
- Подключаем к АР планшет (андроид)
- отключаем телефон
- отключаем планшет
- подключаем телефон - получаем "not new tcp!"
 

pvvx

Активный участник сообщества
Да, я вижу, что по сравнению с SDK 1.5.2. там многое изменилось и попытки исправить были, но, к сожалению - проблема присутствует.

Проще всего проблему можно повторить так:

- Подключаем к АР телефон (андроид)
- Подключаем к АР планшет (андроид)
- отключаем телефон
- отключаем планшет
- подключаем телефон - получаем "not new tcp!"
Я знаю, что там есть проблема. Она просто не решается. Reopen порта тоже не работает - убивать все соединения насмерть при отключении тоже не вариант - возникают другие проблемы - при разрыве и новом подключении комп и другое оборудование сходит с ума, т.к. ESP открывает соединение на тех-же портах, что незаконно без паузы в 120 сек (TIME_WAIT) если произошел разрыв... идут одни реконнекты по TCP, а ESP не врубается, что творит и соединения становятся по байту в час... Управление netif-ами у Espressif в соответствии с состояниями WiFi нет. Рандома тоже нет - это так-же приводит к бешенству всех на линии, если включить ESP и пресбросить - она лезет в тот-же порт по старту к примеру на комп, как ни в чем не бывало :) - итог описан - по байту в час, пока устройства не успокоятся, закрыв разорванное ранее соединение.
Возможно, что ESP не всегда посылает разрыв соединения WiFi - тогда по линии бы проходила команда на переинициализацию всех сопутствующих открытых соединений и связей к данном устройству (таблицы роуты и прочее)...
Кароче, лечить весь этот бардак в ESP нет никакого желания. Пусть Espressif лечит. Просите у них :)

Вообще закрытие портов сделано для экономии питания, чтобы в LwIP не отрабатывали таймеры и прочее, а прошивка вечно сидела на команде в ets_run() пониженного потребления, ожидая только аппаратные прерывания, когда активных соединений у WiFi нет. :) Уберите закрытие по любым событиям WiFi порта Web (80), и он будет пожизненно работать :p Единственное, что нужно перезапускать - это клиентов, лезущих во вне - SNTP или если TCP2UART лезет к внешнему серверу - при новом соединении их надо перезапустить, т.к. может смениться путь и прочее... так-же если IP не фиксирован у staion на внешней AP...
 
Последнее редактирование:

aloika

Active member
Уберите закрытие по любым событиям WiFi порта Web (80), и он будет пожизненно работать :p
Это мне подходит, спасибо за совет.
Вот я так вот поступил:

Код:
void ICACHE_FLASH_ATTR close_all_service(void)
{
#if DEBUGSOO > 1
    os_printf("Close all except WEB (MK):\n");
#endif
    if(flg_open_all_service) {
#ifdef USE_NETBIOS
        netbios_off();
#endif
#ifdef USE_TCP2UART
        tcp2uart_close();
#endif
#ifdef USE_MODBUS
        mdb_tcp_close(); // mdb_tcp_init(0);
#endif
#ifdef USE_WEB
    //    if(syscfg.web_port) webserver_close(syscfg.web_port); // webserver_init(0);
#endif
    //    tcpsrv_close_all();
        flg_open_all_service = false;
    }
}
т.е. закомментировал webserver_close и tcpsrv_close_all.

Ну и вроде работает, как задумывалось.
Но зачем вообще tcpsrv_close_all ? В ней три действия... не до конца мне понятных. Может быть, из них что-то нужно оставить?
 

pvvx

Активный участник сообщества
Не подскажите, что это у вас за приложение для отображения отладки по udp используется и где его взять?
Купить с модулем, но не ESP :) - > [USR-TCP-Test] Testing Software V1.3 | USR IOT
(да, и поаккуратнее там, на данном сайте - в части софта с него неоднократно вылавливал вирусы...)
 
  • Like
Реакции: vad7

vad7

Active member
Я тут один момент обнаружил в вебсервере:
Если пытаешься загрузить на место диска обычный файл размером больше 32кb, то браузер пишет: ERR_CONNECTION_RESET.
memi0x00000000[1400] rec 1400 of 1400 :
srv[80] 192.168.0.220:62989 [1] read: 1400 tst_rx: 200, 1, 32929 rx:32929[1400] recved_bytes=1400
bufi[1400]0, cont:32929 find_bndr len=143,ret=1 name:'file' filename:'1.bin' trim#147
bufi[1253]0, cont:32782 tst,fn='1.bin'(file) ERR1 ret u_b: 200,f108 resp=61706 prh#f10a,200,16 #f10a (83) 302 dis
tcpsrv_server_close (0x3fff0018)
tcpsrv: check 0 tm pcb
srv[80] 192.168.0.220:62989 [1] disconnect
cf254

А если меньше 32к, то как и должно быть disk_er1.htm - Image Corrupt or Wrong Version.

Причем в логах одно и то же в обоих случаях, только добавляется после:
srv[80] 192.168.0.220:63057 [1] listen
memi0x00000000[581] rec 581 of 581 :
srv[80] 192.168.0.220:63057 [1] read: 581 http_ver=11 of1[disk_er1.htm]
 

vad7

Active member
@pvvx, попробовал отладку по UDP.
В момент загрузки вебдиска при включенной отладке, происходит такое, после успешной загрузки около 16к:
memi0x3fff7380[3062] rec 1400 of 3062 :
srv[80] 192.168.0.220:49953 [1] read: 3062 tst_rx: 200, 1, 90862 rx:90862[3062] recved_bytes=1400
bufi[3062]0, cont:90862 fdata ret=0
Write to 0x47000, len=2048, block_size=2048, c_len=90862, sbry= 38, r=0, d=-19144, l=3062trim#2048
bufi[1014]0, cont:88814 fdata ret u_b: 0,7108 no boundary ...
WiFi event(7): Probe Request (MAC:f0:5b:7b:b5:09:dc, RSSI:-93)
WiFi event(7): Probe Request (MAC:00:1e:64:9f:04:9e, RSSI:-59)
srv[80] 192.168.0.220:49953 [1] poll: 0 #4, 5,5
srv[80] 192.168.0.220:49953 [1] poll: 1 #4, 5,5
...
srv[80] 192.168.0.220:49953 [1] poll: 2 #4, 5,5
...
srv[80] 192.168.0.220:49953 [1] poll: 3 #4, 5,5
...
srv[80] 192.168.0.220:49953 [1] poll: 4 #4, 5,5
...
srv[80] 192.168.0.220:49953 [1] poll: 5 #4, 5,5
tcpsrv_server_close (0x3fff02a8)
srv[80] 192.168.0.220:49953 [1] disconnect
Далее:
no buf for action frame

И, наконец:
Fatal exception (29):
epc1=0x4000e1b2, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

Поймать глюк с помощью udplog не получится. :(
 

vad7

Active member
Иногда, правда, не сразу падает - нет несколько минут коннекта, только потом ексепшн:
state: 5 -> 2 (10c0)
rm 0
WiFi event(1): Disconnect from ssid HOME, reason(16): Ie_in_4way_differs, count 1 (rt=30)
Close all:
WEB: close
state: 2 -> 0 (0)
WiFi event(1): Disconnect from ssid HOME, reason(202): Auth_fail, count 2 (rt=30)
Close all:
WiFi event(7): Probe Request (MAC:00:1e:64:9f:04:9e, RSSI:-60)
scandone
state: 0 -> 2 (b0)
state: 2 -> 0 (2)
reconnect
WiFi event(1): Disconnect from ssid HOME, reason(2): Auth_expire, count 3 (rt=30)
scandone
Set reconnect after 30 sec
Close all:
....
New connect ST...
...
Fatal exception (29):
epc1=0x4000e1b2, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

Иногда еще такая фигня вылазит: srv[80] new listen - low heap size!
 
Последнее редактирование:

vad7

Active member
@pvvx, еще наблюдения за вебсервером:
Скачиваю с модуля всю флеш (4Mbyte):
Если быстро выбрать место на диске - то все ок.

Если долго выбирать (скачка все равно начинается сама), то через несколько секунд соединение рвется:
srv[80] 192.168.0.220:52017 [1] send: rcb 0012ee39..0012f911 #22d8,2776 ....
srv[80] 192.168.0.220:52017 [1] send: rcb 0012f911..001303e9 #22d8,2776 ....
srv[80] 192.168.0.220:52017 [1] send: rcb 001303e9..00130ec1 #22d8,2776 ....
WiFi event(7): Probe Request (MAC:a4:4e:31:50:13:c0, RSSI:-94)
srv[80] 192.168.0.220:52017 [1] send: rcb 00130ec1..00131999 #22d8,2776 ....
srv[80] 192.168.0.220:52017 [1] send: rcb 00131999..00131f0a fr3:0x3fff0768<-0x00131f0a[1]
#22d8,1393 ....
WiFi event(7): Probe Request (MAC:00:1e:64:9f:04:9e, RSSI:-56)
srv[80] 192.168.0.220:52017 [1] poll: 0 #4, 5,5
WiFi event(7): Probe Request (MAC:00:1e:64:9f:04:9e, RSSI:-59)
WiFi event(7): Probe Request (MAC:54:27:1e:c1:35:8b, RSSI:-80)
srv[80] 192.168.0.220:52017 [1] poll: 1 #4, 5,5
WiFi event(7): Probe Request (MAC:54:27:1e:c1:35:8b, RSSI:-81)
srv[80] 192.168.0.220:52017 [1] poll: 2 #4, 5,5
WiFi event(7): Probe Request (MAC:00:1e:64:9f:04:9e, RSSI:-59)
srv[80] 192.168.0.220:52017 [1] poll: 3 #4, 5,5
srv[80] 192.168.0.220:52017 [1] poll: 4 #4, 5,5
srv[80] 192.168.0.220:52017 [1] poll: 5 #4, 5,5
tcpsrv_server_close (0x3fff0020)
srv[80] 192.168.0.220:52017 [1] disconnect
Если включить оверлей udplog - и быстро выбрать место - рвется соединение.
rv[80] 192.168.0.220:52028 [1] send: rcb 001e5dff..001e68d7 #22d8,2776 ....
WiFi event(7): Probe Request (MAC:1c:e6:2b:11:f1:df, RSSI:-87)
srv[80] 192.168.0.220:52028 [1] send: rcb 001e68d7..001e6e48 fr3:0x3fff12b8<-0x001e6e48[1]
#22d8,1393 ....
srv[80] 192.168.0.220:52028 [1] poll: 0 #4, 5,5
WiFi event(7): Probe Request (MAC:00:1e:64:9f:04:9e, RSSI:-56)
WiFi event(7): Probe Request (MAC:00:1e:64:9f:04:9e, RSSI:-60)
srv[80] 192.168.0.220:52028 [1] poll: 1 #4, 5,5
При включенном udplog, если выбирать дольше - Fatal exception (0) здесь:
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
4021160c: d0c112 addi a1, a1, -48
 

pvvx

Активный участник сообщества
@pvvx, еще наблюдения за вебсервером:
Скачиваю с модуля всю флеш (4Mbyte):
Если быстро выбрать место на диске - то все ок.

Если долго выбирать (скачка все равно начинается сама), то через несколько секунд соединение рвется:
А чего ему бы ему не рваться? По умолчанию стоит дисконект по 5 сек тишины от клиента.
---
После этого:
scandone
state: 0 -> 2 (b0)
state: 2 -> 0 (2)
из потрохов WiFi драйвера может быть что угодно -> пишите письма в Espressif - они вам ответят: "Спасибо за интерес к продукции Espressif!" и на этом всё :)

Это вообще чудо "no buf for action frame" от драйвера WiFi - вылезает когда он не справляется со своими прямыми обязанностями - передавать пакеты :)
Вместо простого предупреждения и скипания пакета, что льете "через силу" (поток более чем тянет его устаревший HT20 WiFi) он что-то делает некому ненужное... Никаких ограничений для заливки UDP вообще нет, Espressif драйвер WiFi просто накроется после этого соо... У всех других продолжит работать, выводя кол-во скипнутых пакетов :p
Ну умер уже ESP8266, а ESP-32 никуда не годиться. Пытаться писать что-то на них - мазохизм. Будете няньчиться с данными тамогочами всю жизнь... Нуль встроенной отладки в SDK (On/Off) и прочего отладочного ПО к ним, да полная убогость на сегодня. Espressif пишет, в своих доках, что SDK надо от 1 Мег Flash и пользователю выделено всего до 40 к RAM. Куда с такими характеристиками в 2017 году?
 
Последнее редактирование:

vad7

Active member
@pvvx, да это понятно, просто еще как я понял этот веб-сервер вы планируете использовать и дальше в других модулях.
В нем похоже есть какая-то нестабильность.

Вот сейчас откатил tcp_srv_conn.c на лето прошлого года и теперь по крайней мере соединение при скачивании рваться перестало - неважно, быстро ли ты выбираешь место или нет. Так же из-за этого не падает с udplog.
Но вот запись вебдиска во влеш также падает с udplog-ом.

Я уже и очистку блока флеши убрал (оставил только сектора), чтоб поменьше времени на ней зависало...
 

pvvx

Активный участник сообщества
@pvvx, да это понятно, просто еще как я понял этот веб-сервер вы планируете использовать и дальше в других модулях.
В нем похоже есть какая-то нестабильность.

Вот сейчас откатил tcp_srv_conn.c на лето прошлого года и теперь по крайней мере соединение при скачивании рваться перестало - неважно, быстро ли ты выбираешь место или нет. Так же из-за этого не падает с udplog.
Но вот запись вебдиска во влеш также падает с udplog-ом.

Я уже и очистку блока флеши убрал (оставил только сектора), чтоб поменьше времени на ней зависало...
На других модулях ядро работает, а глюков с WiFi нет, т.к. RTOS - процессы разные и приоритеты у них ставятся. Падало при записи в flash на любом SDK, ... при процессе записи надо менять CLK на 80 МГц и пробовать переставлять местами процедуры, размеры блоков, может какие-то сообщения в лог вписать как задержку вместо delay()... В общем маяться с бубном вокруг текущего WiFi драйвера. Падает только при большой скорости потока... И всё заброшено - надоело - обновлений SDK всё равно нет и никакого смысла делать что-то более "демки на вечер" на ESP8266 на сегодня нет. Старая версия на старом SDK работает и имеет одну ошибку - с PullUp вроде (её и пользуйте), а новою, на новых SDK, не сделать. Причина банальная - не работает данный чип с имеющимся WiFi драйвером при требуемых мне условиях - пример: тупой показометр потребления на INA219. Помирает station и дырявят выходной поток, на любом SDK и ПО (хоть Arduino). Нулевая стабильность работы.
Когда задача тупая, типа несколько байт в час или RS-232 до 115200 типа modbus и модуль сидит на твердом питании и один у AP, то вроде как работает. Если к нему что-то подключается (типа стоит в лаб.БП в качестве измерителя) и рядом другие модули с WiFi, особенно если меряет питание другого модуля с WiFi - то полные кранты - и часа стабильной работы в таких условиях не достигнете (при этом испытуемый модуль другого производителя и стоящий те-же 1xx руб, на плавающем питании которое не может показывать ESP8266 сидящий на собственном стабильном(!), работает без данных глюков). Это говорит о том, что ESP8266 не жилец, когда рядом пробегают большие уровни в его диапазоне WiFi (по тем-же проводам хоть GND, что включаются к другому модулю).
 
Последнее редактирование:

vad7

Active member
@pvvx, хорошо, а нам, то что делать, прикладным разработчикам?
Я уже и так кучу времени убил ковыряясь с этими глюками, вместо того, чтобы дальше библиотеку доступа к счетчику дописывать.

Альтернативы то пока нету?
rtl модули на пробу уже заказал, но с ним тоже еще не все гладко и библиотеки вебсервера нету.
 

pvvx

Активный участник сообщества
@pvvx, хорошо, а нам, то что делать, прикладным разработчикам?
Я уже и так кучу времени убил ковыряясь с этими глюками, вместо того, чтобы дальше библиотеку доступа к счетчику дописывать.

Альтернативы то пока нету?
rtl модули на пробу уже заказал, но с ним тоже еще не все гладко и библиотеки вебсервера нету.
Там уже есть HTTPD c websocket - он работает и проблем особых из-за наличия больших ресурсов у него нет. Практически напрямую к нему подключается microSD c web-сервером на 32 Гегобайта. :) 128 и более ещё не пробовал.
 

PostLast

Member
Добрый день! Хочу реализовать реализовать анонс на сервер по UDP с информацией IP и мак модуля при его регистрации в сети. Сейчас, насколько я понимаю IP модуля получается в ip_current_netif()->ip_addr.addr
но функция работает только при получении данных в соответствии с описанием. Как получить IP модуля сразу после регистрации в сети?
 

PostLast

Member
Я ценю ваш юмор Но я в трех соснах заблудился. как выдернуть upcb->offered_ip_addr
Хотя я его и на стороне сервера могу определить;)
 
Последнее редактирование:

pvvx

Активный участник сообщества
Я ценю ваш юмор Но я в трех соснах заблудился. как выдернуть upcb->offered_ip_addr
Хотя я его и на стороне сервера могу определить;)
Там есть стандарный драйвер событий, по нему всё и работает. Событие получения IP и запускает/открывает все сокеты web и т.д... Так что шутки там не было. :(
 
Сверху Снизу