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

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

pvvx

Активный участник сообщества
Если в запросе браузера запрашивается файл, то он и открывается для последующей передачи...
При открытии смотрится флаг - парсить его (CGI) или нет, сжатый он или нет...
Открытие файлов происходит по команде CGI ~inc:xfile_name~... Вложенность ~inc:~ ограниченна 4-мя.
...

Есть пара служебных-виртуальных файлов с 'хитрыми' индексами и используются для других целей:
Код:
typedef enum
{
    WEBFS_MAX_HANDLE = 251,
    WEBFS_NODISK_HANDLE,
    WEBFS_WEBCGI_HANDLE,
    WEBFS_UPLOAD_HANDLE
} WEBFS_NUM_HANDLE;
Эти файлы и обрабатываются web_send_fnohanle().
Но вроде у вас вопрос не о них...

Для гадания уточнение того, что связано с файлами в WEBFiles.bin и Web-сервером:

1) Инициализация файловой системы – WEBFSInit()
2) Проверка наличия файла \protect\init.ini. Если есть, то обработка инструкций из него.
3) Запуск WEB сервера.
4) Ожидание запроса от браузера.
5) Разбор параметров запроса браузера. Открытие указанного в URI файла. Если такого нет – ответ ошибки.
6) Передача заголовка ответа броузеру.
7) Передача тела файла с обработкой, если атрибут у файла ‘парсить’, иначе без обработки. Если при обработке указано вложение ещё файла, то открытие нового файла и передача с обработкой и закрытие. И т.д. до открытых 4-х фалов. Если вложенность более, то возврата к первым файлам не будет - они будут закрыты.
8) Завершение данного соединения.
 
Последнее редактирование:

pvvx

Активный участник сообщества
чтобы это проверить, нужно чтобы pvvx пересобрал webbase на новом SDK 2.0.0. У меня с ходу самого не получилось пересобрать библиотеки - теряются ссылки из китайских библиотек на какие-то новые функции, которые при пересборке уходят.
Переход на SDK 2.0.0 (патч1) в стадии начальной обработки.
Пока такие бяки при сборке TCP2UART:
Код:
   Section|                   Description| Start (hex)|   End (hex)|Used space
------------------------------------------------------------------------------
      data|        Initialized Data (RAM)|    3FFE8000|    3FFE838C|     908
    rodata|           ReadOnly Data (RAM)|    3FFE838C|    3FFE8BBC|    2096
       bss|      Uninitialized Data (RAM)|    3FFE8BC0|    3FFEEC48|   24712
      lit4|     Uninitialized Data (IRAM)|    40105958|    401065A0|    3144
      text|          Uncached Code (IRAM)|    40100000|    40105958|   22872
