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

Web-свалка на RTL871x

aloika

Active member
Прошил, в целом работает! Начало положено и это замечательно!

Настройки Wi-Fi не сохраняются, сканирование станций тоже не работает (а, увидел, отключено в коде).

В flasher.mk строка 170 нужно поправить:

-c "rtl8710_flash_write $(BIN_DIR)/WEBFiles.bin 0xd0000" \

там имя файла другое стоит сейчас.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Я имел в виду SSI который просто вставляет переменные в текст страницы как в lwip-шном httpd, т.е. [inline]~имя~[/inline].
Вам про это и написано. + поддержка include фалов c вложенностью до 4-х. [inline]~inc:имя_фала~[/inline]
Это базовый коплект, остальные функции дописывает user.
RTL00_WEB/index.htm at master · pvvx/RTL00_WEB · GitHub
RTL00_WEB/wifi.htm at master · pvvx/RTL00_WEB · GitHub
RTL00_WEB/fullflash.bin at master · pvvx/RTL00_WEB · GitHub
 

pvvx

Активный участник сообщества
Настройки Wi-Fi не сохраняются, сканирование станций тоже не работает (а, увидел, отключено в коде).
Ломаю WiFi API в SDK, переписываю на свой.
По поводу WiFi драйвера. В SDK сейчас реализовано стандартное управление драйвером WiFi через ioctl для Lunix (wireless extensions are for now a set of standard ioctl... VERSION 2.2). Через него всё и работает, но он жрет немерянно... Ver 2.2 стоит в Андроиде...
Этот уровень "слоя" использует перекодировку команд в текстовый вид + данные, далее идет на декодировщик, разбирается и передается ниже уровнем. Слеплено такими слоями по причине поддержки драйвером WiFi и SDIO (код включен в ROM-BIOS). Realtek использует стандартные интерфейсы и имеет кучу чипов, по тому так и написано, для совместимости. Но нам, в случае внутреннего программирования непосредственно в чипе с открытым доступом к любой подпрограмме или структуре драйвера, не нужны эти наслоения, которые занимают большую часть кода... Снимать эти слои долго, но можно - все хидеры от внутренних потрахов WiFi есть... Ошибок нагородить и потом их ловить :) Смысл в этом пропадает, т.к. есть чипы с буквой "M" и лишние сотню кило в RAM для них это проценты от 2.5 Мегабайта... По этому счас пытаюсь оптимизировать только уровень наслоения API. Это уже дало к 20 кило, но может ещё чаго вырежу... Процесс вечный.

Желающие копаться в регистрах, любителям "ногодрыга", т.е. сторонникам подхода от AVR/STM и прочих древней шушары :) - полное описание регистров WiFi в указанных хидерах есть - копайте и накрошите свой драйвер WiFi и для Arduino... :) :)
 
Последнее редактирование:

pvvx

Активный участник сообщества
Alfa версия готова - проверяем. Не все опции в HTML ещё работают (некогда разрисовывать), но они, в основном, ненужные (малоиспользуемые).
и классика UART<->TCP в пару кликов как на esp.
Это будет отдельный проект.
Сначала базовый - только управление WiFi без всего другого. Это более нужная часть для создания любых проектов. Захламить всяким всегда можно отдельно, потом выковыривать будет сложно.
Больше интересует добавка к базе конфигуратора WiFi в виде связи с NCF для просыпания из DeepSleep + активации SoftAP с автоматической связью со смартфоном для дальнейшей конфигурации. Модуль RTL00 имеет NFC в чипе, ноги с чипа не выведены на контакты модуля, но припаять к двум ножкам рамку можно -> NFC и RTL00.

