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

Баги и недосмотры в sdk от espressif

pvvx

Активный участник сообщества
Основные баги от Espressif для SDK 0.9.3 в их отвратительном и лажевом espconn:

Кол-во одновременно открытых соединений можно изменить в espconn_tcp_set_max_con(x). Но espconn пользуется массивом из 5 структур remot_info premot[5], размещенной в постоянной памяти. Соответственно, при указании кол-ва соединений более 5 она испортит память за данным массивом структур :)

При закрытии tcpсоединения, espconn часто теряет событие disconnect. Тем самым, отведенные, и так по максимуму 5 соединений, заполняются и остаются занятыми. Получаем ошибку ESPCONN_CONN = - 11. Освобождение внутренних структур espconn у Espressif для занятых соединений сделано некорректно – лезут в Lwip по запомненному указателю на когда-то живую структуру pcb и что-то там сравнивают :). Но структура уже исключена из списка активных и неактивных соединений в Lwip-е. Память может быть затерта уже другими процедурами, а может и нет. В итоге, от значений там, зависит освободит или нет espconn занятый блок на соединение :) Дополнительно это дает путаницу номерков соединений в ATпрошивке :)
Только эти баги уже напрочь закрывают возможность пользоваться любыми интернет соединениями с ESP8266 на любых прошивках, основанных на текущем SDK, без грубых 'хаков'. А багов ещё очень много и не описываю, пока не конкретизированы их конкретные источники. Т.е. писать 'надстройки' на текущий SDK преждевременно.
 
Последнее редактирование:

Andy Korg

Moderator
Команда форума
Жалко конечно, что такие баги. Но видно кто-то обходит их. Вот эта прошивка http://git.spritesserver.nl/esphttpd.git/ вроде как довольно стабильно работает. Мне правда так и не удалось ее скомпилировать.
 

pvvx

Активный участник сообщества
В той “прошивке” https://github.com/mziwisky/esp8266-dev те-же баги. Она работает с espconn.

Конкретно:
espconn_server_close ставит таймер на espconn_sclose_cb:

os_timer_setfn(&psclose->pcommon.ptimer, espconn_sclose_cb, psclose);

os_timer_arm(&psclose->pcommon.ptimer, TCP_FAST_INTERVAL, 0);

espconn_sclose_cb, спустя время таймера, смотрит состояние у передаваемой структуры, в которой указана старая ссылка на pcb в стеке Lwip-а. К этому моменту данная pcb может быть уже исключена из списка и этот кусок памяти освобожден lwip-ом. По состоянию байт в данном куске памяти espconn_sclose_cb снова ставит таймер и так продолжается, пока в данном куске памяти не выпадут подходящие значения для espconn_sclose_cb (некий байт там не станет равен значению CLOSED или TIME_WAIT) :) Когда нибудь ей повезет и тогда будет вызван calback disconnect-а пользователя. А пока не везет, занят таймер и disconnect-а соединения нет. А “везет” ей тогда, когда в данную область памяти Lwip распределит другой pcb, от другого соединения, и у него будет состояние CLOSED или TIME_WAIT… Тогда disconnect для “потерянного соединения” завершится. Но если этот кусок памяти Heap занял кто-то другой и распределение памяти сдвинулось, то по вероятности 2 к 256, зависящей от ожидаемого там espconn_sclose_cb значения байта завершится disconnect для “потерянного соединения” :)
Это ошибка в алгоритме ecpconn и патчем не лечится. Обходится путем использования Lwip напрямую, без espconn от "чудаков" из Espressif.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Есть ещё такая беда. При приеме через соединение tcp, установленное в espconn, нет возможности управления скоростью входного потока. Это сказывается всегда, когда имеем входной поток tcp более чем успеваем обработать. Пример – надо принять файл длиной более имеющегося буфера в памяти Heap. Пусть для записи во flash или передачи по UART. Функция работы со стеком espconn tcp будет выдавать блоки со скоростью ограниченной только соединением wifi (это более мегобайта в секунду). В итоге имеем или переполнение памяти и потерю информации - придется отбрасывать, то что не влезает и повторять всё с начала. На tcp стеке это решается через управление окном приема WIN в TCP (в Lwip это есть), но espconn не предоставляет таких средств управления и такие задачи на ней не решить. Только если использовать нестандартные надвески над протоколами – на передающей стороне резать передаваемую информацию на куски и следить, как тама модуль с espconn, проглотил прошлый кусок и уже можно давать следующий (?) :)

----------
С lwip это организуется так:

Ставим throttle_data_reception = true.

После этого по tcp будет принято в организованный буфер RAM до WIN + пара пакетов cдлиной MSS. Окно WIN tcp в SDK с Lwip1.4.0 у ESP8266 = 4*MSS, MSS=1460 байт. Следовательно, буфер c резервом, надо на 6*MSS = 8760 байт.

В процедуре приема:

err_t callback_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)

{

….

if (throttle_data_reception) unrecved_bytes += p->tot_len;

else tcp_recved(pcb, p->tot_len); // сообщает стеку, что можно посылать ACK и принимать новые данные.

….

}