irom0_text|             Cached Code (SPI)|    40207000|    40240694|  235156
------------------------------------------------------------------------------
Entry Point : 4010016C call_user_start()
Total Used RAM : 53732
Free IRam : 6752 or 23136 (option 48k IRAM)
Free Heap : 54204
Total Free RAM : 77340
Итого в отличии от SDK1.5.4 (все меньше на):
IRAM: 848 байт
RAM: 112 байт
irom0_text: 4320 байт
+ и ещё надо доп. сектор для записи настроек (в конце песочницы SDK в 512к) для новой приблуды user_rf_cal_sector_set(), которая передает номер сектора для записи настроек/калибровок WiFi в глобальную переменную uint32 rf_cal_sec.
В итоге имеем уже 5 секторов, которые китай-SDK мучает постоянной записью и 6-ой для esp_init_data_default.bin. Итого на них долой из flash 6*4096=24576 -> 24 кило! :(
И ущё - у китайцев, с их либами и кодом, для их проектов, уже нет места в IRAM :D:p

С такими 'перспективами' от Espressif скоро закат ESP8266. Основная причина - громоздкий код user_interface.o в libmain.a, который содержит 99% хлама и переадресации пользовательских процедур к либам WiFi и т.д. Т.е. является в основном интерфейсной прослойкой для сохранения имен их выдуманных процедур для увеличения кода и стека и тормоза при исполнении, но возможности выкинуть лишнее и не используемое в 90% проектах пользователей нет и не дано.
 
Последнее редактирование:

AlexMelven

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

pvvx

Активный участник сообщества
главное что все эти новые версии ничего нового не дают..
Обновил на git для теста версию с SDK2.0.0. Там пока не подключено сохранение калибровок WiFi, т.е. ещё не полноценная, но работает.
В инициализации SDK теперь совсем страшно - китайцы такое наворотили, что глюков будет на много лет.
Кое-как набросал "первый проход" перевода из disasm в СИ, чтоб ознакомиться что там накрутили... Примерно такой киш-миш -> esp8266web/startup.c at master · pvvx/esp8266web · GitHub :rolleyes:
 

AlexMelven

New member
блин, та же фигня :(
WiFi event(1): Disconnect from ssid ESP8266-1, reason 4, count 1
reconnect
state: 2 -> 0 (0)
f r0, scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 1

connected with ESP8266-1, channel 1
dhcp client start...
cnt
WiFi event(0): Connect to ssid ESP8266-1, channel 1
WiFi event(7): Probe Request (MAC:7c:b1:5d:2b:82:2f, RSSI:-94)
ip:192.168.4.3,mask:255.255.255.0,gw:192.168.4.1
Напомню - прошиваю Web_Base в два модуля, одним соединяюсь к другому. Реконнект каждые 15-20 секунд.
PS. Один раз было что сразу после переподключения, отключился с:
WiFi event(1): Disconnect from ssid ESP8266-1, reason 6, count 1
 
Последнее редактирование:

pvvx

Активный участник сообщества
попробовал соединить два устройства на базе web_base - одно как точка доступа, второе к нему цепляется клиентом. Раз во сколько-то времени клиент отваливается от точки и подцепляется снова. Анализ сообщений показал что при этом приходит Wifi event (1), reason (4), Assoc_expire.
кто-нибудь пробовал соединять их таким образом? Свисток компьютера к точке доступа ESP8266 подключается без отваливаний.
На роутере есть 'Интервал ротации сетевых WPA ключей'. Может это с этим и связано?
Я уже не помню и не проверял, но ранее была беда у подключения с шифрованием у модуля. Когда нарушалась связь, к примеру при удалении модуля на расстояние на малое вермя, то она не возобновлялась, т.к. похоже не происходило смены ключа... в общем потеря ключа... Если соединение без шифрования, то всё было OK.
---
В SDK 2.0.0 изменения у китайцев в основном связаны с напихиванием кучи не оптимизированного кода в процедуру инициализации связанного с калибровками WiFi и изменения загрузки всяких конфигов из Flash. Всё это вставлено 'на скорую руку' как 'патч', но с большим объемом кода. Т.е. наворотили, но не оптимизировали и видно, что вставлено как тест для проверки на пользователях, для оптимизации в следующих версиях... :) А сам баг, из-за которого у них проблема с просыпанием после DEEP-SLEEP они не исправили. :mad:

Я пока не дублировал (не вставлял) этот код в свою инициализацию и не патчил system_deep_sleep_local_2(). По этому время соединения после всяких DEEP-SLEEP может быть долгим...
Напомню - в system_deep_sleep_local_2() последняя команда IO_RTC_2 = 1<<20 вызывае отключение CPU, но при 160 MHz проц успевает выполнить ret и вернуться в код вызова system_deep_sleep_instant(), а она находится в Flash. Но 'кеш' flash отключен и CPU исполняет белиберду с выходом на 'протектед'. При этом, до аппаратного исполнения IO_RTC_2 = 1<<20 застрявшего в fifo шины, успевает записать в RTC что перезагрузка по 'протектед', а не по DEEP-SLEEP. Их программа 'Баунти' не работает - не дают бабло (не перечисляют на счет форума) и писать им давно отказался.
Т.е. надо каждый раз вставлять патч в либу/obj - после IO_RTC_2 = 1<<20 while(1);... А китайцы это исправлять не хотят, а лепят кучу всякого кода в инициализацию по вополям пользователей, что после DEEP-SLEEP установка соединения очень долгая...

PS: libmmain.a для SDK2.0.0 запатчу позже, когда разберусь с бредом, вставленным у китайцев в инициализацию и переведу в свой код. А пока нет времени на это... Лето ещё не закончилось :)
 
Последнее редактирование:

AlexMelven

New member
Сейчас я проверяю коннект при условии, когда нет шифрования и расстояние между модулями - они лежат рядом. Пробовал и в соседние комнаты растаскивать, т.к. читал некий бред от писателя альтернативной MESH сети: "держите модули на некотором расстоянии друг от друга и в метре от пола, иначе они ведут себя нестабильно" - скорее всего он столкнулся с этим же глюком, что постоянный реконнект.
 

pvvx

