Ethernet Library 2.0
- Войдите на сайт для отправки комментариев
Ср, 26/12/2018 - 10:43
Коллеги, конечно многие из вас следят за обновками и модными тенденциями в библиотеках Arduino, но, думаю, что есть и такие, как я - сидят себе на 1.6.11 и в ус не дуют, пока баг не словят.
Так вот, для последних сообщаю, что в актуальных версиях Arduino IDE поставляется Ethernet library 2.0 (это не Ethernet2 для w5500) - feature list. Там многое зафиксено, но многое и не лежит на поверхности, а спрятано в исходниках.
Сильно я пока ее не прошерстил, из интересного нашел это (размер памяти под сокет можно переконфигурировать без особых извращений):
// By default, each socket uses 2K buffers inside the Wiznet chip. If
// MAX_SOCK_NUM is set to fewer than the chip's maximum, uncommenting
// this will use larger buffers within the Wiznet chip. Large buffers
// can really help with UDP protocols like Artnet. In theory larger
// buffers should allow faster TCP over high-latency links, but this
// does not always seem to work in practice (maybe Wiznet bugs?)
//#define ETHERNET_LARGE_BUFFERS
Ethernet library 2.0 (это не Ethernet2 для w5500)
А какую лучше использовать? я немного с Ethernet2 для w5500 работаю, пока проблем не заметил.
Точную историю развития я не могу привести (не сильно следил), но ежели гадать по внутренностям, то могу предположить что Ethernet и Ethernet2 - это форки драйвера, написанного с демонстрационными целями корейцем из Wiznet. Сначала Arduino.cc и пр. выпускался Ethernet Shield на W5100 и для него была изготовлена библиотека (включена в состав IDE) Ethernet.h. Через какое-то время вышел Ethernet Shield 2 на W5500 и в библиотеке Ethernet.h подменили нижний уровень (работающий с регистрами по SPI), оставив всё, что сверху, нетронутым. Обозвали это, стало быть Ethernet2.h. Оба варианта можно было считать библиотекой Ethernet v1.0.0.
Ethernet v2.0.0, поддерживающий одновременно W5100/W5200/W5500 пилился отдельно (вроде как) от команды Arduino товарищем Paul Stoffregen. Я какое-то время почитывал Issues, не находя для себя причин менять шило на мыло, но теперь вижу, что прожект вышел удачным, раз он включен в стоковый состав библиотек IDE.
Я вчера подменил им старую стоковую 1.0.0 в одной из прошивок средней величины, интеграция прошла почти бескровно. Пришлось, правда, кое-что из использованных недокументированных и самопальных фич подпиливать - но я знал, на что шёл, когда свернул на кривую дорожку правки кода драйвера )) Пока наблюдаю за поведением макета, взрывов и самовольного выкачивания всего Интернета в EEPROM до данного момента не случилось.
Конечно объем объектного кода подрастет, так как выбор методы работы с конкретным чипом осуществляется не условной компиляцией, а автоопределением и if-ами.
Проблемы... Тут сложно сказать, потому что я несколько лет сидел на стоковом 1.0.0, писал что-то простенькое и тоже особо не наблюдал глюков. Но в более-менее сложных проектах с неустойчивой связью вылезает, конечно, сущность демодрайвера. Например, день назад (после чего и полез искать альтернативы) я закончил итерацию отладки ситуации в которой "веб-страница с Arduino показывается, а наружу данные не пушатся". Крайне странная ситуация - контроллер не висит, сетевой адаптер не висит, веб-интерфейс работает, а исходящих коннектов нет (но должны быть). Проиcходило это внезапно, на удаленном сегменте, два раза за полгода. На столе воспроизвести баг не удалось. Но, насколько я понял из исходника драйвера и навернутой вокруг диагностики, в том случае, если в процессе connect() возникает проблема, то сокет может подвиснуть в последнем состоянии стейт-машины чипа, но не по его вине - просто команда DISCONN не засылается, считается, что и так "все будет заеб...". Соотвественно - в следующей итерации посылки пакета данный сокет не может быть использован. Берется следующий... Драйвер "падает на нож и так три раза подряд". В итоге все сокеты как бы заняты, прошивка не может инициировать новый коннект. А веб-интерфейс... Ну, под него-то сокет был зарезервирован на старте, встал в LISTEN и как работал, так и работает.
К тому же оказалось, что у connect() тупо нет программного таймаута. И если удаленный конец является слоупоком, то можно легко подвиснуть на N sec, а то и на watchdog нарваться.
И это только пара историй о драйвере v1.0.0 ))
В v2.0.0 часть тупых вещей исправлена. Насколько это так? Время покажет. По исходнику видно, что он переработан чувствительно.
ясно, спасибо, будем тестировать.
Подыму тему, так как руки дошли слегонца покопаться у неё внутрях.
Вот примерно таким образом выкидывается медленный клиент (в прежней версии библиотеке он мог висеть на проводе бесконечно или вообще влёгкую заDDoS-ить систему на W5100 в четыре хода):
Обратите внимание на способ получения активного сокета (выделено в коде): https://www.arduino.cc/en/Reference/EthernetServerAccept
Да неужели у них дошли руки? :)))
Наверняка за это время те ардуинщики, кому интересны сетевые фокусы, прошерстили мануал и исходники библиотеки. Ну, а если нет, то кратко сообщу о тех нововведениях, которые мне показались полезными:
- Ethernet.init() позволяет произвести предконфигурирование пина CS для нестандартных шилдов либо самоделок. Должен вызываться перед begin();
- Ethernet.hardwareStatus() возвращает enum модели сетевого чипа (W5100, W5200, W5500 или никакой). Можно использовать для определения кол-ва доступных сокетов (теоретически) или для проверки чипа на наличие (вдруг он отстегнулся в полёте);
- Ethernet.linkStatus() отдаёт состояние линка (позволяет обнаружить отключение кабеля или, теоретически, его дефективность). К сожалению W5100 не имеет соответствующего функционала на уровне чипа, поэтому с ним использование данной функции бессмысленно;
- if(server) показывает чем закончился begin(), есть ли свободные сокеты и т.д. Т.е. позволяет быстро определить способность системы обслуживать новые соединения в целом;
- setConnectionTimeout() - крайне нужная штука. В прежней версии библиотеке connect() блокировал весь процессинг пока соединение не пройдёт удачно, не будет отвергнуто либо чип не наткнется на закрытый порт. Т.е. поведение функции было непредсказуемо. Сейчас же управление будет передано обратно, если коннект не состоялся в течении одной секунды (значение по-умолчанию, изменяемая величина);
- Ethernet.begin(mac) на самом деле может быть применена как Ethernet.begin(mac, timeout, responseTimeout), где timeout - время выделенное на все действия по получению адреса, responseTimeout - время, выделенное на каждый запрос к DHCP (их несколько). Таким образом - более не требуется висеть в begin() целую минуту при упавшем DHCP, можно быстро перейти к назначению статического IP;
- EthernetClient.connected() теперь возвращает true даже если при входящем соединении данные не начали поступать. Ранее было невозможно отследить наличие открытого соединения до тех пор, пока в сокет не поступал хотя бы один байт данных извне;
- EthernetClient.status() - не описана, но существует. Любители пощупать голый чип могут узнать в каком состоянии находится сокет, с которым они работают или просмотреть состояния всех сокетов. Раньше приходилось использовать "дыру в системе" и брать информацию с экземпляра класса W5100. Если нужно или не забуду - приведу пример;
- EthernetClient.getSocketNumber() - возвращает номер привязанного к текущему коннекту сокета;
На этом пока всё, остальные фичи простым домоседам наврядли понадобятся.
Продолжаю ковыряться в Ethernet 2.0. Сегодня мне придётся расстроить любителей делать стабильность через механизмы сторожевого таймера. К сожалению, как и ранее, библиотека закрывает глаза на его существование, в чём можно убедиться даже без анализа исходных текстов, путём простого эксперимента.
Включаем USE_DHCP, вытаскиваем сетевой кабель из гнезда и смотрим в Serial Monitor... Наверняка кто-то думает, что ничего страшного тут нет - проскочим setup() и приключения закончились. Но не тут-то было. Для продления аренды IP-адреса необходимо вызвать Ethernet.maintain(), который делает такой же длинный запрос к DHCP-серверу, как и Ethernet.begin(mac). Любая задержка - и МК идёт в ребут.
Впрочем, если вы думаете, что с переходом на статический IP всё нормализуется, то мне придётся вас огорчить - проблему можно словить, например, прямо на .print(), так как он, в тёмных глубинах классов, вызывает EthernetClass::socketSend(), который содержит следующее:
Таким образом, в случае проблем с отправкой данных, функция блокирует выполнение остального кода на неопределённое время и... Hello watchdog's reset!
Примечание#1: в коде, который расположен в начале, приведена обещанная функция просмотра состояния сокетов, которая, при определённой сноровке, помогает понять отчего заклинило обмен по Ethernet.
Примечание#2: наверняка вы заметили бесхозный Ethernet.linkStatus(). Но он там для дела - без него Ethernet.hardwareStatus(), вызванный до Ethernet.begin() работает неправильно. Думаю, что это тривиальный баг.
P.S. Совсем забыл. Чтобы изменить состояние сокета - достаточно чем-нибудь (например телнет-клиентом) приконнектится на 80-й порт ардуино-сервера.
Ethernet library 2.0 (это не Ethernet2 для w5500)
А какую лучше использовать? я немного с Ethernet2 для w5500 работаю, пока проблем не заметил.
кину свои 5 копеек в тему W5500 :
пользовался для написания серверной части Modbus TCP на C , столкнулся с таким "глюком" : если сконфигурировать в W5500 сокет TCP с буффером больше 4KB и флагом SF_TCP_NODELAY ,функция send отрабатывает "верно" но данные по факту не отправляются ( даже при пакете до 200 байт) а при 4KB и меньше все шлется . прошу у кого есть шилд на данной железке подтвердить или опровергнуть .Пользовался драйверами из официального репозитория Wiznet на GitHub ~месячной давности .
Это что ли https://github.com/Wiznet/ioLibrary_Driver/issues/47 ?
Небольшая ремарка на предмет W5100 vs W5500:
Чем выигрывает W5500.
- W5500 поддерживает восемь сокетов, т.е. позволяет иметь восемь одновременных соединений. Редко кому нужно, конечно. Размер одного сокета можно раздуть до 16Кб (за счёт урезания остальных). Так же он умеет коммуницировать с МК в потоковом режиме: SPI Operation Mode supports two modes, the Variable Length Data Mode and the Fixed Length Data Mode. Variable Length Data Mode (VDM) - Data Length is controlled by SCSn. Fixed Length Data Mode (FDM) - 1, 2, or 4 Byte Data Length. Т.е. МК открыл SPI-сессию и копипастит гигабайты данных не останавливаясь.
- W5100 ограничен четырьмя сокетами с максимальным размером в 8Кб. К сожалению справляется только с однобайтовым FDM: МК открыл сессию, считал/записал один байт данных, закрыл сессию. Открыл... закрыл... Медленно и печально. Правда, у него есть адский Direct Bus Interface mode с 15-битной адресной и 8-битной шиной данных, но эта история не про Ардуину.
Чем выигрывает W5100 (лично для меня).
- W5100 не умничает и не лезет помогать программисту, когда его не просят: например, если у него не осталось доступных сокетов, находящихся в состоянии LISTEN, то он оставляет управление TCP-сессией удалённой (инициирующей) стороне. Она сама решает сколько ожидать открытия сессии;
- W5500 открывает любой коннект и делает ему reject, если доступных сокетов в режиме LISTEN не осталось. И даже, если порт назначения в TCP-пакете не совпадает с любым заданным в чипе, - всё равно делает reject.
Таким образом часть соединений будет отвергнута, если МК сильно загружен не успевает переводить сокеты в LISTEN, или же получает частые, но короткие сессии. А это наврядли может понравится удалённой системе. Например - с Web-сервера, который внезапно захостился на Arduino, будет недополучена часть картинок или CSS-файл.
Вы можете убедиться в этом самостоятельно, проэкспериментировав с опциями, расположенными в Ethernet.h:
Просто откройте телнетом два соединения на вашу Arduino....
Доброго дня.
У меня эта библиотека на Arduino Due + Arduino Ethernet R2 не работает.
Пробовал различные варианты подсоединения пинов и инициализации. Компилировал демонстрационный проект. Ничего не помогло. Выдает ошибку: Ethernet shield was not found.
С библиотеками 1.х работает без проблем.
Что делать?
Проблема решена.
Небольшая ремарка на предмет W5100 vs W5500:
Чем выигрывает W5500.
Уважаемый sadman41, может вы подскажете как победить одну беду или где-то в библиотеке или тогданезгаю где стоит задержка примерно в секунду. Когда создаю UDP прослушку сокетов на Arduino - все хорошо, "НО" после получения пакета Arduino ждет как будто delay(1000) и игнорит пакеты,проходит это время и опять принимает,причем это не случайно,а постоянно.
В самой библиотеке я таких delay() не наблюдал.
Без исследования исходного кода и воспроизведения проблемы на реальном железе на Ваш вопрос ответить невозможно.
Добрый день, есть Arduino Mega 2560 R3 + Ethernet W5100 shield. Загружаем библиотеку Ethernet v2.0, открываем Examples\WebServer, компилируем и запускаем скетч примера, который в ответ на запрос браузера формирует простую HTML-страницу с автоматическим обновлением каждые 5 сек, и наблюдаем следующую картину: после загрузки страницы на 3-м или 4-м обновлении страницы браузер зависает. Смотрим в Serial-монитор и видим, что очередной запрос принят скетчем не полностью. После принудительного обновления страницы в браузере все повторяется. Тенденция, однако..
Что это, глючный шилд или баг в библиотеке?
Вот на моём. Никаких затыков.
Друзья, я пару недель в фоновом режиме позанимался с ICMP и накропал пару небольших "библиотек". В кавычках - потому, что классически подключить их возможности нет. Паразитируя на Ethernet Library 2.0, они используют пару функций, до которых штатно не дотянешься.
Первая "библиотечка" реализует функционал ICMP. Вторая, погоняя первой, делает ICMP Ping и ICMP Traceroute. Обе утилиты запускаются как в блокирующем режиме, так и в асинхронно. Теоретически они должны работать и с W5500 и с W5100 (начинал я с одним, а добивал - с другим).
Я не совсем уверен что все баги выловлены и API приведено к удобному состоянию, поэтому если кто-то из увлекающихся может потестить со знанием дела - будет великолепно. На всякие гитхабы пока выкладывать не готов. Если кто-то готов погонять - отпишитесь.
Пытался подружить esp32 и w5500.
Лажа какая-то.
Начнём с того, что в одном скетче не могут находиться одновременно
Ошибка компиляции. Переменная передачи значения не соответвует стандарту arduino. Приплыли. WebServer.h со всеми его плюшками с ethernet использовать нельзя. Те же костыли с websocket.
Пришлось переделывать готовый прототип на lan8720.
Во первых эта 8720 в 10(!) раз дешевле в закупке, обвязки в 5 раз меньше, так ещё 100% совместимость с esp32.
Может кому-нибудь эта информация будет полезна.
Покажите драйвер под 8720, совместимый со средой Arduino.
Покажите драйвер под 8720, совместимый со средой Arduino.
Для esp32:
Покажите драйвер под 8720, совместимый со средой Arduino.
См также
http://arduino.ru/forum/apparatnye-voprosy/podklyuchenie-ethernet-lan8720-i-esp32-devkit-c-esp32-devkit-v1
А ссылкой на гитхаб и для ATMega328?
Мега не потянет. Там тактирование 50мГц...
Ещё немного подчистил и погонял ICMP Ping library, выложил для критики и предложений: https://github.com/zbx-sadman/Arduino/tree/master/ICMP
Наткнулся на такую проблему, на стороне клиента в HTML файле подключены css, png, js, и jquery. Каждый раз при обновлении в страницу не подгружается один из этих файлов ( в браузере " (failed)net::ERR_CONNECTION_REFUSED " ) А на стороне сервера нет GET запроса на нужный файл.
Чип W5500, библиотека Ethernet 2.0, STM32F103
Наткнулся на такую проблему, на стороне клиента в HTML файле подключены css, png, js, и jquery. Каждый раз при обновлении в страницу не подгружается один из этих файлов ( в браузере " (failed)net::ERR_CONNECTION_REFUSED " ) А на стороне сервера нет GET запроса на нужный файл.
Чип W5500, библиотека Ethernet 2.0, STM32F103
См. сообщение #10:
--------------------
- W5500 открывает любой коннект и делает ему reject, если доступных сокетов в режиме LISTEN не осталось. И даже, если порт назначения в TCP-пакете не совпадает с любым заданным в чипе, - всё равно делает reject.
--------------------
И мне кажется, что библиотека делает +1 Listen socket при начале работы с открытым сокетом.
Т.е. скорее всего браузер делает параллельные запросы, часть из них успевает залететь в Listen-сокеты, а остальная часть режектится самим чипом, не доходя до МК, так как он не успел приоткрыть дополнительные, пока чухается, работая уже с открытыми коннектами.
Тогда надо или библиотеку править, чтобы на старте прям все 4/8 сокетов в Listen переводились или сокращать кол-во запросов, сливая css+js+html в единый.
Да, но я пробовал, чтобы браузер давал меньше 8 запросов, все равно один не доходит. Заметил в браузере в запросах к серверу такую строку
GET /mainFrame.htm HTTP/1.1
У не отвеченных запросов GET /mainFrame.htm undefined
Может в этом дело? почему браузер не определяет тип HTTP ?
Попробуйте в другом браузере. В некоторых ситуациях они работают по разному
Пробовал, все таки это связано с сокетами :(
Чипу, вобщем-то без разницы что принимать: "GET / HTTP/2.0", ”EHLO" или "privet, server, vote peremennye: ....". Парсингом занимается прикладная программа. И это не библиотека Ethernet 2.0.
Я бы вайршарком еще послушал что там происходит.
готов оплатить полнный пакет дороботки на 8720 и выходом spi fastled ws2811 2 out 4 universa /
Просто оч нужно времени нет занет кто готов по кодить жду .
что такое 8720?
сетевая карта lan8720
100т. р.
По срокам месяц.
Бонусом плату нарисую.
lan8720 это драйвер витой пары, а никакая не сетевая карта
остальной набор слов - непонятен
Asterixs, вообще подобные запросы размещают в разделе "Ищу исполнителя".
to sadman41
добрый день
как на данный этап охарактеризуете плюсы/минусы данной библиотеки?
спасибо
Устройство работает уж пару лет точно, не сбоит. Это плюс, несомненно. Минусы, наверное, видны в специфических применениях. Я сильно не извращаюсь, не накатываю каждый новый релиз.У меня и IDE 1.8.9 необновленное.
Ну, например, нельзя простым способом кол-во сокетов переконфигурировать, отдав больше памяти определённым. Это минус, полагаю. Но кому из простых людей нужна такая операция - вопрос на мильен.
разбираю потихоньку библиотеку, есть "непонятно" сформированный код
w5100.h
не понятно/а:
1. необходимость применение косой
2. имя функции write##name() - использование ##
3. необходимость вставлять реализацию в хедер-файл!
2) функция препроцессора, которая слепляет строку и параметр.
__GP_REGISTER8(name, address) static inline void write##name(uint8_t _data) { ...
При обработке __GP_REGISTER8(REG_CFG, 0x18) генерируется функция с именем writeREG_CFG()
1) Дефайн должен находится в одной строке, CRLF его заканчивает. \ аннигилирует CRLF.
3) Просто автору так захотелось - все бахнуть через дефайны. А они в .cpp будут просто выкинуты.
> Просто автору так захотелось
хорошо-та хорошо... да, блин... этот код ведь ещо и другим смотреть и разгребать... :о)
спасибо!
еще небольшие наблюдения (библиотека выдрана из Arduino/1.8.18.x64/libraries//Ethernet)
мои выкусы, надеюсь, кому надо - пригодится :о)
sunjob, вы два сообщения назад не узнали стандартный синтаксис формирования дефайна - а уже беретесь что-то править?
to боинг, Вам что, делать нечего?!
to боинг, Вам что, делать нечего?!
спрошу тоже самое у вас
нафига лезть в код. который вы не понимаете?
sunjob, к чему эти кривые переводы комментариев из исходника? Кому надо - переведет сам.
Если у вас есть вопросы по библиотеке - формулируйте их яснее.