С парольным доступом к страницам и восприятию переменных концепция, для открытой версии web-свалки, ещё не полностью сформировалась.
Пока оно так:
Имеется список из N username и их паролей. Номер в списке имеет приоритет. Т.е. user c большим номером имеет больший доступ. Браузеру сообщается необходимый уровень авторизации для разных ресурсов (realm) "Unauthorized\r\nWWW-Authenticate: Basic realm=\"Protected%u\"". В принципе он формируется из [inline]Protected[/inline] + число уровня user. В файловую систему отметка уровня авторизации пока не введена, т.к. вариантов много и надо что-то выбрать... По умолчанию имена и пароли в текущей прошивке забиты как:
  1. SSID_AP : Password_AP (уровень ноль - будет разрешать установки WiFi),
  2. SSID_ST : Password_SP (уровень ноль - будет разрешать установки WiFi),
  3. rtl871x : webfs_write + разрешение на перезапись webfs,
  4. rtl871x : ota_write + разрешение на перезапись программы,
  5. rtl871x : supervisor - разрешено всё.
Разрешения не доделаны - ожидаются комментарии для выработки правил.
Жду предложения по поводу как осуществлять разграничение авторизации и на что (подстановка разных каталогов фаловой системы?), смену паролей...

Авторизация уровня "зашита от дурака" требуется, т.к. предполагается использование модуля с непосредственным выходом в глобальный инет без брандмауэра и прочих.
 
Последнее редактирование:

GDI

New member
Обычно делают наоборот, чем меньше номер, тем больше дозволено пользователю. Тогда можно обычных пользователей просто добавлять в конец и делать их сколько угодно. Дальше возможны варианты. Например, разделить права в диапазоны номеров, т.е. номера 1-10 - это supervisor-ы, 11-20 - ота и т.д. А лучше сделать для пользователей поле "роль" и там ставить цифру - вот этот Ваш номер
 
Последнее редактирование:

pvvx

Активный участник сообщества
Обычно делают наоборот, чем меньше номер, тем больше дозволено пользователю. Тогда можно обычных пользователей просто добавлять в конец и делать их сколько угодно. Дальше возможны варианты. Например, разделить права в диапазоны номеров, т.е. номера 1-10 - это supervisor-ы, 11-20 - ота и т.д. А лучше сделать для пользователей поле "роль" и там ставить цифру - вот этот Ваш номер
Нам как-бы по ресурсам более 5-ти уровней не нужно. Их просто не на что там заводить, да и ограничения у RTL871xAF, которые все пользуют... В итоге фиксед кол-во users и жесткая привязка. Нумерация по тому безразлична с конца или начала. Cчитать всегда до пяти :)
Может на файлы просто сделать, если папка имеет имя "protected"+число, то это и есть уровень доступа?
Переменные при парсинге просто проверяют (запрос >= уровню) и не отрабатывают далее следующие проверки на совпадения их имен?
Типа:
if("cmd1") {...}
else if("cmd2") {...}
else if(userlevel>x) {
if("cmd3") {...}
else if("cmd4") {...}
else if(userlevel>x+1) {
...
}
}
Надо простой базовый вариант, а кто захочет - тот впишет расширение на группы. Защита паролем в HTTP чисто условная - пароль идет практически открытым текстом. У нас нет возможности на 512 кило RAM сделать HTTPS-WEB...

PS: Вопросы я задаю, т.к. просто некогда даже думать или разобрать тему, других хватает, а так при наводящих ответах проще...
 
Последнее редактирование:

sboganov

Member
if("cmd1") {...}
else if("cmd2") {...}
else if(userlevel>x) {
if("cmd3") {...}
else if("cmd4") {...}
else if(userlevel>x+1) {
...
}
}
Лучше рахделить по уровням и вынести всю безопастность в отдельный класс. Тогда для пользователя должна остатся только одна функция вида checkPermission(context, realm, "cmd1"...). Если никакая безопастность ненужна - то фунция всегда возвращает true. И потом можно будет реазиловать эту функцию и она будут работать через userlevel, или проверять название каталога, или там по ldap запрашивать внешний сервер...
 

pvvx

