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

Общие вопросы по Arduino IDE для ESP8266

anakod

Moderator
Команда форума
Да, это очень мощный функционал. Насколько я понимаю, всё это можно обернуть в библиотеки. При этом останется базовая совместимость с Arduino и совместимые API для работы с WiFi и TCP/IP, но также появится куча мощных функций. Внутри библиотек при этом можно делать все что угодно — использовать lwip напрямую, не использовать String и т.п.
Если мы сможем адаптировать ваши библиотеки (веб-сервер, http, ftp, spi, sleep modes и т.д.) для компиляции в составе Arduino, мне кажется, будет очень крутое решение.
По идее - да, но пока не особо понятна возможная реализация. Дело в том что Sming использует нативный для LWIP подход - асинхронные callback вызовы (но при этом красиво оборачивает их чтобы пользователю не нужно было думать о внутренней части). Ардуино - напротив работает в loop модели с последовательным вводом-выводом.

Вообще вариант интеграции Sming с данным проектом мог бы быть как раз по линии веб серверы + файловая система. Т.е. если пользователь хочет использовать классические Ардуиновские WEB сервера - пожалуйста, подключает библиотеку, использует. Если хочет большего функционала - подключает Sming библиотеку(библиотеки), получает более полноценный HTTP клиент\сервер с файловым хранилищем и полноценными шаблонами.

@igrr, какие у Вас есть идеи по этому поводу?
 

pvvx

Активный участник сообщества
Дело в том что Sming использует нативный для LWIP подход - асинхронные callback вызовы
Ещё не известно, не подхвачена ли в них "зараза" от espconn. Бегло смотрев исходники в данной библиотеке не нашел отличий алгоритмов обращений от espconn - всё те-же самые ошибки: нет проверки закрыто или нет соединение, если, к примеру идет обращение "со стороны" (таймер или ещё чаго) по старому указателю на pcb (которого уже нет или там разместился новый), а не отработка callback вызванной самой LwIP c выданным текущем указателем на pcb. :)
 

anakod

Moderator
Команда форума
pvvx, Sming подразумевает что ведущая роль в работе сервера за ним. Т.е. он сам вызывает callback когда ждет фрагмент данных. Более того - сохранять указатель на открытое соединение - явно грубое нарушение, т.к. конечный пользователь ничего о нем не знает и нигде его не имеет/не хранит, кроме момента вызова внутри callback.

Проще показывать на примере: https://github.com/anakod/Sming/blob/master/HttpServer_Bootstrap/app/application.cpp

А так - любой код может содержать ошибки, от них никто не застрахован. Хорошо бы иметь UNIT тесты, но как создать тестовую среду? По эмуляторам пока вроде все слабовато..
 

Victor

Administrator
Команда форума
@igrr , есть вот такая идея реализации прошивки модуля по воздуху.
А что если для прошивки ESP8266 использовать вторую ESP8266?
Эту, вторую, условно назовем WiFi программатором. Заливаем в нее специально разработанную прошивку (лучше всего скетч), прописываем пароль домашнего WiFi роутера и поднимаем mDNS, подключаем к ESP8266 (или Arduino), которую надо программировать. Подключаем их друг к другу UARTами, один из GPIO программатора подключаем к RESET жертвы, еще один свободный GPIO программатора к GPIO0. В Arduino IDE выбираем драйвер программатор WiFiProgrammer, он по имени WiFiProg.local подключается к нашему программатору по TCP/IP, и шлет новую прошивку по воздуху. Программатор дергает GPIO0 и RESET жертвы как положено и шьет ее. Далее этот же драйвер программатора (или отдельная утилита) используется как debug терминал, принимая по WiFi данные из UARTа жертвы.
Можно также реализовать и без домашнего роутера, если настроить в программаторе точку доступа.

С одной стороны программатор - это лишнее устройство, а с другой - универсальное решение для программирования (и отладки!) чего угодно по WiFi из Arduino IDE.
Ну и wifio будут брать парами, а не по одной :)
 

alexhi

