Исправление: Ethernet_stm-Master выходит из строя с помощью чипа W5200

Фоно
Вторник 07 июня 2016 г. 18:33
Привет,
Я заметил, что Вассилис упомянул, что он не может проверить версию W5200, прежде чем отправить. Но Мерфи заботится ! Два метода
uint8_t w5200class :: read (uint16_t _addr)
и
uint16_t w5200class :: read (uint16_t _addr, uint8_t *_buf, uint16_t _len)
Пропустил надлежащий настройку сигнала CS.
Я исправил его, как показано ниже.
Вассили, или тот, кто за это отвечает?
******************************************** uint8_t W5200Class::read(uint16_t _addr) { #if defined(ARDUINO_ARCH_AVR) setSS(); SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); SPI.transfer(0x00); SPI.transfer(0x01); uint8_t _data = SPI.transfer(0); resetSS(); #elif defined(__STM32F1__) [b]digitalWrite(STM32_SPI_CS, LOW);[/b] SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); SPI.transfer(0x00); SPI.transfer(0x01); uint8_t _data = SPI.transfer(0); [b]digitalWrite(STM32_SPI_CS, HIGH);[/b] #else SPI.transfer(SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(SPI_CS, 0x00, SPI_CONTINUE); SPI.transfer(SPI_CS, 0x01, SPI_CONTINUE); uint8_t _data = SPI.transfer(SPI_CS, 0); #endif return _data; } uint16_t W5200Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len) { #if defined(ARDUINO_ARCH_AVR) setSS(); SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); SPI.transfer((0x00 | ((_len & 0x7F00) >> 8))); SPI.transfer(_len & 0x00FF); for (uint16_t i=0; i<_len; i++) { _buf[i] = SPI.transfer(0); } resetSS(); #elif defined(__STM32F1__) [b] digitalWrite(STM32_SPI_CS, LOW);[/b] SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); SPI.transfer(0x00 | ((_len & 0x7F00) >> 8)); SPI.transfer(_len & 0x00FF); for (uint16_t i=0; i<(_len-1); i++) { _buf[i] = SPI.transfer(0); } _buf[_len-1] = SPI.transfer(0); [b]digitalWrite(STM32_SPI_CS, HIGH);[/b] #else SPI.transfer(SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(SPI_CS, (0x00 | ((_len & 0x7F00) >> 8)), SPI_CONTINUE); SPI.transfer(SPI_CS, _len & 0x00FF, SPI_CONTINUE); for (uint16_t i=0; i<(_len-1); i++) { _buf[i] = SPI.transfer(SPI_CS, 0, SPI_CONTINUE); } _buf[_len-1] = SPI.transfer(SPI_CS, 0); #endif return _len; }

Вассилис
Вторник 07 июня 2016 г., 19:22
Спасибо Фоно ;)
Вы проверили библиотеку с помощью чипа W5200 ?
Работает ОК ?

Фоно
Вторник 07 июня 2016 г. 22:59
Вассили,
Я проверил исправление с помощью щита чипа W5200 на плате Olimex STM 32. Работает хорошо. Я также проверил его на чипе W5100. Работал хорошо сразу, исправление не требуется.
Я должен сказать, что, используя IDE Maple Leaflabs, я написал вариант библиотеки Ethernet, чтобы сделать его полностью эффективным при использовании Freertos. Действительно, если вы защитите доступ к чипу W5XX через SPI, используя критические разделы, вы можете иметь несколько задач, обрабатывающих несколько сокта без помех (трафик одного сокета не замораживает другой трафик сокетов). Я думаю, что это большое улучшение, и я предлагаю добавить этот вариант в STM 32 для библиотек Arduino.

Mrburnette
Ср. 08 июня 2016 г. 12:19
Фоно написал:<...>
Вы можете иметь несколько задач, обрабатывающих несколько розеток без помех (трафик одного сокета не замораживает другой трафик сокетов). Я думаю, что это большое улучшение, и я предлагаю добавить этот вариант в STM 32 для библиотек Arduino.

Фоно
Ср. 08 июня 2016 г., 6:30 утра
Для этого мы могли бы создать выделенную версию библиотеки; Но что было бы хорошо, так это то, чтобы библиотека автоматически обрабатывала присутствие или отсутствие библиотеки TERTOS. Вы знаете, как это сделать? Дело в том, чтобы добавить вызовы в «Запуск критического раздела» и «Конечный критический раздел» в различных местах библиотеки Ethernet, и в случае библиотеки RTOS не используется в эскизе, эти вызовы просто ничего не сделают.