Активный участник сообщества
Лучше рахделить по уровням и вынести всю безопастность в отдельный класс. Тогда для пользователя должна остатся только одна функция вида checkPermission(context, realm, "cmd1"...). Если никакая безопастность ненужна - то фунция всегда возвращает true. И потом можно будет реазиловать эту функцию и она будут работать через userlevel, или проверять название каталога, или там по ldap запрашивать внешний сервер...
У нас не классическое программирование. При его подходе код Web не лезет вообще в устройства с 512 килобайтами RAM...
Уже пустой проект ESPHTTPD, портированный на RTL выжирает больше RAM, чем данный, со всеми настройками WiFi и отладкой.
По этому всё на компромиссе, с учетом как транслятор переведет в ASM. :) Закон прост - хотите что-то дополнить, извольте сократить другое, чтобы итого в байтах было одинаково. Я вот грызу WiFi драйвер. От него кусок ужался, можно что-то вставить... Итого, при запущенном Web с WiFi + SNTP +mDNS и прочей бижутерии у модуля должно остаться от 128 кило Heap. Иначе это всё в помойку. Т.е. даже алгоритм должен подбираться под оптимум объема выходного кода и данных.
И CLK у нас не ГГц-ы, чтобы каждый раз для сравнения, обращаться к процедурам.
С классическим подходом уже есть Web на Луних с 99% ненужного кода для тормозов и нагрева атмосферы...
Надо всё осмыслить и оптимизнуть, а пока идет набивка, не совсем оптимальная, чтобы потом не забыть, где и какие зависимости... Структурировать такие вещи как Web невозможно - это как создать таблицу пересчета местного времени в каждом селе от Гринвича - основа там нагромождение всякой выдуманной людьми глупости и её наслоения и переплетения... :)
 
Последнее редактирование:

GDI

New member
Вот лично для меня было бы классно сделать веб сервер обособленной библиотекой или куском кода. Чтобы его можно было бы просто папкой вставить в проект на любом кортексе с frertos и lwip. По типу того же lwHTTPD. Кстати, там у чувака сделана авторизация и разделение и пользователей по уровням, и cgi тоже имеют уровень с которым можно получить к ним доступ.
 

aloika

Active member
Alfa версия готова - проверяем.
Прошил, посмотрел. Как сбросить настройки wi-fi к дефолтным значениям? И вообще все настройки? Сейчас я загнал модуль в такое состояние, что AP есть, но при подключении к ней web-сервер не работает почему-то, сайт не открывается. Перепрошивка не помогает.
 

pvvx

