Перейти к содержанию
    

NIOS2 + TSE + PHY RTL8211E на Циклоне 4

Доброго дня плисоводам.

При разработке системы, указанной в сабже, возникли проблемы при запуске стандартного примера SSS (интерфейс с PHY - GMII). Некоторые подробности описывал тут, поэтому повторять не буду (отладка заработала).

По началу не было ни приёма, ни передачи. Но, переделал схему (оказалось, расширенный режим MSGDMA вкдючать нельзя) системы и вроде начало как-то работать - приём вроде появился: ethernet-фреймы принимаются, смотрю в обработчике прерываний приёма, вижу mac-адреса реальных девайсов в домашней сети.

А вот передача не идёт. Первый посылаемый пакет - дискавери от dhcp клиента, посылаемый dhc_request. В пошаговом режиме дохожу до выделения буфера с помощью udp_alloc, а оно завершается неудачей. В результате стек вырубает сетевой интерфейс и делает exit. Пытаюсь по шагам пройти до критического места, но не выходит. Функция udp_alloc вызывает pk_alloc, которая принимает требуемый размер буфера len=592 байта, но как только делается проверка размера, то len уже становится равным 1528. Подозреваю, что отладчик ловит вызов от приёмной ветки, там, как я понимаю, выделяется на приём пакета память исходя из размера MTU. После проверки размера вызывается getq, которая непосредственно пытается выделить память из каких-то свободных цепочек, но почему-то сразу нарывается на то, что свободных буферов уже нет, возвращает 0, ну а дальше я уже написал - в итоге exit. В чём может быть проблема?

890326799_pk_alloc(len1528).thumb.png.b7f16b1184a4843b1eaaf5ca2ee22b89.png

И вообще, какие настройки должны быть у MSGDMA? Может с ними что-то не так?

 

msgdma_tx.thumb.png.fbf1b946b5149e33daa32aff539cbfb3.png

msgdma_rx.thumb.png.f2b74aabbb2da35b393076c39255e711.png

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Во время танцев с бубном вокруг TSE и гуляниям по исходникам выяснилось что:

1. Под пакеты (как я понял, и принимаемые, и передаваемые, что странно - передача может заткнуть приём и наоборот, как в моём случае) выделяются буферы двух размеров: 128 байт под маленькие пакеты и 1536 байт под большие в количестве по 30 штук каждых. Дескрипторы буферов объединяются в связанные списки. Всё это делается в pktalloc.c:

queue   bigfreeq;    /* big free buffers */
queue   lilfreeq;    /* small free buffers */

unsigned lilbufs = NUMLILBUFS;      /* number of small bufs to init */
unsigned lilbufsiz = LILBUFSIZE;    /* big enough for most non-full size packets */
unsigned bigbufs = NUMBIGBUFS;      /* number of big bufs to init */
unsigned bigbufsiz = BIGBUFSIZE;    /* big enough for max. ethernet packet */

#ifdef NPDEBUG
PACKET pktlog[MAXPACKETS]; /* record where the packets are */
#endif

Все эти константы задаются в ipport.h. В отладочном коде есть глобальный массив pktlog, где можно все буфера посмотреть в одном массиве.

2. Оказывается, что когда в корке TSE включена возможность loopback, в исходниках одновременно включается опция promiscuous (файл ins_tse_mac.c):

  /* enable MAC */
  dat = ALTERA_TSEMAC_CMD_TX_ENA_MSK       |
        ALTERA_TSEMAC_CMD_RX_ENA_MSK       |
        mmac_cc_RX_ERR_DISCARD_mask        |
#if ENABLE_PHY_LOOPBACK
        ALTERA_TSEMAC_CMD_PROMIS_EN_MSK    |     // promiscuous mode
        ALTERA_TSEMAC_CMD_LOOPBACK_MSK     |     // promiscuous mode
#endif
        ALTERA_TSEMAC_CMD_TX_ADDR_INS_MSK  |
        ALTERA_TSEMAC_CMD_RX_ERR_DISC_MSK;  /* automatically discard frames with CRC errors */

А это означает, что TSE будет принимать всё что оказывается на входе. У меня loopback был по недоразумению включен.

3. Исходя из 1 и 2 у меня получалось, что все буферы большого размера сразу расходовались на принимаемые пакеты, ибо плата включена в сеть, где куча компов, умных розеток (их MAC-адреса я и видел в принятых фреймах) и т.д. Тем более, что буферов всего по 30 шт. Тем более в пошаговом режиме отладчика! Когда я вставал на первой же точке останова, хоть и сразу в нужном месте, но уже список bigfreeq был наполовину израсходован. Надо отключать loopback!