Вассилис
Ср. 08 июня 2016 г., 7:36 утра
FIR SELECT FIX в функции READ () выполняется (W5200.CPP файл).

Mrburnette
Ср. 08 июня 2016 г. 14:58
Фоно написал:<...> Дело в том, чтобы добавить вызовы в «Запуск критического раздела» и «Конечный критический раздел» в различных местах библиотеки Ethernet, <...>

Стевех
Ср. 08 июня 2016 г., 15:44
Фоно написал:Для этого мы могли бы создать специальную версию библиотеки; Но что было бы хорошо, так это то, чтобы библиотека автоматически обрабатывала присутствие или отсутствие библиотеки TERTOS. Вы знаете, как это сделать? Дело в том, чтобы добавить вызовы в «Запуск критического раздела» и «Конечный критический раздел» в различных местах библиотеки Ethernet, и в случае библиотеки RTOS не используется в эскизе, эти вызовы просто ничего не сделают.

Фоно
Пн 18 февраля 2019 г., 20:52
В процессе отслеживания ошибки в моей собственной версии библиотеки Ethernet, которую я называю Ethernet_rtos, я проверил сегодня его код в основном ветви репозитория v1.0.0 Бета.
Я был удивлен, обнаружив, что ошибка, которую я сообщил в своем посте от 7 июня 2016 года (в этой теме) о пропущенном примере линии CS в обоих методах чтения () класса W5200Class все еще присутствует в версии хранилища 1.0.0 Бета!

Еще одна вещь, которую я не понимаю: в репозитории в методах w5200class :: write () и w5200class :: read () Есть следующий код: for (uint16_t i=0; i<(_len-1); i++) { _buf[i] = SPI.transfer(0); } _buf[_len-1] = SPI.transfer(0);

Фоно
Пн 18 февраля 2019 г., 21:11
Я пишу отдельный пост, потому что я встретил ошибку в работе Ethernet Shield, так что это отличается от различных комментариев моего предыдущего поста.
Я использую версию для RTOS, которую я сделал из библиотеки Ethernet_stm. По сути, я добавил семафоры, чтобы защитить доступ к SPI, чтобы гарантировать, что переводы являются атомными, даже если две или более задач хотят использовать интерфейс Ethernet одновременно.
Я построил систему регулирования отопления для моего дома, которую можно контролировать и контролировать снаружи. Для этого я реализовал простой веб -интерфейс. Таким образом, в моем коде есть простой веб -сервер, и я также закодировал клиента NTP, который получает дату и время для временного метки данных, которые регистрируются на SD -карте.
Я подключил систему с модемом оптического волокна с соответствующими правилами перенаправления порта, чтобы я мог получить доступ к веб -серверу из WAN.
Моя система установлена ​​во Франции. Он работает отлично, когда я подключаюсь из любой точки во Франции. Я проводил обширные стресс -тесты с более чем 10 вкладками Google Chrome, каждая запрашивая веб -страницу каждые 5 секунд (обновление = 5 включено в код HTML). Этот тест работал в течение нескольких дней без проблем.
Но, если я поеду в другую страну (я попробовал Англию и Колумбию) и подключаюсь, используя свой смартфон на 3G -соединении, после нескольких запросов (возможно, дюжина), веб -сервер не работает и больше не отвечает. Когда я возвращаюсь домой, я замечаю, что клиент NTP все еще работает, а также глобальное регулирование моего центрального отопления. Только веб -сервер заморожен. Я должен перезагрузить систему, чтобы восстановить доступ к Интернету.
Любые идеи о разнице между соединением из Франции и из другой страны?
Как я мог имитировать соединение из другой страны во время пребывания во Франции, чтобы провести тестирование?

Fredbox
Пн 18 февраля 2019 г., 22:27
[Фоно - Пн 18 февраля 2019 г., 21:11] - Как я мог имитировать соединение из другой страны во время пребывания во Франции, чтобы провести тестирование?
Зарегистрируйтесь в службе VPN. Тот, который я использую (Torguard), имеет около 70 различных серверов, перечисленных примерно в 30 разных странах. Я знаю, что у них есть клиент Apple, которого я использую на iPad. Я предполагаю, что у них также есть один для Android. Сразу после того, как я зарегистрировался, я застрял в отеле, где они заблокировали почти все, поэтому я не мог подключиться к своей домашней сети. Как только я подключился к VPN, я немедленно вошел. Я плачу 15 долларов США за 6 месяцев обслуживания.