Активный участник сообщества
Прошил, посмотрел. Как сбросить настройки wi-fi к дефолтным значениям? И вообще все настройки? Сейчас я загнал модуль в такое состояние, что AP есть, но при подключении к ней web-сервер не работает почему-то, сайт не открывается. Перепрошивка не помогает.
Сброса по пинам пока нет, есть командная строка в LogUART. Наберите "?" и даст описание команд:
Код:
>?
CONSOLE COMMAND SET:
================================
ATST: Memory info
ATLW: LwIP Info
ATSB=<ADDRES(hex)>[,COUNT(dec)]: Dump byte register
ATSD=<ADDRES(hex)>[,COUNT(dec)]: Dump dword register
ATSW=<ADDRES(hex)>,<DATA(hex)>: Set register
ATDS=[TIME(ms)]: Deep sleep
ATSP=<a,r>,<wakelock_status:1|2|4|8>: Power
ATPN=<SSID>[,password[,encryption[,auto-reconnect[,reconnect pause]]]: WIFI Connect to AP
ATPA=<SSID>[,password[,encryption[,channel[,hidden[,max connections]]]]]: Start WIFI AP
ATWR: WIFI Connect, Disconnect
ATWI: WiFi Info
ATWP: WiFi power
ATSN: Scan networks
PR<1/0>: Printf on/off
?: This Help
================================
Переключение режимов WiFi:
  • atwr 0 - выключить WiFi
  • atwr 1 - включить Station
  • atwr 2 - включить SoftAP
  • atwr 3 - включить SoftAP+Station
Есть ещё пару хитрых команд, оставленных для отладки:
  • atwi r n - установить в структуре старта режим старта WiFi
  • atwi l 1023 - установить в структуре старта побитно в числе конфиги для авто-загрузки
  • atwi s 1023 - записать указанные побитно конфиги
Команды в LogUART обрабатываются в двух форматах:
  • в "AT": cmd=p1,p2,,p4,...
  • параметры через пробелы: cmd p1 p2 p3 p4 ...
Параметры могут быть в скобках [inline]"[/inline] или [inline]'[/inline] для передачи в них символов, задействованных для парсинга команд. Пример: " ', e2'" - получится параметр [inline]', e2'[/inline]
Ввод в LogUART не работает в режиме экономии питания. Она отключается, если нет активных процессов - например в SoftAP она работает всегда, т.к. проц почти всегда активен, а в Station - только импульсно на время прием beacon или если идет прием-прередача по WiFi... :) Для реакции на внешние события в режиме экономии обычно используют какой пин или устройство, активирующее модуль в полный режим на время отработки внешнего события. Ввод в LogUART не имеет распределения в PMU и вообще UART-ы включить сразу по перепаду и принять символ невозможно, если они не активны ради экономии питания. В режиме работающей Station (LPS режим) и активных прочих сервисах с опцией экономии питания модуль RTL00 потребляет средних 2.5 мА с активацией на время приема-передачи пакетов по WiFi (в этих случаях ток к 60..70 мА).

Опции старта задаются тут: RTL00_WEB/wifi_user_set.h at master · pvvx/RTL00_WEB · GitHub и есть все комбинации в конфиге до запуска WiFi. Вписываете опрос пинов или ещё чего и меняете эти битики при старте как вам надо... Никто не знает что в вашем проекте надо будет и надо ли сохранять режимы при успешном соединении и прочим действиям с WiFi - всё это и устанавливается, и задается в конфиге по умолчанию, который тоже может сохраняться при изменениях режимов WiFi и использовать загрузку ранее сохраненного по старту (тоже задается :) )...

Жду ответов в темах
WiFi в RTL8195/871x серии
WiFi mode IPS/LPS TDMA/DTIM
или прекращаю отвечать на вопросы - исходники есть и там, как говорят, "черным по белому" всё описано. :)
А то выходит не честно - у меня всего 2 простых вопроса, на которые никто тут не отвечает. :)
 
Последнее редактирование:

pvvx

Активный участник сообщества
Авторизация на 5-ть "левел" встроена, как и описал ранее:
Если каталог или имя файла содержит "protect", то смотрится цифра после этого слова. "protect4" - означает предельный уровень авторизации > 4, просто "protect" или "protect0" -> авторизация > 0. В websock посылается "user=имя:пароль", для установки уровня авторизации. Имя и пароль так-же могут содержать ":". RTL00_WEB/WEBFiles at master · pvvx/RTL00_WEB · GitHub
Авторизация по уровням отключается глобально в установке при трансляции web_srv.h : #define USE_WEB_AUTH_LEVEL 0.
 

pvvx

Активный участник сообщества
Сегодня сравнил Mongoose Web-сервер на ESP8266, пишут что тоже работает непосредственно через LwIP без espconn и т.д.
Объем прошивки к 1 мегабайту, heap до 34 кило, во время работы логер и программы показывающие текущий heap - виснут.
Итого, что выходит в apache-jmeter-3.1 (10 тредов примерно имитируют 2 одновременно открытых окна эксплоррера):
Mongoose1422.gif Mongoose1423.gif Mongoose1424.gif Mongoose1425.gif Mongoose1426.gif
Т.е. кроме ошибок ещё долгое время открытия файла (ответа после соединения).
Итого 517 обращений в минуту к статической странице в сотни байт без парсинга.
 