Активный участник сообщества
Ещё поковырял, но до "Реконнект каждые 15-20 секунд." ещё не успел.
Пока пропатчил уже вечную ошибку SDK для deep-sleep и адаптирую инициализацию в SDK 2.0.0
По скорости соединения ST к роутеру после deep-sleep terminal говорит:
Код:
--- RF calibration after deep-sleep wake up: sys_const[108]=0 ---
12:59:07.734> meSDK 2.0.0
12:59:07.734> Reset event: DeepSleep
12:59:07.734>
.....
12:59:08.164> ip:192.168.1.15,mask:255.255.255.0,gw:192.168.1.1
12:59:08.164> WiFi event(0): Connect to ssid xxxxxxxxxxx, channel 1
12:59:08.164> WiFi event(3): Station ip:192.168.1.15, mask:255.255.255.0, gw:192.168.1.1
12:59:08.164> MDB: init port 502
12:59:08.164> SNTP: start
12:59:08.164> WEB: init port 80
12:59:08.164> NetBIOS init, name 'AESP8266'
...
12:59:10.195> SNTP: Set time: 0x57cd41eb

--- No RF calibration after deep-sleep wake up --
13:00:58.209> meSDK 2.0.0
13:00:58.209> Reset event: DeepSleep
13:00:58.209>
...
13:00:58.658> ip:192.168.1.15,mask:255.255.255.0,gw:192.168.1.1
13:00:58.658> WiFi event(0): Connect to ssid xxxxxxxxxxx, channel 1
13:00:58.658> WiFi event(3): Station ip:192.168.1.15, mask:255.255.255.0, gw:192.168.1.1
13:00:58.658> MDB: init port 502
13:00:58.658> SNTP: start
13:00:58.658> WEB: init port 80
13:00:58.658> NetBIOS init, name 'AESP8266'
....
13:01:00.719> SNTP: Set time: 0x57cd4259
------
Скорость Web/HTTP/TCP передачи в SDK2.0.0 вроде не пострадала.
Google Chrome: WEB-Speed.gif
 
Последнее редактирование:

vad7

Active member
@pvvx, получается 1.5.4 пока самая стабильная. У меня на одном счетчике - Start time: 24.08.2016 2:10:18, да и то в это время свет выключали.
 

pvvx

Активный участник сообщества
@pvvx, получается 1.5.4 пока самая стабильная. У меня на одном счетчике - Start time: 24.08.2016 2:10:18, да и то в это время свет выключали.
2.0.0 мало отличается от 1.5.4. В оф.SDK 2.0.0 вставлено:
1) Поддержка ещё каких-то типов Flash (в текущем meSDK для web-свалки это вырезано)
2) Ускорение старта после deep-sleep (в текущем meSDK для web-свалки ещё не адаптировано до нормы)
3) Какие-то никчемные дополнения, очень редко используемые пользователями (в meSDK вырезано по пределу возможности)
И это всё впихнуто в основном как патч в код инициализации SDK (в esp8266web/startup.c at master · pvvx/esp8266web · GitHub - он не полон, содержит ошибки, но есть то, что необходимо было для адаптации инициализации в meSDK... ).
Как итог - отличий практически нет. Оставшиеся под новые 'фичи' оф. SDK зарезервированные переменные в bss и части кода для их поддержки не столь большие. Всё вырезать пока нет возможности - необходимо полностью перевести в свой код несколько десятков процедур из user_interface.o. А эта задача не стоит сил и трат времени, т.к. в новом SDK всё изменится и каждый раз перелапачивать данное безобразие очень и очень долго.
На текущий момент meSDK 2.0.0 на git ещё в тестовом варианте. Надо проверять, не забыто ли что в инициализации и как это поведет себя, т.к. много выкинуто.
---
'Очистить SDK' от китай фич не удается, т.к. этим я занят один. Основная беда указана - много бреда в libmain.a. Espressif не хочет делать нормальный SDK, как это сделали другие (к примеру в 'Амёбе' для RTL87xx). У других закрытые библиотеки содержат код только низкоуровневой работы с WiFi и можно построить любой собственный интерфейс. А у Espressif закрыт и пользовательско-интерфейсный слой пожирающий большую часть доступной памяти. Т.е. вы не можете использовать даже другой тип TCP стека и написать собственные алгоритмы инициализации, включений и переключений WiFi части и т.д.
В связи с этим я перехожу на модули других производителей. ESP теперь находится в второстепенных задачах, только ради поддержки того, что намутил.
 
Последнее редактирование:

mcmega

Member
К примеру на Реалтек модули… За прошедшее время контроллеры и иx интеграция подросли. ESP8266 уже устаревает.
Скажите, а Вы Web интерфейс там тоже используете? Где можно познакомиться с наработками? А то и вправду с китайцами этими много проблем получается...
 