Стивестронг
Вт 19 февраля 2019 г. 8:33 утра
У меня также есть аналогичная установка и аналогичная проблема.
Я думаю, что разница в том, что вы используете ПК во Франции и мобильный телефон за границей.
Я думаю, веб -просмотрщик Android может изменить ситуацию.
В моем случае W5500 не может быть достижимы в любом случае, когда висит, независимо от клиентской платформы. Сброс помогает.

Фоно
Ср 20 февраля 2019 г. 14:23
Вы правы, говоря, что из -за рубежа я подключаюсь на своем смартфоне Android. Но когда я подключаюсь к своему смартфону из Франции, он работает так же хорошо, как и на моем компьютере.
До сих пор я заботимся о том, чтобы провести стресс -тест из -за рубежа и записать событие коммуникации здесь, во Франции, пока я не увижу замораживание, чтобы увидеть, где застрял процесс. Я уже прикрепил ноутбук к моей системе, и он будет работать 24/7 до тех пор, пока общение.
Я просто скучаю по сайту за рубежом, который может подключиться к моей системе в течение нескольких дней, надеюсь, ожидая провала связи.

Стивестронг
Ср 20 февраля 2019 г., 18:29
[Фоно - Ср 20 февраля 2019 г. 14:23] - Я просто скучаю по сайту за рубежом, который может подключиться к моей системе в течение нескольких дней, надеюсь, ожидая провала связи.
Ну, я мог бы запрограммировать один из моих чертепов с W5500, чтобы подчеркнуть ваш сайт 24/7, если хотите.
Просто дайте мне немного подробности.

Фоно
Сб 23 февраля 2019 г., 8:15 вечера
Спасибо за ваше предложение. Я настраиваю испытательную установку, и когда она будет готова, я могу принять ваше доброе предложение.

Фоно
Ср 27 февраля 2019 г., 22:52
В конце концов я нашел причину блокировки, которую иногда наблюдаю.
У моего приложения есть веб -сервер, а также клиент NTP. Последний использует UDP.
Я обнаружил проблему в вызове TakesEmaphore () в модуле веб -сервера, который заблокирован из -за отсутствующего gateMaphore () в модуле UDP.
Поэтому, пожалуйста, измените следующую функцию, как показано: /* Start EthernetUDP socket, listening at local port PORT */ uint8_t EthernetUDP::begin(uint16_t port) { if (_sock != MAX_SOCK_NUM) return 0; W5100.TakeSemaphore () ; for (int i = 0; i < MAX_SOCK_NUM; i++) { uint8_t s = W5100.readSnSR(i); if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) { _sock = i; break; } } if (_sock == MAX_SOCK_NUM) { W5100.GiveSemaphore () ; // This one was missing return 0; } _port = port; _remaining = 0; socket(_sock, SnMR::UDP, _port, 0); W5100.GiveSemaphore () ; return 1; }

Rogerclark
Пт, 01, 2019 2:35 утра
[Фоно - Ср 27 февраля 2019 г., 22:52] - В конце концов я нашел причину блокировки, которую иногда наблюдаю.
У моего приложения есть веб -сервер, а также клиент NTP. Последний использует UDP.
Я обнаружил проблему в вызове TakesEmaphore () в модуле веб -сервера, который заблокирован из -за отсутствующего gateMaphore () в модуле UDP.
Поэтому, пожалуйста, измените следующую функцию, как показано: /* Start EthernetUDP socket, listening at local port PORT */ uint8_t EthernetUDP::begin(uint16_t port) { if (_sock != MAX_SOCK_NUM) return 0; W5100.TakeSemaphore () ; for (int i = 0; i < MAX_SOCK_NUM; i++) { uint8_t s = W5100.readSnSR(i); if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) { _sock = i; break; } } if (_sock == MAX_SOCK_NUM) { W5100.GiveSemaphore () ; // This one was missing return 0; } _port = port; _remaining = 0; socket(_sock, SnMR::UDP, _port, 0); W5100.GiveSemaphore () ; return 1; }