Когда данные обработаны, вызываем tcp_recved(pcb, unrecved_bytes), чем позволяем стеку и всем кто там за ним, передачу нам следующих байт. Таким образом мы можем принять и обработать бесконечный поток с ограниченной скоростью приема, без потерь ...
----------

Как заключение – имеющийся SDK рассчитан на работу по tcp с предельными сообщениями до пары килобайт и обработке одного активного соединения (что лезет в организованный буфер в RAM– это до 8 кбайт, с учетом распределения RAM для работы остального ПО).
Остальные (все!) писанные на сегодня надстройки на SDK от Espressif, использующие espconn, имеют описанные ограничения и баги. :)
 
Последнее редактирование:

CHERTS

Moderator
Команда форума
Судя по всему стек lwip в SDK не самый свежий, в офф. репозитарии активно исправляются баги http://git.savannah.gnu.org/cgit/lwip.git

pvvx а можешь привести простенький пример нативной рабоыт с lwip, например на примере организации tcp-сервера или клиента?
 

pvvx

Активный участник сообщества
Что-то не видать тут никакого “сообщества” – никто не делиться информацией по SDK... :)
Не вижу смысла, т.к. они уже есть в примерах у Lwip.
Используемая версия Lwip 1.4.0 в SDK нормальная. Её писали не в Espressif (только "портировали" - там всего до 10 вставок и задан свой конфиг) и ошибок в ней практически нет. Те, что есть, это не ошибки, а недочеты с нововведениями и в новых версиях Lwip их и обсуждают. Нам это не требуется. У нас задача освоить пусть и "старый стек" - нет смысла гоняться за номерками.
Пример будет, но позже. Необходимо "культурное" мультиплатформенное внешнее ПО по созданию диска с файлами, дизайн страниц сервера и много другой мелочи, никак не относящейся к ПО на самой ESP8266. Пока это не слеплю - примера не будет. А одному это тяжко и долго...

Например не решен вопрос, что делать со скатыванием закрытых соединений с TIME_WAIT и переполнением от них памяти. Это актуально, когда на HTTP сервер ESP8266 заходят через proxy. Большинство proxy не закрывают соединение первыми (им не нужны "отложения" на 60 сек) и приходится серверу http закрывать их самому, наращивая "отложения" в "TIME-WAIT PCB states" в итак малой памяти ESP8266... А пока соединение не закрыто браузер ждет и выходит "медленный сайт". Остальное с http сервером у меня уже решено (обработка "парсера" страниц, файловая система, запросы и установки всех параметров имеющихся у ESP8266, куки, имитация cgi и другое) и он "летает" - обрабатывает соединения с потоком в свой предел по полосе wifi.
 
Последнее редактирование:

CHERTS

Moderator
Команда форума
Что-то не видать тут никакого “сообщества” – никто не делиться информацией по SDK... :)
Да как бы все пока в зачаточной стадии по ESP8266, сообщество отталкивает отсутствие нормальной оффициальной поддержки.
Я вот потихоньку пишу статьи, вот сегодняшняя http://geektimes.ru/post/242669/
Но это чисто баловство, вчера наконец то с горем пополам собрал компилятор xtensa-lx106-elf-gcc под Win x86, а то в сети под Win x64 он болтается, не очень удобно. C xtensa-lx106-elf-g++ компилятором засада, не собирается, куча ошибок вылазит. Ззаодно libhal от сообщества собрал, вроде пока мои тестовые прошивки нормально работают, сейчас буду пробовать работать напрямую с lwip, без espconn.
Где бы вот нарять исходники libmain, libphy, libpp, libnet80211 для исследования.
 

pvvx

Активный участник сообщества
++ не требуется. "Мало памяти" у ESP8266. Мультизадачка - туда-же. Всё это не актуально на имеющихся ресурсах у ESP8266. Всякие интерпретаторы разных языков с единственной целью - для настройки параметров связи модуля - это "погоня за лейбочками" и не более. Актуально только для обучения создателя такого приложения, но никак не требуется простому пользователю.
Не забываем, что памяти heap у нас всего до 30 килобайт, при этом любое и каждое соединение с сетью требует иметь там резерв от 8 кило, плюс на активные ещё от 300 байт, как минимум ... В итоге имеем всего до десятка килобайт памяти на всё приложение.
Это “частично” компенсируется скоростью проца и увеличения программной части. Но тогда имеем ограничение в размере flаsh с заданной разметкой от Espressif...
 
Последнее редактирование:

CHERTS

Moderator
Команда форума
Мультизадачка - туда-же. Всё это не актуально на имеющихся ресурсах у ESP8266. Всякие интерпретаторы разных языков с единственной целью - для настройки параметров связи модуля - это "погоня за лейбочками" и не более. Актуально только для обучения создателя такого приложения, но никак не требуется простому пользователю.
Абсолютно согласен про многозадачность и то, что всякие интерпретаторы типа lua и micro-python не нужны, чистый Си и только он.