pvvx

Активный участник сообщества
Скажите, а Вы Web интерфейс там тоже используете? Где можно познакомиться с наработками? А то и вправду с китайцами этими много проблем получается...
Пока только ознакомился с RTL8710AF -> http://esp8266.ru/forum/threads/sravnenie-rtl8710-i-esp8266.1467/#post-21249
Если вопрос по теме WiFi и Web, то:
В данный сезон, начиная с осени, MCU без набортных пол мегабайта RAM+ 2 мегабайта flash с FCLK от 166 MHz уже не считаются современными. Модно ещё с наботными FPU + Security Engine (AES/SHA/DES/MD5..). При этом цена такого чипа должна быть явно менее $6. Всё остальное - это уже отходы старого производства.
Для моих текущих задач требуется чип от 500к RAM с нормальной поддержкой SSL, а так-же требуется web не только с WiFi, но и с LAN. Все уже вышедшие и выходящие новые модули и MCU в этот сезон имеют на борту более 0.5Мег RAM и 2Мег Flash + ROM, >= 166MHz CPU. При этом они кушают меньше ESP8266. Так-же все они базируются на RTOS/FreeRTOS/... и набора из стандартного списка доступных всем библиотек стека TCP и SSL (LwIP + .../CycloneTCP/CycloneSSL/CycloneCrypto/PolarisSSL и т.д.) Т.е. для них возможно создание единой системы из стандартного набора библиотек, чем и занят. Но некоторые либы имеют лицензии, условно - не для всех и проект у меня специфический и не всем нужен. По этому пока ничего не выкладываю. Сделаю что-то, появится время - буду думать об версии с простой лицензией (желательно под Unlicense.org » Unlicense Yourself: Set Your Code Free :) ).
Анализ разных SDK от разных производителей показал, что в некоторые чипы системная часть с более менее полным HTTPS (API+TCP+SSL) для Web (и прочей системной мелочи) укладывается в объем 200..300 килобайт ROM + 200к RAM. Поддержка WiFi - ещё плюс до ~100к ROM и мелочи в RAM (смотря какой WiFi :)).
ESP8266 имеет минимальную базовую часть (сборка только API+WiFi без LwIP и многого другого) от 175 килобайт Flash, ~130к RAM и 32к ROM. Остается максимум до 64к RAM на остальное. Это кошмар и не удивительно, что стандартные либы SSL туда не лезут и сделать на нем что-то полноценное практически невозможно. ESP32 - тоже не лучший кандидат.
 
Последнее редактирование:

Shara

New member
@pvvx, сделал, когда было нужно в стиле тяп-ляп. сейчас возвращаюсь, но на этот раз хочется реализации за которую не будет стыдно. Что из SDK рекомендуете использовать на текущий момент? mySDK + примеры из "свалки"? Или вообще стоит закинуть подальше ESP модули и переориентироваться на что-то другое? Слышал, что у Realtek тоже не всё хорошо с документацией.
 

pvvx

Активный участник сообщества
@pvvx, сделал, когда было нужно в стиле тяп-ляп. сейчас возвращаюсь, но на этот раз хочется реализации за которую не будет стыдно. Что из SDK рекомендуете использовать на текущий момент? mySDK + примеры из "свалки"? Или вообще стоит закинуть подальше ESP модули и переориентироваться на что-то другое? Слышал, что у Realtek тоже не всё хорошо с документацией.
Тут сложно сказать что-либо про Realtek. Всё зависит от 'содружества'. Доки там не нужны, т.к. всё общение с аппаратурой там в ROM и для пользовательских задач не требуется лезть в регистры самому (просто другой подход). Так-же там возможна установка своей операционной системы и стека TCP. Есть SDK Амёба, на ней уже есть Дурина ИДЕ, но на чипе постарше (с 2.5 мегабайта RAM)... Но 'сообщество' мудрит что-то на свой любимый GPL2 и пока ничего, кроме программатора в OpenOCD у них нет :) Это с учетом того, что дешевые модули RTL00V1.0 стали доступны месяц назад и на днях дошли из Китая желающим. Т.е., условно, прошла неделя как модули смогли появиться на руках у многих. До этого были только дорогие Амёбные...
 
Последнее редактирование:

-VenoM-

New member
Если в запросе браузера запрашивается файл, то он и открывается для последующей передачи...
При открытии смотрится флаг - парсить его (CGI) или нет, сжатый он или нет...
Открытие файлов происходит по команде CGI ~inc:xfile_name~... Вложенность ~inc:~ ограниченна 4-мя.
...


