Здравствуйте. Проверяю данную плату на предельных скоростях на своём протоколе, в качестве МК взят Arduino. Начал наблюдать следующие поведение. Выходной буфер сокета TX переполняется и соответственно мк подвисает, пока буфер не очистится. Очищение всего буфера происходит через определенное время, видимо, по какому-то внутреннему таймеру чипа (~200 мс). При этом такое поведение наблюдается только тогда, когда работают два микроконтроллера в режиме запись-чтение. При работе мк с компьютером выходной буфер сокета освобождается сразу как сообщение будет послано. Какое условие должно быть выполнено, чтобы буфер TX освободился? Запись в буфер->запись указателя буфера->отправка сообщения->ожидания подтверждения? Write в сокет я использую полностью как в родной Wiznet библиотеке. Read маленько модифицировал - читает в два приёма, правда в один приём тоже самое выходит.
Если значение приращения счётчика буфера превышает максимальное значение 0xFFFF, то есть больше 0x10000, счётчик буфера обнуляется... И так по кругу))
Просто надо отправить W5500 команду передачи пакета (SEND) и немного подождать...)) пока закончится передача пакета... После передачи пакета установится соответствующий флаг (см. регистр флагов) и статус команды (SEND) Sn_CR = 0x20 меняется на (SEND) Sn_CR = 0x00. (команда выполнена).
Вообще режим TX в W5500 такой: 1-Прочитайте начальный адрес буфера TX (регистр указателя Sn_TX_WR ) для записи передаваемых данных. 2-Сохраните передаваемые данные с начального адреса буфера TX (регистр указателя Sn_TX_WR). 3-После сохранения передаваемых данных обновите адрес буфера TX (регистр указателя Sn_TX_WR ) до увеличенного значения. 4-Запись команды передачи SEND. 5-Дождитесь окончания передачи (по окончанию передачи статус Sn_CR = 0x20 меняется на Sn_CR = 0x00). (команда выполнена). (из даташита): Если записать новые данные в буфер TX раньше, чем закончится текущая передача, то это может привести к ошибке передачи.
Очищение всего буфера происходит через определенное время, видимо, по какому-то внутреннему таймеру чипа (~200 мс).
это RTR (Retry Time-value Register) - период повторной передачи W5500.
W5500 ожидает подтверждение (ACK) на отправленный пакет. Если запрашиваемый узел не отвечает в течении RTR (200 мс), то W5500 ретранслирует пакет повторно.
ещё есть RCR - количество повторных ретрансляций.
если нет подтверждения (ACK) в течении RTR (200 мс) х (RCR + 1), то происходит таймаут.
таймаут для ARP = 2000 X 0.1ms X 9 = 1800ms =1.8s (по умолчанию)
таймаут для TCP = (0x07D0+0x0FA0+0x1F40+0x3E80+0x7D00+0xFA00+0xFA00+0xFA00+0xFA00) X 0.1ms = (2000 + 4000 + 8000 + 16000 + 32000 + ((8 - 4) X 64000)) X 0.1ms = 318000 X 0.1ms = 31.8s (по умолчанию)
Здесь подразумевается свободный участок для записи. Размер свободного буфера можно прочитать в регистре Sn_TX_FSR. Считается как разница Sn_TX_WR и Sn_TX_RD. В случае TCP маленько подругому. Есть внутрений ACK указатель, который сдвигается на место Sn_TX_WR в случае подтверждения и вот он видимо не двигается. При этом в связке с компьютером-подписчиком всё прекрасно работает - размер буфера уменьшается не более чем на 1-2 размеров сообщений (выводил Sn_TX_FSR в последовательный порт). При работе в паре с микроконтроллером-подписчиком видимо не долетают/не успевают обрабатываться пакеты с ACK. Я поэтому и выложил код чтения подписчиком, так как для записи код выглядит рабочим. Я посмотрел алгоритм записи в сокет - всё как в мануале и даже более - ожидание прерывания SEND_OK. Вот так выглядит алгоритм 1) Чтение Sn_TX_FSR 2) Ждём пока Sn_TX_FSR < len размер нашего пакета и параллельно проверяем соединение. 3) Считываем Sn_TX_WR в ptr 4) Записываем в буфер по адресу ptr длинной len данные data 5) Записываем новое положение указателя Sn_TX_WR ptr + len 6) Шлём команду Sock_SEND (0x20) и ждём 0x00 7) Ждём пока SnIR != SEND_OK (0x10) и параллельно проверяем соединение. зы уменьшил RTR и убедился, что этот провал обусловлен временем ожидания ACK.
1) - 2) - 3) Считываем Sn_TX_WR в add 4) Записываем в буфер W5500 по адресу Sn_TX_WR данные data и считает len (len = add + data). 5) Записываем новое положение указателя Sn_TX_WR + len 6) Шлём команду Sock_SEND (0x20) и ничего не ждём..)) Пока идёт передача в это время мой МК готовит новые данные для передачи... тайминги так расчитаны... ))
Если данных больше нет: 7 -закрывает соединение DISCON 8 -ждём FIN... 9 -закрываем сокет CLOSE. Всё))
Scaarj писал(а):
При работе в паре с микроконтроллером-подписчиком видимо не долетают/не успевают обрабатываться пакеты с ACK.
Я вывожу на экран все регистры W5500 и смотрю анализатор трафика.
Scaarj писал(а):
Есть внутрений ACK указатель, который сдвигается на место Sn_TX_WR в случае подтверждения и вот он видимо не двигается.
подтверждение чего?
SYN ACK (подтверждение нового соединения), TCP ACK (подтверждение передачи пакета - окно TCP), FIN ACK (подтверждение разрыва соединения).
у меня W5500 может после каждого пакета получать ACK: SYN... W5500 1500 байт -> перадача -1. <- ACK -1 W5500 1500 байт -> перадача -2. <- ACK -2 W5500 1500 байт -> перадача -3. <- ACK -3 ... FIN...
а может после пачки пакетов получить один ACK: SYN... W5500 1500 байт -> перадача -1. W5500 1500 байт -> перадача -2. W5500 1500 байт -> перадача -3. <- ACK -3 ... FIN...
И так и так у меня работает. Из чего я сделал вывод, что W5500 не ждёт подтверждение (ACK) на каждый отдельный пакет. Я отправляю сразу пачку пакетов и при этмом у меня буфер TX не переполняется... Главное дождаться окончания передачи перед отправкой нового пакета.)) Короче как-то так.))
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
В общем стало более менее понятно. w5500 довольно таки умный и когда пакеты прилетают слишком быстро он не отвечает на каждый пакет ACKом.
Как выглядит в моём случае. Паблишер шлёт с макс скоростью сообщения - упирается в участок буфера, который ещё не был подтверждён и подвисает в ожидание ACK. Подписчик читает постоянно прилетающие сообщения, но не шлёт ACK, а аккумулирует все подтверждения для отправки одного ACK, но этот момент всё никак не может наступить Дальше образуется пауза, но ACK почему то не посылается И вот проходит 200 мс (по умолчанию) с момента отправки первого сообщения пабом. Чип видит, что данные не были доставлены и делает ретрансмиссию. Если RCR = 0 - получим разрыв соединения по таймауту. Если RCR > 0, то заново посылаем весь буфер (как его разбивает на фреймы по 1500 понятия не имею) и получает ACK от подписчика. Если уменьшить RTR со стороны издателя, то соответственно ретрансмиссия будет раньше, чем заполнится буфер, но на осциллограмме её даже не увидеть (дёргаю ногами перед/после write/read). А вот если уменьшить RTR со стороны подписчика, то этот интервал магическим образом станет уменьшаться. То есть грубо говоря у меня в одном цикле(200 мсек) ~130 мсек это приём-передача данных, 70 мсек ожидания ACK. Если RTR для подписчика указать меньше 70 (< 700*0.1), то этот интервал станет уменьшаться и будет в точности равен времени RTR
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Ясно)) я так подробно W5500 не разбирал... Надо будет поковырять))
Да, по даташиту там есть внутренний указатель... "difference between Sn_TX_WR and the internal ACK pointer which indicates the point of data is received already by the connected peer "
Как он там работает.. без понятия)) Я не понимаю зачем он вообще нужен, если буфер 2000 байт. Это надо сначала буфер увеличивать до 16000 байт... Затем грузить в буфер кучу данных... Затем там (по идеи) должен работать автоматических фрагментатор, который нарезает фреймы по 1500 байт... и следит за их правильной отравкой)) И т.д.
В общем пришёл мне управляемый коммутатор, отзеркалил порт и увидел, что читающий МК не отсылает ACK, точнее отсылает, но не вовремя. Выглядит это как посылка N сообщений, потом те же N сообщений одним пакетом. А всего то надо было сделать, это прочитать полностью и внимательно документацию. У регистра Sn_MR, есть настройка в 5 бите - использование ACK без/с задержкой. Соответственно, задержка выставляется регистром RTR. Это я уже опытным путём выяснил Поэтому, если RTR рассылающего = RTR принимающего МК, а по умолчанию они равны 200 мс, то у нас будут постоянно ретрансмиссии и подвисания..
Прпробовал конотрлировать регистр CR после отправки SEND - сбрасывается СРАЗУ ЖЕ. В ДШ на стр. 47 сказано: "After W5500 accepts the command, the Sn_CR register is automatically cleared to 0x00. Even though Sn_CR is cleared to 0x00, the command is still being processed. To check whether the command is completed or not, please check the Sn_IR or Sn_SR."
Короче у меня проблема похожая, на большой нагрузке есть симптомы что происходит "перехлест" ТХ.. воюю дальше. (STM32F103VET6).
Есть регистр Sn_TX_FSR - Tx-free-space-register - при передаче он увеличивается. Поставил заплатку, ожидание момента когда считываемые показания из этого регистра перестанут меняться. Это довольно немало - точно не считал.. но примерно с 20-50мкс.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения