реклама на сайте
подробности

 
 
> Важно ! uC-TCPIP bug @ SAM7X port, Некорректная обработка пакетов
_dem
сообщение Dec 27 2007, 18:47
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 263
Регистрация: 2-02-07
Из: CN, Ukraine
Пользователь №: 24 970



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) {


Это позволяет отловить вышеописанную ситуацию и отреагировать на второй пакет.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
defunct
сообщение Dec 27 2007, 23:40
Сообщение #2


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(_dem @ Dec 27 2007, 21:47) *
нужен код примерно такой :

идеология неправильная imho. чем обрабатывать пакет в прерывании, надо бы просто потушить флаг в RSR и взвести семафор чтобы RX таск начал вынимать и обрабатывать пакеты.
Go to the top of the page
 
+Quote Post
timofey_99
сообщение Dec 28 2007, 01:15
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 28-10-06
Пользователь №: 21 741



Цитата(defunct @ Dec 28 2007, 02:40) *
идеология неправильная imho. чем обрабатывать пакет в прерывании, надо бы просто потушить флаг в RSR и взвести семафор чтобы RX таск начал вынимать и обрабатывать пакеты.


Всё верно, но нужен комплекс мер. И совершенно необходимо знать сколько новых пакетов появилось по прерыванию. Например, в стеке lwIP, точнее в реализации с SAM7X EMAC, мне видится, что авторы не учли, что флаг прерывания взводится когда ПДП положил один или более фреймов в буфер, вот это "более" - ключевое слово. Семафор с блокировкой на 100 мс, первый пакет вычитывается по сигналу из прерывания, а остальные уже каждые 100 мс, за это время легко возникает ситуация BUFFER NOT AVAILABLE и неоднократно... Счётчик пакетов нужен таки при работе с семафором, если не все пакеты вычитаны из буферов, не блокироваться на семафоре
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 13:53
Рейтинг@Mail.ru


Страница сгенерированна за 0.01428 секунд с 7
ELECTRONIX ©2004-2016