Member
Здравствуйте! Запускаю пример на компиляцию и получаю ошибку
\DOCUME~1\9335~1\LOCALS~1\Temp\build8547920213757854907.tmp\WiFiWebServer.cpp -o C:\DOCUME~1\9335~1\LOCALS~1\Temp\build8547920213757854907.tmp\WiFiWebServer.cpp.o
c:\projects\Tools\arduino-1.6.1/hardware/tools/esp8266/xtensa-lx106-elf/bin/xtensa-lx106-elf-g++ возвратил 128
Ошибка компиляции.
В чем может быть дело ?
 

pvvx

Активный участник сообщества
pvvx, Sming подразумевает что ведущая роль в работе сервера за ним. Т.е. он сам вызывает callback когда ждет фрагмент данных.
Значит вы не поняли. callback вызывает LwIP. О вашей передаче данных в pcb LwIP ничего не знает и никак не может вызывать callback c передачей указателя на нужный вам и ещё активный у него pcb :) Он пока не умеет гадать,когда вы соизволите начать отправку. Та-же ошибка жила и в espconn. Но в поздних версиях её устранили, путем предварительного поиска в списках LwIP pcb на необходимое соединение (содрав методу из моего патча для неё), путем сравнения номера порта и ip host и remote, которые были заранее запомнены при открытии соединения. И теперь espconn всегда тупит и ищет pcb, перед почти любым действием... :)
В Sming, я наблюдал только вызов какой-то post-task в процедуре poll на активный pcb, которую вызывает LwIP. Но она вызывается не часто и между этими вызовами LwIP уже может грохнуть ту pcb, если на него придет FIN, ACK. Стеком TCP не вы управляете, а LwIP и он вызывает callback с указателем на активный pcb, если там что происходит... И при множестве активных соединений там тысячи перестановок в этих pcb в секунду :)
 
Последнее редактирование:

Lazy Fox

New member
В чем может быть дело ?
Такая же проблема, после распаковки ArduinoIDE любой скетч (даже пустой) компилится так:
Код:
void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:
}
==============================================
Arduino: 1.6.1 (Windows 7), Плата"Generic ESP8266 board"
Изменена опция сборки, пересобираем все
C:\Program Files\Arduino/hardware/tools/esp8266/xtensa-lx106-elf/bin/xtensa-lx106-elf-g++ -D__ets__ -DICACHE_FLASH -IC:\Program Files\Arduino/hardware/tools/esp8266/sdk//include -c -Os -mlongcalls -mtext-section-literals -fno-exceptions -fno-rtti -std=c++11 -MMD -DF_CPU=80000000L -DARDUINO=10601 -DARDUINO_ESP8266_ESP01 -DARDUINO_ARCH_ESP8266 -IC:\Program Files\Arduino\hardware\esp8266com\esp8266\cores\esp8266 -IC:\Program Files\Arduino\hardware\esp8266com\esp8266\variants\esp01 C:\Users\admin\AppData\Local\Temp\build5046200345775703863.tmp\sketch_apr02a.cpp -o C:\Users\admin\AppData\Local\Temp\build5046200345775703863.tmp\sketch_apr02a.cpp.o

Ошибка компиляции.
==============================================

Подозреваю что кроме распаковки архива с ArduinoIDE в каталог с установленной ардуиной нужно было проделать некие танцы с бубном
 

anakod

Moderator
Команда форума
Значит вы не поняли. callback вызывает LwIP. О вашей передаче данных в pcb LwIP ничего не знает и никак не может вызывать callback c передачей указателя на нужный вам и ещё активный у него pcb :) Он пока не умеет гадать,когда вы соизволите начать отправку. Та-же ошибка жила и в espconn. Но в поздних версиях её устранили, путем предварительного поиска в списках LwIP pcb на необходимое соединение (содрав методу из моего патча для неё), путем сравнения номера порта и ip host и remote, которые были заранее запомнены при открытии соединения. И теперь espconn всегда тупит и ищет pcb, перед почти любым действием... :)
В Sming, я наблюдал только вызов какой-то post-task в процедуре poll на активный pcb, которую вызывает LwIP. Но она вызывается не часто и между этими вызовами LwIP уже может грохнуть ту pcb, если на него придет FIN, ACK. Стеком TCP не вы управляете, а LwIP и он вызывает callback с указателем на активный pcb, если там что происходит... И при множестве активных соединений там тысячи перестановок в этих pcb в секунду :)
Думаю да мы не совсем поняли друг друга, а если точнее я неудачно выразился. Разумеется не Sming играет ведующую роль (точнее он играет но только по отношению к конечному разработчику), а по факту изначальная инциацива за LWIP. Поэтому отправка происходит только внутри callback вызовов LWIP, соответственно:
1. Соединение не может быть неверным в момент обратного вызова (не зря же нам LWIP этот хендл передает в функцию). Конечно не считая NULL и т.п. Но я офф.доки внимательно читал, надеюсь что все учел правильно
2. Мы в начале всегда берем не какой-нибудь наш сохраненный указатель на класс (в котором мог, теоретически, бы быть неверный хендл), а наоборот по хендлу который дал LWIP ищем наш класс
3. Как только приходит событие о закрытии соединения от внешней стороны (а LWIP нас должен уведомить соответствующим callback) или как только сам пользователь закрывает соединение, хендлу присваивается NULL. Поэтому дальше даже в случае если пользователь каким-то совсем уж диким образом обратиться к объекту, он получит вполне честный exception.
 