pvvx если не секрет, то откуда так много знаний о ESP8266 ?
 

Andy Korg

Moderator
Команда форума
Да как бы все пока в зачаточной стадии по ESP8266, сообщество отталкивает отсутствие нормальной оффициальной поддержки.
Мало времени еще прошло. Сам только-только начал читать SDK
... вчера наконец то с горем пополам собрал компилятор xtensa-lx106-elf-gcc под Win x86, а то в сети под Win x64 он болтается, не очень удобно....
Вот и я то же специально поставил wi64, что бы компилятор запустить. Под win32 так и не получилось запустить?
 

pvvx

Активный участник сообщества
pvvx если не секрет, то откуда так много знаний о ESP8266 ?
Купил у китайцев десяток модулей и пытаюсь сделать из них то, что мне надо. Всё остальное из инета. Я не проф. программист, на народных поделках бизнеса не делаю (что будет доведено до нормальной стадии всегда выкладываю в открытый доступ). Правда, со времен появления первых MCU (более 25 лет) занимаюсь созданием разных поделок на них, начиная с решения задачи как это сделать, до серийного выпуска (т.е. полный цикл разработки) ...
Вы хотели пример с http без espconn. Взял пару примеров из Lwip http://download.savannah.gnu.org/releases/lwip/

HTTPd_sample https://yadi.sk/d/YPTjTr5UdJbt9

Собран для конфигурации под windows, указанной тут http://geektimes.ru/post/241842/ (но там автор :) не задал правильные опции -D для компиляции Iot в Makefile (!) )

При старте проверяет, находится или нет модуль в режиме STATIONAP_MODE. Если нет, то пытается его поставить данный режим с опциями подключения, указанными в user_config.h.
UART-ы ставятся в 115200 Baud, UART0 и UART1 меняются местами, для последующей загрузки flashиз Eclipse, чтобы не переключать портов.
При старте выводит в UART:

SDK version:0.9.3
NetBIOS init, name 'ESP8266 '
UDP Test port 1025 init
HTTPD init

Тестовый UDPпорт (1025) открывается на соединение ESP8266 к базовой станции.
Запросы в Тестовый UDP порт:

W? – WiFi info (информация по WiFi):

Chip_id: 0099acf1 AP_id:0 sys_time:3957beb2 ADC:21
OPMode:3 SSID:'ESP8266' Pwd:'0123456789' Ch:13 Authmode:4 MaxCon:4 Phu:3 ACon:1
Connect status:5
heapsize: 34096

C? – info Lwip pcb (списки соединений tcp у Lwip):

HeapSize: 33608
Active PCB states:
Port 80|1139 flg:00 tmr:0a03 ESTABLISHED
Listen PCB states:
Port 80|48093 flg:84 tmr:7308752d LISTEN
TIME-WAIT PCB states:
Port 80|1138 flg:30 tmr:09da TIME_WAIT

H? - system_get_free_heap_size:
HeapSize: 34096

R? - system_restart()

0? - system_set_os_print(0) (отключить вывод системной информации в UART)

1? - system_set_os_print(1) (включить вывод системной информации в UART)

PS: беда с пробелами, после английских символов - так работает местный движок, при вставке текста из других редакторов и исправлять надоело :(
 
Последнее редактирование:

CHERTS

Moderator
Команда форума
Вот и я то же специально поставил wi64, что бы компилятор запустить. Под win32 так и не получилось запустить?
Все получилось, читайте мою статью http://geektimes.ru/post/242669/, там в начале сылки на Espressif ESP8266 DevKit x86 под Win x86

Собран для конфигурации под windows, указанной тут http://geektimes.ru/post/241842/ (но там автор :) не задал правильные опции -D для компиляции Iot в Makefile (!) )
Собсно автор этой статьи Я ;) А что там не верно в Makefile? Скиньте правильный, я подправлю в DevKit.

За пример спасибо, сейчас изучу.
 

pvvx

Активный участник сообщества
Собсно автор этой статьи Я ;)
А там и сказано " :) "
CFLAGS = -Os -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH -DLWIP_OPEN_SRC -DPBUF_RSV_FOR_WLAN -DEBUF_LWIP
За пример спасибо, сейчас изучу.
Там обычный демо Httpd и Netbios от Lwip.
Netbios для приколу - позволяет обращаться по имени в локальной сети http://имя wifi модуля. Длина имени ограничена 16 символами - берутся первые 16 от имени wifi ...
Это может вызвать радостный ажиотаж броузера с поиском WPAD файла :)
http://ubuntu-faq.blogspot.ru/2013/11/wpad-proxy-pac.html
Wireshark:
49.604574000 сек 192.168.4.101 -> 192.168.4.1 HTTP GET /wpad.dat HTTP/1.1
116.779580000 сек 192.168.4.101 -> 192.168.4.1 HTTP GET /wpad.dat HTTP/1.1
...
 
Последнее редактирование:

CHERTS

Moderator
Команда форума
Сверху Снизу