4. Попутно заметил фичу выделения буферов в куче, если размер пакета превышает максимальный для списка bigfreeq (1536):

PACKET pk_alloc(unsigned len)
{
   PACKET p;

   if (len > bigbufsiz) /* caller wants oversize buffer? */
   {
#ifdef HEAPBUFS
      if ((p = pk_alloc_heapbuf (len)) == NULL)
         return NULL;
#else
      return(NULL);
#endif
   }
   else
   {
      if ((len > lilbufsiz) || (lilfreeq.q_len == 0)) /* must use a big buffer */
         p = (PACKET)getq(&bigfreeq);
      else
         p = (PACKET)getq(&lilfreeq);

      if (!p)
         return NULL;
   }
  //...

Но, как я понял, HEAPBUFS не определена (задаётся в ipport.h). Так что при больших размерах пакетов будет пшик. Дефайн HEAPBUFS убран условной компиляцией через определение NOT_USED (задаётся в редакторе BSP для "новых версий" Iniche стека). Там вообще много чего выкидывается интересного. И как можно вносить в ipport.h свои правки, если при перегенерации BSP всё пропадёт (как пропадают, например, мои добавки для PHY RTL8211E в файлы altera_avalon_tse.h/c, приходится их возвращать). Жаль не сделали "окна" для пользовательских правок как в студии для STM32.

Пошёл убирать loopback. Продолжение следует...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...продолжение опупеи.

Убрал loopback, но радости это не принесло - передачи так и нет, хотя интерфейс уже вырубаться перестал, ведь буферов хватает (если в отладке не вставать).

Далее в дело вступил осциллограф и помог: оказалось, что на PHY подавался GTX_CLK (такт передачи) частотой 100 МГц вместо 125. Тут я и вспомнил, что когда понижал частоту ядра NIOS и SDRAM до 100 (было 125), то забыл, что эта же частота идёт на PHY (её же, кстати, ещё надо переключать 125/25/2.5 в зависимости от скорости). В итоге пришлось ещё один выход в PLL организовать для 125 МГц. Далее пересобрал проект fpga и начал шить его в epcq (без прицепленного приложения). Когда прошивка завершилась и я нажал кнопку сброса, антивирус бодро сообщил мне, что в локальной сети появился новый клиент и показал mac-адрес моего девайса! Я понял, всё поехало!

Я удивился, что приложение пошло, хотя я его не прошивал. Но потом понял, что оно же осталось в epcq с прошлого раза, я же полное стирание флеша не делал, а адреса в нём не поменялись, так что старое приложение вступилось (странно только, что SystemID то изменился, должно ли было запускаться?). На пинги плата отзывается.

В итоге SSS работает, проверил, запустив в WSL Ubuntu (чтобы в Windows telnet не добавлять) команду

telnet 192.168.81.99 30

Где 30 - номер порта, который обязательно указывать. SSS показал меню команд, далее попробовал вводить команды, мигать светодиодами и выкл/вкл "шоу" показа случайных чисел на семисегментном индикаторе (шоу - вывод случайных значений с периодичностью 50мс). Шоу, кстати включено по умолчанию, что помогает понять успешный запуск приложения. Всё работает, ура.

Подсистему TSE (что я приводил выше) доработал - выкинул лишний pipeline. В результате это избавило от красноты таймингов после компиляции. В плане таймингов помог сам PHY RTL8211E - у него была включена задержка 1.5-2 нс по передаче и приёму. Так что с этим вообще не заморачивался. Констрейны задавал так (если кому интересно):

create_clock -name CLK -period 50MHz [get_ports {CLK}]
create_clock -name RXCLK -period 125MHz [get_ports {GMII_RXCLK}]

derive_pll_clocks
derive_clock_uncertainty

set_clock_groups -asynchronous -group {CLK} -group {RXCLK}

set_input_delay -clock RXCLK -max 2 [get_ports {GMII_RXD[*] GMII_RXDV GMII_RXER}]
set_input_delay -clock RXCLK -min 1.2 [get_ports {GMII_RXD[*] GMII_RXDV GMII_RXER}]

set_false_path -from [get_ports KEY[*]]
set_false_path -from [get_ports SW[*]]
set_false_path -to [get_ports LED[*]]
set_false_path -to [get_ports ELED[*]]
set_false_path -to [get_ports SEG[*]]
set_false_path -to [get_ports DIG[*]]

Последние шесть строчек для игнора кнопок/светодиодов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...