Для гадания уточнение того, что связано с файлами в WEBFiles.bin и Web-сервером:

1) Инициализация файловой системы – WEBFSInit()
2) Проверка наличия файла \protect\init.ini. Если есть, то обработка инструкций из него.
3) Запуск WEB сервера.
4) Ожидание запроса от браузера.
5) Разбор параметров запроса браузера. Открытие указанного в URI файла. Если такого нет – ответ ошибки.
6) Передача заголовка ответа броузеру.
7) Передача тела файла с обработкой, если атрибут у файла ‘парсить’, иначе без обработки. Если при обработке указано вложение ещё файла, то открытие нового файла и передача с обработкой и закрытие. И т.д. до открытых 4-х фалов. Если вложенность более, то возврата к первым файлам не будет - они будут закрыты.
8) Завершение данного соединения.

Спасибо за ответ. Вытаскивать из xml-файла значения тэгов со стороны js научился. Теперь задача получить с помощью этих запросов реальные значения переменных/функций ESP. На ум приходят два варианта:
1. Постоянно заполнять соответствующий xml-файл со стороны ESP и тянуть значения тэгов запросами js. Общение наоборот - аналогично. Тут пока не понимаю как парсить xml файл со стороны ESP. Для адруины всё выглядит несложно, но для SDK...
2. Кидать соответствующие запросы и получать ответ.

Запрос:
Код:
   function funonload()
    var xmlhttp;
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
      xmlhttp = false;
    }
  }
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
    xmlhttp = new XMLHttpRequest();
  }
    xmlhttp.open("GET",'callback',false);
    xmlhttp.send();
    var message=xhttp.responseXML;
    document.getElementById('message3').innerHTML = "Получен ответ: "+ xhr.responseText;;
     


}
window.onload = funonload;

Дальше, предполагаю, ESP принимает запрос и выполняется ф-ция:

Код:
* FunctionName : webserver_recv
* Description  : Processing the received data from the server
* Parameters   : arg -- Additional argument to pass to the callback function
*                pusrdata -- The received data (or NULL when the connection has been closed!)
*                length -- The length of received data
* Returns      : none
*
* For HTTP 1.0, this should normally only happen once (if the request fits in one packet).
*
*******************************************************************************/
LOCAL err_t ICACHE_FLASH_ATTR webserver_received_data(TCP_SERV_CONN *ts_conn)
{
}
Где куча условий (файл, тип запроса и т.д.) . Интересует, где проверить, принята ли строка "callback", чтобы дальше обрабатывать запрос?
 

pvvx

Активный участник сообщества
xmlhttp.open("GET",'callback',false);
Дальше, предполагаю, ESP принимает запрос
Запрос будет будет аналогичен 'http://ip_или_имя_модуля/callback' ?
Выходит, что это запрос файла c именем 'callback'.
Если такой файл есть на диске модуля, то он его передаст. Если в нем указаны какие переменные, то они назначаться и передадутся.
Похоже вы не по тому пути идете...
Простейший AJAX предполагает другую систему.
AJAX для новичков
'Обмениваться данными с сервером можно двумя способами. Первый способ — это GET-запрос. В этом запросе вы обращаетесь к документу на сервере, передавая ему аргументы через сам URL. При этом на стороне клиента будет логично использовать функция Javascript`а escape для того, чтобы некоторые данные не прервали запрос.
Не рекомендуется делать GET-запросы к серверу с большими объемами данных. Для этого существует POST-запрос.
'
'Ответ от сервера может быть не только XML, как следует из названия технологии.'

Типичная передача переменных start и stop:
newAJAXCommand('mdb.xml?start=0&stop=100', updateStatus, true);
= http://ip_или_имя_модуля[/текущий_каталог]/mdb.xml?mdb.xml?start=0&stop=100
Модуль назначит переменные start=0 и stop=100, откроет файл mdb.xml, увидит что у него атрибут = "парсить", начнет передавать с поиском команд/переменных, обрамленных '~'. В данном mdb.xml он найдет ~xml_mdb~ и выполнит вставку, описанную в esp8266web/web_int_callbacks.c at master · pvvx/esp8266web · GitHub
и далее esp8266web/web_int_callbacks.c at master · pvvx/esp8266web · GitHub
Т.е. вставит значения ячеек с 0 по 100.
Клиент примет mdb.xml со значениями ячеек... Далее разбираете на java...
Это только один вариант передачи... На обучение работы с javaскрипт времени нет. Уж как нибудь сами или создайте тему...
 
Последнее редактирование:
Сверху Снизу