pvvx

Активный участник сообщества
Поэтому отправка происходит только внутри callback вызовов LWIP
Тогда верно, но до уровня приоритетов прерываний всей цепочки WiFi-SDK-LwIP-User :)
А в SDK по данному поводу БЯДА... От туда и возник тот метод патча espconn с поиском pcb. По другому не решалось и дало хоть минимальную стабильность... Если приоритеты починили - тогда будет всё Ok...
 
Последнее редактирование:

anakod

Moderator
Команда форума
Да в СДК много бед.. Вы кстати libpp разбирали?

Что касается похода основанного на callback, это было изначальной архитектурной задумкой чтобы избежать промежуточных буферов и потери памяти.
 

pvvx

Активный участник сообщества
Да в СДК много бед.. Вы кстати libpp разбирали?

Что касается похода основанного на callback, это было изначальной архитектурной задумкой чтобы избежать промежуточных буферов и потери памяти.
Промежуточные буфера всё равно будут. Копаться в буферах LwIP не гуд. Их сегментированность не дает возможностей применения строковых поисков и т.д.
libpp - частично. Смотрел, но не разгребал.
Пока стоит задача с libmain.a - она не дает работать в режиме малого потребления и всё остальное уже мелочи, т.к. одна из главных задач на модуле (из-за неё и её стартовых процедур) не решается.
 
Последнее редактирование:

anakod

Moderator
Команда форума
применения строковых поисков и т.д.
В Sming я реализовал специальные функции для строкого поиска/сравнения/копирования в цепочке буферов lwip. Но в других местах все равно конечно кок-какие буферы заводить пришлось, без них не удобно уже конечному пользователю (но они обычно поменьше чем для входных данных).

Про декомпиляцию - не поделитесь ли методикой? А то я в соседней ветке мучаюсь :(
 

AnonymUser

New member

igrr

Moderator
Команда форума
@lazy-fox
@alexhi
С компиляцией под windows проблема в криво собранном тулчейне — gcc зависит от libiconv, который прилинковался динамически. Нужно пересобрать, чтобы не требовалась дополнительная dll-ка.
 

Victor

Administrator
Команда форума
@lazy-fox
@alexhi
С компиляцией под windows проблема в криво собранном тулчейне — gcc зависит от libiconv, который прилинковался динамически. Нужно пересобрать, чтобы не требовалась дополнительная dll-ка.
igrr, не все могут пересобрать Arduino IDE
Lazy Fox и @alexhi , пока воспользуйтесь вот этим советом:
скопируйте файл libiconv-2.dll из arduino-1.6.1\hardware\tools\avr\libexec\gcc\avr\4.8.1 в arduino-1.6.1
 

igrr

Moderator
Команда форума
igrr, не все могут пересобрать Arduino IDE
Собственно я тоже не могу пересобрать правильно тулчейн, иначе уже давно бы починил :) И винды у меня вообще нет.
Если кто-нибдуь знает, как его правильно пересобрать под win x32, или где взять работающую сборку — welcome.
 

igrr

Moderator
Команда форума
Его и использовал, получается зависимость на libiconv-2.dll.
Говорят, нужно снести libiconv, установленный вместе с mingw, и собрать его самостоятельно, -static. Если кто-нибудь может это попробовать на локальной машине, буду признателен — на билд-сервере очень неудобно экспериментировать.
 
Сверху Снизу