14.02.2012

Проблемы Ethernet в ArduinoIDE 1.0

Только что столкнулся с проблемами использования Ethernet Shield на W5100 в рамках ArduinoIDE 1.0. Великолепно до этого работавшие скетчи решительно отказались работать, что меня привело в панику слегка озадачило.

Формально, чтобы перенести скетч со "старых" ArduinoIDE 0022/0023 под 1.0, надо исправить названия классов "Server" и "Client" на "EthernetServer" и "EthernetClient" соответственно. Идеологически, классы Server и Client теперь сделаны полностью абстрактными и перенесены в ядро Arduino. И поскольку они не имеют ни одной реальной функции, библиотека должна  породить от них свой класс, "наполнив" его реальным содержимым. Думаю, делается это с прицелом на будущее, но предсказывать его пока не берусь ;)

К сожалению, даже после успешной компиляции, надо обязательно залить скетч и проверить его работу. Скорее всего, проблемы (если они действительно есть) вскроются сразу же - речь идет о неверном обмене с  Ethernet-чипом Wiznet W5100. Первым делом, открывайте файл arduino-1.0/libraries/Ethernet/utility/w5100.h и ищите в нем строки:

#define __SOCKET_REGISTER16(name, address)                   \
  static void write##name(SOCKET _s, uint16_t _data) {       \
    writeSn(_s, address,   _data >> 8);                      \
    writeSn(_s, address+1, _data & 0xFF);                    \
  }                                                          \
  static uint16_t read##name(SOCKET _s) {                    \
    uint16_t res = readSn(_s, address);                      \
    res = (res << 8) + readSn(_s, address + 1);              \
    return res;                                              \
  }

Вместо них поставьте полностью аналогичные (но, удивительным образом - работающие):

#define __SOCKET_REGISTER16(name, address)                   \
  static void write##name(SOCKET _s, uint16_t _data) {       \
    writeSn(_s, address,   _data >> 8);                      \
    writeSn(_s, address+1, _data & 0xFF);                    \
  }                                                          \
  static uint16_t read##name(SOCKET _s) {                    \
    uint16_t res = readSn(_s, address);                      \
    uint16_t res2 = readSn(_s,address + 1);                     \
    res = res << 8;                                             \
    res2 = res2 & 0xFF;                                         \
    res = res | res2;                                           \
    return res;                                              \
  }

(это исправление взято отсюда: http://code.google.com/p/arduino/issues/detail?id=605)

В большинстве случаев это помогает; мало того - говорят, что некоторые PPA в Ubuntu уже содержат пакет "arduino" с этим патчем, но давать на них ссылки не буду - я не понимаю смысл создания пакета для программы, которая великолепно работает, будучи распакована в одну папку. Гораздо удобнее качать и ставить дистро непосредственно с arduino.cc, не мучаясь вопросами "а чой-то они там наменяли-то?!"

Тем, у кого после вышеописанного патча все равно не заработает - рекомендую посмотреть на версию кросс-компилятора gcc-avr в составе вашего дистрибутива Linux. Если это, например, 4.5.3 - причина может быть в этом, и стоит позаботиться об откате на 4.3.2 или создании собственного окружения. Возможны разные варианты действий, но я пока выбрал наиболее тупой простой - развернул в виртуальную машину под Windows дистрибутив 0023 и временно работаю в нем. И вообще - пользователям Windows в этом плане проще, поскольку хоть их дистрибутив ArduinoIDE и выглядит чрезмерно "пухленьким", в него уже включен порт avrgcc - WinAVR, что драматически повышает стабильность по сравнению с Linux, где пакет gcc-avr "приходит" вместе с дистрибутивом ОС.

Тем, кто уже начал использовать включенные в состав ArduinoIDE библиотеки DHCP, стоит обратить внимание на другой патч: http://code.google.com/p/arduino/issues/detail?id=742

Сейчас при формировании DHCP-запроса, код из библиотеки Ethernet не совсем корректно формирует уникальное имя хоста, генерируя псевдослучайный суффикс в том числе и из "непечатных" символов: это может создавать потенциальные проблемы при работе DNS.


3 комментария:

  1. Добрый вечер!
    А вот не могли бы вы сказать каковы могут быть побудительные мотивы для использования IDE 1.0? Ну то есть что там есть такого, что перевешивает старый добрый 023?

    ОтветитьУдалить
  2. Я постоянно задаю на работе похожий вопрос любителям поставить распоследний M$-офис.

    Ответа я пока не получил, но полагаю, они испытывают тайное наслаждение, видя мучения коллег, пытающихся безуспешно открыть созданные ими файлы "старыми добрыми" версиями :)

    ОтветитьУдалить
  3. Вот например разработчики Maple собственный IDE выпустили на базе всё того же Wiring, на основе которого и Arduino IDE сделан. Возможно, что вести "раскопки" стоит именно в этом направлении.

    ОтветитьУдалить