uCOS/II v 2.85
ucTCPIP v 1.86
MCU - AT91SAM7X256 @ 43Mhz + RTL8201BL, порт ucTCPIP от micrium.com - свежий по состоянию на 27.12.2007
Долго отлавливал следующий баг в порте uTCP-IP на SAM7X -
в случае, если на плату приходит пара пакетов из Ethernet с малым расстоянием между ними (менее 1 мс), возможно "зависание" стека до получения следующего пакета из сети.
Картина выглядит так - приходит подряд два пакета, на каждый из которых плата должна ответить.
Плата отвечает на первый пакет, потом сетевая подсистема "зависает" (API работает, но обмена нет) до прихода еще одного пакета (неважно какого, например ARP).
Вместо
Код
---------- time ------------------------------->
[ request1 ][ request2 ] [ reply1][ reply2 ] --<time>------[ request3 ][ reply3 ]
имеем
Код
---------- time ------------------------------->
[ request1 ][ request2 ] [ reply1] ----<time>------[ any ethernet packet ][ reply2 ]
Если подряд принимаются три или более пакетов, проблема не возникает, т.к. прерывание по третьему пакету обрабатывает второй и третий.
Проблема связана с тем, что за время обработки пакета в прерывании успевает придти еще один пакет, повторно же обработка не запускается (прерывание срабатывает, но флаги EMAC_RSR корректно не установлены, т.к. были сброшены при выходе из прерывания на прошлом пакете) - код не в определяет причину прерывания.
Код
---------- time ------------------------------->
[ packet1 ][ packet 2]
[irq1]-----[irq2]-------
[-----irq1_processing:packet ready-----][----irq2_processing:reason unknown----]
Проблема решается следующим образом :
В файле net_nic.c вместо кода
Код
n_new = NIC_GetNRdy() - NIC_RxNRdyCtr; /* Determine how many NEW packets have been received */
while (n_new > 0) {
нужен код примерно такой :
Код
while ((n_new = NIC_GetNRdy() - NIC_RxNRdyCtr) > 0) {
Это позволяет отловить вышеописанную ситуацию и отреагировать на второй пакет.