pvvx

Активный участник сообщества
И RTL8710AF, при тех-же условиях (ip запроса заменен на имя "rtl871x0" и вставлено обращение к файлу "rtl.gif" для примерно одинаковой отдаваемой длины контекста):
Объем прошивки 251384 bytes с отладкой, heap ~130 килобайт, при работе:
Снимок1431.gif
(потребление с дурным стабилизатором 5->3.3 - вычитать 5 мА, все sleep включены, но постоянный опрос по HTTP размера heap не дает упасть до 2.5 mA)
WebRtl1428.gif WebRtl1429.gif WebRtl1430.gif
Итого: 15 666 обращений в минуту к статической странице (файлу на web-диске) в сотни байт без парсинга.
 
Последнее редактирование:

pvvx

Активный участник сообщества
Mongoose Web-сервер на ESP-32S (DevKit плата).
Потребление во время теста:
Снимок1435.gif
(130 мА в покое, включена только Station)
По памяти:
mongoose_poll New heap free LWM: 119480
Tock uptime: 188.291 RAM: 127384
Tick uptime: 189.273 RAM: 126628 ...
Размер только прошивки более 800 килобайт (без boot и fs.img)


apache-jmeter-3.1 (условия предыдущие, замен только ip):
Снимок1436.gif Снимок1437.gif Снимок1438.gif
1413 в минуту, из них 14% error.

PIC32 c разными платами от Microchip тоже есть, но заявленного порта Mongoose на него не наблюдаю...

Вывод - "портировать" Mongoose на RTL или ещё куда не имеет никакого смысла.
 
Последнее редактирование:

lsm

Разработчик Smart.js
Команда форума
@pvvx, не знаю что вы там меряли. Вот мои замеры.
jmeter 3.2, macos.
ESP8266 - nodemcu v2

Ставим Mongoose OS:

Код:
$ mos flash esp8266

Fetching https://mongoose-os.com/downloads/esp8266.zip...
Loaded mjs_base/esp8266 version 1.0 (20170428-121030/???)
Opening /dev/cu.SLAB_USBtoUART...
Connecting to ESP8266 ROM, attempt 1 of 10...
  Connected
Running flasher @ 460800...
  Flasher is running
Flash size: 4194304, params: 0x0240
Deduping...
    2544 @ 0x0 -> 0
 ...
Booting firmware...
All done!
Настраиваем Wifi:
Код:
$ mos wifi SSID PASS
...
Смотрим какой IP:
Код:
$ mos call Sys.GetInfo
{
  "app": "mjs_base",
  "fw_version": "1.0",
  "fw_id": "20170428-121030/???",
  "mac": "1AFE34E14B07",
  "arch": "esp8266",
  "uptime": 6,
  "ram_size": 51968,
  "ram_free": 39324,
  "ram_min_free": 37352,
  "fs_size": 113201,
  "fs_free": 47941,
  "wifi": {
    "sta_ip": "192.168.0.206",
    "ap_ip": "",
    "status": "got ip",
    "ssid": "VMDF554B9"
  }
}
Смотрим - index.html размером 825 байт:
Код:
$ curl http://192.168.0.206/  |wc
      22      68     825
Запускаем jmeter, на index.html, работает 2 минуты. 10 threads:
Screen Shot 2017-04-30 at 11.21.50.png Screen Shot 2017-04-30 at 11.22.05.png Screen Shot 2017-04-30 at 11.22.11.png


Итого - 5915 запросов за 2 минуты, ошибок - 0.17%.

Сейчас повторю на ESP32 devkitc.
 

lsm

Разработчик Smart.js
Команда форума
Так, esp32 devkitc.

Процедура настройки модуля - та же самая, только в команде прошивки не esp8266, а esp32.

Код:
$ mos flash esp32
Результат:
Screen Shot 2017-04-30 at 11.43.11.png Screen Shot 2017-04-30 at 11.43.16.png Screen Shot 2017-04-30 at 11.43.20.png Screen Shot 2017-04-30 at 11.43.23.png Screen Shot 2017-04-30 at 11.43.27.png

За 60 секунд: запросов 2198, ошибок - 0.41%.

На обеих прошивках по умолчанию крутится blink пример на javascript - https://github.com/cesanta/dev/blob/master/fw/examples/mjs_base/fs/init.js .
 

Neov

Member
в project/src/web/web_int_vars.c добавьте [inline]extern QueueHandle_t xQueueWebSrv;[/inline]

в
Код:
ifdef USE_FATFS
SRC_C += sdk/component/common/file_system/fatfs/fatfs_ext/src/ff_driver.c
SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/diskio.c
SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/ff.c
SRC_C += sdk/component/common/file_system/fatfs/r0.10c/src/option/ccsbcs.c
SRC_C += sdk/component/common/file_system/fatfs/disk_if/src/sdcard.c
endif
добавьте соответствующий [inline]INCLUDES += sdk/component/common/file_system/fatfs[/inline]
 
Последнее редактирование:

pvvx

Активный участник сообщества
Итого - 5915 запросов за 2 минуты, ошибок - 0.17%.
На RTL8710AF при 40 тредах ошибок 0% за час (но на надо выключить WDT или вписать подтверждение где в цикл - сейчас он вписан только в IDLE).
На RTL8711AМ при 80 тредах ошибок 0% за час (но на надо выключить WDT или вписать подтверждение где в цикл - сейчас он вписан только в IDLE). Для большего кол-ва тредов надо снять ограничение по умолчанию в инициализации web на 99 одновременно открытых соединений.
При этом в RTL учитывается TIME_WAIT, а у вас - нет.
Тут делается подобие многопользовательского Web, а у вас одиночный запрос с ограничением на 5-ть открытых соединений, т.е. для одиночной открытой страницы эксплорера. Если в вашем "web" снять ограничения, то всё равно не получим более десятка одновременных - кончится RAM. И смотреть как заливается страница на вашей версии тоже никто не хочет - у вас открытие файлов и общая реакция соединения переваливает за 2 секунды на страничках с несколькими вложениями файлов и парсингом переменных когда отрыто одновременно уже пара соединений. Меняйте файловую систему и интерпретатор на более оптимизированный. По другому у вас не выйдет - у вас другое назначение системы и оно не годиться для надежного web. Ведь вся ваша система рассчитана на мигание светодиодом и не более. Других функций она не выполняет, т.к. нет других драйверов для связи с периферийными устройствами кроме "ногодрыга". Потому и сравнение не корректно.
Кароче - гуляйте и делайте далее свою Arduino с Java. Специфика тут разная и я ищу оптимизированные подходы для web, более малый код имеет меньше ошибок, тем более web на RTL ещё в alpha версии и не все оптимизированные алгоритмы в него вставлены - не успел, а стоят куски из прошлой Web-свалки. Почерпнуть у вашего web просто нечего - по тому "портировать" его или куски из него не вижу смысла.
Если потребуется исполнение скриптов java - движок на ARM есть в mbed.

PS: Но прикольно выходит - я в качестве хобби и не программист затратил на данный web на RTL не более 4-х дней, но ошибок тесты не дают, а у вас там целая команда "профессионалов" занимающаяся годами и итог - ошибки при эмуляции 2-х открытых окон эксплорера :) По этому подумайте, прежде чем сравнивать своё и что тут. Разная весовая категория. :p
Если хотите сравнивать - берите ESPHTTPD - его построил не один человек и тесторов там было больше. Будете сравнивать у кого процент ошибок при 10 тредах в apache-jmeter больше :)
 
Последнее редактирование:
Сверху Снизу