Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ethernet + Cyclone + Nios
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Системы на ПЛИС - System on a Programmable Chip (SoPC)
Страницы: 1, 2, 3, 4, 5, 6, 7, 8
vadimuzzz
Цитата(dim99 @ Mar 23 2010, 13:50) *
Отправляю пакеты с pc, естественно посылается еще куча всего (broadcast к примеру), как среди этих всех пакетов отсеять свои?
Понятно, что нужно определить какую-то служебную информацию в пакете, чтоб считать его своим.

по MAC-адресам (это основной адрес вашего устройства) TSE фильтрует сам (при выключенном promisc). если этого недостаточно - можно делать дополнительные фильтры - по IP, протоколам, портам и т.п. - естественно, программно. broadcast тут не в кассу, т.к. нужен, например, для ARP. Хотите, скажем, попинговать адрес, сначала идет broadcast ARP-запрос: кто имеет такой-то айпишник, в ответ получает MAC-адрес.
Цитата
И как быть, если нужно обработать или скопировать пришедшие данные, когда уже пришел следующий пакет и возникает прерывание, ведь после него все мои данные от предыдущего пакета сотрутся?
Или нужно выключать dma, а после обработки включать и отсылать пакет на PC с сообщением об успешном приеме, чтобы синхронизироваться.

тут все от вашей задачи зависит. если кровь из носу надо несколько пакетов принять - делаете очередь пакетов (можно посмотреть в LwIP или NicheStack). а нет - затыкаете прием на время обработки пакета и отправки квитка о готовности.
wpost
А кто-нить реализовывал UDP/IP на основе TSE и NicheStack???
Может кто-нить поделиться рабочим примером?
vadimuzzz
наткнулся тут случайно: "Description: VHDL implementation of a UDP/IP core! Area-optimized for direct PC-FPGA communication! "

http://opencores.org/project,udp_ip__core
dim99
Ну вот, стоило перенести свой ethernet в другой проект, как тут же всплыли старые ошибки.

После TseMacSgDmaReadInit заходит в TseMacRxRead выполняет
alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, (alt_sgdma_descriptor *)rxDesc);

и впадает в постоянную обработку прерывания TseMacSgDmaRxIsr.

Дескрипторы в норме, отдаю ему currdescriptor_ptr, который подготовлен для записи данных.
Результат выполнения async_transfer=0, ошибок нет.
В прошлый раз эта проблема решилась, когда оставил все дескрипторы, как в примере vadimuzzz.

Так теперь беру этот же работающий проект, переношу код и старые ошибки вылазят.
vadimuzzz
Цитата(dim99 @ Apr 2 2010, 13:11) *
Так теперь беру этот же работающий проект, переношу код и старые ошибки вылазят.

выкладывайте последнюю версию и содержимое регистров SGDMA до и после входа в обработчик прерывания
dim99
Все разрешилось, прошу прощения.

В SOPC builder проморгал связь: descriptor_memory->sgdma_rx, отсюда и проблемы.
wpost
пытаюсь сделать свой проект на основе hello_world от dim99 возникло несколько вопросов

1. какой объем памяти вы отводите под descriptor_memory?
2. можно ли выделить пространство в основной ОЗУ процессора под descriptor_memory или это обязательно должна быть отдельная память?
3. Как удалось наладить приемпакетов? (поделитесь, плз, последней версией hello_world.с)
dim99
1. descriptor_memory: 4k, хотя можно меньше - 4 дескриптора x размер дескриптора. (2 - прием\отправка, 2 заглушки)
2. лучше отдельной памятью, но наверное можно и в основной. (в примере была отдельная)
3. Нажмите для просмотра прикрепленного файла
wpost
Цитата(dim99 @ Apr 3 2010, 10:43) *
1. descriptor_memory: 4k, хотя можно меньше - 4 дескриптора x размер дескриптора. (2 - прием\отправка, 2 заглушки)
2. лучше отдельной памятью, но наверное можно и в основной. (в примере была отдельная)
3. Нажмите для просмотра прикрепленного файла


Спасибо огромное!
передача вообще чисто работает, а вот с приемом есть трудность - пропадают первые 2 байта пакета... я, конечно, вышел из положения выставлением IP Align в мегафункции, но интересно где может быть косяк. (rx_pkt начинается с третьего байта).


З.Ы.: С ПЛИС я не новичок, а вот с ниос и С еще начинающий, так что извиняите за глупые вопросы из области программирования =)
dim99
Да, отлаженный soft это всегда здорово, скажите отдельное спасибо vadimuzzz.

пропадают первые 2 байта пакета - это как раз и есть align ip.
wpost
Цитата(dim99 @ Apr 5 2010, 23:24) *
пропадают первые 2 байта пакета - это как раз и есть align ip.


я так не думаю... при отправке четко: если нет IP align то отправляется с первого байта, если есть - то с третьего...
а на приеме мы тоже видим смещение на 2 байта (потеря без align и начало с первого байта с align)... ip Align просто компенсирует наш косяк...

когда я работал с TSE через конечные автоматы, то ip align работал четко симметрично на прием и передачу...
wpost
похоже дело было в кривой цепочке include.... подцепил по другому все модули и проблема самоликвидировалась.... всё стало как нужно и на приеме... если Align то принимает 2 байта нулей, потом пакет, если не Align то сразу идет пакет...
dim99
wpost
Вы кстати как инициализировали PHY?
Хочется узнать, только у меня отпадает link, когда через MDIO выставляю контрольные биты для PHY(поэтому и приходится на PC режим задавать. чтобы срабатывал auto-neg).
wpost
Цитата(dim99 @ Apr 6 2010, 19:21) *
wpost
Вы кстати как инициализировали PHY?
Хочется узнать, только у меня отпадает link, когда через MDIO выставляю контрольные биты для PHY(поэтому и приходится на PC режим задавать. чтобы срабатывал auto-neg).


я не спользую MDIO вообще.. PHY у меня DP83848I
auto-neg у меня жестко включен на уровне схемотехники (pin AN_EN pull-up)
вся инициализация сводится к достаточно длинному аппаратному ресету, выдаваемому альтерой на соответствующую ногу PHY. после чего сразу устанавливается линк на 100.
далее я записываю MAC адрес в соответстующие адреса мегафункции (TSE) и
записываю в управляющий регистр TSE в 0x00000023. где 3 означает включить прием и передачу, а 2 - говорит TSE автоматически убирать PAD (дополнение нулями маленьких пакетов до минимальной длины).

вот собственно и все настройки.
опыт применения DP83848I достаточно большой (3 года), но с другим процессором LPC2468. C MDIO за это время ни разу не заморачивались. auto-neg вроде как работает... хотя проверить трудно т.к. у меня все хабы и PC умеют переворачивать.
wpost
И всетаки пример "Hello_world" принимает пакеты неправильно...
если отправлять одинокие редкие пакеты всё кажется лучезарно, но...
если отправить фрагментированный пакет (много не надо достаточно двух кусков), то в массиве rx_pkt оказывается только последний пакет, а первый пропадает.
я так понимаю что проблема в том, что они диут подряд и новый пакет перекрывает старый при вычитывании из SGDMA... изучение вопроса привело к обнаружению "Read until EOP = 0" см ниже

Цитата(vadimuzzz @ Mar 14 2010, 21:47) *
...

Код
alt_avalon_sgdma_construct_stream_to_mem_desc(
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST],  // descriptor I want to work with
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST],  // pointer to "next" <- это "левый" дескриптор
            uncached_packet_payload,            // starting write_address
            0,                                  // read until EOP
            0);


...


постановка "Read until EOP = 1" приводит к зацикливанию в прерывании на первом же заходе в него... т.е. на arp пакете... как решить проблему пока не знаю, если у кого есть мысли help!!!
vadimuzzz
Цитата
я так понимаю что проблема в том, что они диут подряд и новый пакет перекрывает старый при вычитывании из SGDMA

не должно такого быть, один дескриптор - один пакет. read until EOP=0 говорит о том, что читать, пока EOP не встретится (длина пакета ведь заранее неизвестна). ненулевое значение в этом поле означает сколько байт читать. надо ловить первое прерывание и разбираться, как дескриптор передали SGDMA, не обработав первый пакет.
wpost
Цитата(vadimuzzz @ Apr 12 2010, 19:56) *
не должно такого быть, один дескриптор - один пакет. read until EOP=0 говорит о том, что читать, пока EOP не встретится (длина пакета ведь заранее неизвестна). ненулевое значение в этом поле означает сколько байт читать. надо ловить первое прерывание и разбираться, как дескриптор передали SGDMA, не обработав первый пакет.


понятно.

тогда есть такой вопрос
при вот таком описании
Код
alt_sgdma_descriptor *desc = (alt_sgdma_descriptor *) ONCHIP_MEMORY2_1_BASE;
alt_sgdma_descriptor *currdescriptor_ptr;

идет обращение
Код
currdescriptor_ptr =  &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST];

тут не косяк??? мне что-то подсказывае что должно быть так
Код
currdescriptor_ptr =  desc+ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST;

я прав?
vadimuzzz
Цитата(wpost @ Apr 12 2010, 23:40) *
тут не косяк??? мне что-то подсказывае что должно быть так
Код
currdescriptor_ptr =  desc+ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST;

я прав?

нет, тогда уж
Код
currdescriptor_ptr =  desc+sizeof(alt_sgdma_descriptor)*ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST;

скорее всего в обработчике прерывания не запретили прием, а первый пакет еще не разобрали, когда пришел следующий.
wpost
Цитата(vadimuzzz @ Apr 13 2010, 02:38) *
скорее всего в обработчике прерывания не запретили прием, а первый пакет еще не разобрали, когда пришел следующий.


пока не очень просек как это нужно сделать...
но количество заходов в прерывание правильное... отправил 2 пакета, 2 раза и зашел... но принял одинаковый пакет (последний)

реально получается что при первом заходе в прерывание в currdescriptor_ptr уже есть первый пакет и вызов функции TseMacReceive(); его затирает...
wpost
Переместил функцию TseMacReceive(); из начала обработки прерывания в конец => просерать пакеты перестало, но выяснился новый баг - последний пакет принимается дважды

Код
void TseMacSgDmaReadInit()
{
    alt_u32 *uncached_packet_payload;
    uncached_packet_payload = (void *)alt_remap_cached ((volatile void*) rx_pkt, 4);
    
    currdescriptor_ptr =  &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST];
    nextdescriptor_ptr = (alt_sgdma_descriptor *) IORD_ALTERA_TSE_SGDMA_DESC_NEXT(currdescriptor_ptr);
    blockdescriptor_ptr = currdescriptor_ptr;
    alt_avalon_sgdma_construct_stream_to_mem_desc(
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST],  // descriptor I want to work with
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST],  // pointer to "next"
            uncached_packet_payload,            // pkt_array[chain_loop]->nb_buff,                     // starting write_address
            0,                                  // read until EOP
            0);
  
    currdescriptor_ptr =  &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST];
    nextdescriptor_ptr = (alt_sgdma_descriptor *) IORD_ALTERA_TSE_SGDMA_DESC_NEXT(currdescriptor_ptr);
    
    int desc_status = 1;
    desc_status = alt_avalon_sgdma_check_descriptor_status(currdescriptor_ptr);
    desc_status = alt_avalon_sgdma_check_descriptor_status(nextdescriptor_ptr);  
    desc_pointer = currdescriptor_ptr;
    
    TseMacRxRead(currdescriptor_ptr);
    
    alt_u32 sgdma_control_rx = 0;
    sgdma_control_rx = IORD_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_1_BASE);
    alt_u32 sgdma_status_rx = 0;
    sgdma_status_rx = IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_1_BASE);
}

int TseMacReceive(){
    alt_u32 *uncached_packet_payload;
    alt_u8 tempVar;
    desc_pointer = currdescriptor_ptr;
    alt_u32 desc_stat=0;
    desc_stat = IORD_ALTERA_TSE_SGDMA_DESC_STATUS(desc_pointer);
    
    if ((desc_stat & ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) )
    {
        desc_pointer->status&=~ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK;
        nextdescriptor_ptr = (alt_sgdma_descriptor *)IORD_ALTERA_TSE_SGDMA_DESC_NEXT(desc_pointer);
    
        uncached_packet_payload = (void *)alt_remap_cached ((volatile void*) rx_pkt, 4);
       tempVar = IORD_8DIRECT(&nextdescriptor_ptr->control, 0 );
    
        alt_avalon_sgdma_construct_stream_to_mem_desc(
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_FIRST_RX_SGDMA_DESC_OFST],  // descriptor I want to work with
            (alt_sgdma_descriptor *) &desc[ALTERA_TSE_SECOND_RX_SGDMA_DESC_OFST],  // pointer to "next"
            uncached_packet_payload,            // starting write_address
            0,                                  // read until EOP
            0);                                 // don't write to constant address
        
        IOWR_8DIRECT(&nextdescriptor_ptr->control, 0, tempVar);
        
      //  desc_pointer = nextdescriptor_ptr;
            }
    return 1;
}

alt_u32  TseMacRxRead(alt_sgdma_descriptor *rxDesc)
{
    
    alt_u32 sgdma_status_rx = 0;
    sgdma_status_rx = IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_1_BASE);
    alt_u32 sgdma_control_rx = 0;
    sgdma_control_rx = IORD_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_1_BASE);
    
    alt_u8 result = 0;
    while ( (IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_1_BASE) & ALTERA_AVALON_SGDMA_STATUS_BUSY_MSK) ){
    }
    result = alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, (alt_sgdma_descriptor *) rxDesc /*&rxDesc[0]*/);
    

        
return 0;
}


int TseMacSgDmaRxIsr(void * context, alt_u32 id)
{
    alt_u32 rx_section = 0;
    rx_section = IORD_ALTERA_TSEMAC_RX_SECTION_EMPTY(sgdma_rx_dev);
    rx_section = IORD_ALTERA_TSEMAC_CMD_CONFIG(TRIPLE_SPEED_ETHERNET_0_BASE);
    
          //TseMacReceive();    
    IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_1_BASE, 0x00);
    IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_1_BASE, ALTERA_TSE_SGDMA_INTR_MASK);

        
    if((IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_1_BASE) & ALTERA_AVALON_SGDMA_STATUS_CHAIN_COMPLETED_MSK )){
       TseMacRxRead(currdescriptor_ptr/*desc*/);
    }    
    
    IOWR_ALTERA_AVALON_SGDMA_STATUS(SGDMA_1_BASE,0xFF);
    
       // тут у меня обработка принятого пакета  &rx_pkt[0]

     TseMacReceive();                
return 0;
}
vadimuzzz
это неправильно, порядок должен быть такой:
*проверка на ошибки при приеме
*обработка пакета (напр., помещение в очередь)
*вызов alt_remap_cached и alt_avalon_sgdma_construct_stream_to_mem_desc (подготовка дескрипторов к проведению очередной транзакции)
*вызов alt_avalon_sgdma_do_async_transfer (начало асинхронной транзакции)

это, что касается обработчика прерывания. в начале работы вызывается read_init, которая делает последние 2 действия. посмотрите код в оригинальном драйвере.
wpost
Цитата(vadimuzzz @ Apr 14 2010, 07:25) *
это неправильно, порядок должен быть такой:
*проверка на ошибки при приеме
*обработка пакета (напр., помещение в очередь)
*вызов alt_remap_cached и alt_avalon_sgdma_construct_stream_to_mem_desc (подготовка дескрипторов к проведению очередной транзакции)
*вызов alt_avalon_sgdma_do_async_transfer (начало асинхронной транзакции)

это, что касается обработчика прерывания. в начале работы вызывается read_init, которая делает последние 2 действия. посмотрите код в оригинальном драйвере.


Т.е. получается в процедуре read_init
функция alt_remap_cached задает формат работы с памятью (32 разрядные данные),
alt_avalon_sgdma_construct_stream_to_mem_desc указывает SGDMA через какую память и куда копировать,
alt_avalon_sgdma_do_async_transfer взводит SGDMA в ожидание приема.

когда прием закончился, то попадаем в наше прерывание где решаем что делать с принятым пакетом, после чего снова готовим дискриптор (alt_avalon_sgdma_construct_stream_to_mem_desc) и взводим SGDMA на ожидание приема следующего пакета (alt_avalon_sgdma_do_async_transfer).

по факту получается как-то так.

но есть косяк... если отправить фрвгментированный пакет (ping -l 9000 -n 1 192.168.0.5) следующую картину: пакеты приходят кучно принимаем 6 пакетов и после заходим еще раз в прерывание и принимаем повторно 6-ой пакет. на меньшем количестве тоже самое, последнее прерывание - двойное...

ладно, отправляем больше пакет (ping -l 20000 -n 1 192.168.0.5)
картина: пакеты приходят кучно принимаем 7 пакетов (число всегда постоянное), после 7-ого в прерывание больше не заходит.....

Если слать пинги не фрагментированные любой цикличности (ping -n 50 192.168.0.5) то они будут приниматься нормально без сбоев, но каждый дважды (т.к. он последний в "кучной" транзакции)...

где-то лажа... но пока не понятно, где именно...
wpost
Цитата(wpost @ Apr 14 2010, 18:50) *
ладно, отправляем больше пакет (ping -l 20000 -n 1 192.168.0.5)
картина: пакеты приходят кучно принимаем 7 пакетов (число всегда постоянное), после 7-ого в прерывание больше не заходит.....


Проблема 7-и пакетов решилась очень просто - исправлением ошибки в размере FIFO... он у меня был 2048*32 при необходимых 16384*32
vadimuzzz
что-то непонятно все это. насколько я понимаю, бороться с фрагментацией пакетов дело не драйвера, а IP. для любого драйвера можно подобрать условия, при которых он начнет терять пакеты, это нормальная ситуация, IP учитывает такую возможность. фокусы с "ping -l 20000" на мой взгляд можно рассматривать лишь в роли некоторого стресс-теста, а не как абсолютный показатель (кстати, попробуйте "ping -i 0" + длину побольше). бороться с потерей пакетов путем увеличения буферов, мне кажется, бесперспективно: любой буфер можно зафлудить и переполнить, если обработчик прерывания еле ворочается. так что если хотите расшить узкое место, то начинать надо с прерываний, это известная проблема ниоса. больше интересен факт размножения пакетов. как вы его фиксируете?
wpost
Цитата(vadimuzzz @ Apr 15 2010, 19:57) *
что-то непонятно все это. насколько я понимаю, бороться с фрагментацией пакетов дело не драйвера, а IP. для любого драйвера можно подобрать условия, при которых он начнет терять пакеты, это нормальная ситуация, IP учитывает такую возможность. фокусы с "ping -l 20000" на мой взгляд можно рассматривать лишь в роли некоторого стресс-теста, а не как абсолютный показатель (кстати, попробуйте "ping -i 0" + длину побольше). бороться с потерей пакетов путем увеличения буферов, мне кажется, бесперспективно: любой буфер можно зафлудить и переполнить, если обработчик прерывания еле ворочается. так что если хотите расшить узкое место, то начинать надо с прерываний, это известная проблема ниоса. больше интересен факт размножения пакетов. как вы его фиксируете?


Да согласен, обработка прерывания сделана не лучшим образом, медленно ворочается... но пока так... когда более менее отлажусь попробую выйти из положения задав частоту процу 100-150 МГц (сейчас 50)

интересный момент, мои BBlaster-ы не хотят заходить в дебаг если я строю ниос систему на частоте более 50.
пробовал как LPT blaster, так и USB... итог один не может остановить процессор по ресету... на 50 работают оба программатора нормально...

размножение последнего пакета из пачки пакетов замечено при постановке точки останова в прерывание и выводе на консоль идентификатора и смещения пакета. сейчас борюсь простым путем - сравниваю идентификатор и смещение с предыдущим пакетом, при совпадении выхожу из прерывания.

так же отмечу, что я вызываю функцию TseMacReceive(); в конце обработки прерывания, а не в начале как вы... таким образом, я не теряю первого пакета из пачки... я думаю тут тесная взаимосвязь. Вы принимали один пакет т.к. ловили всегда второй. попробуйте свой драйвер на прием фрагментированного пинга и вы пропустите пакет со смещением 0....
d1n1s
Доброе время суток)
с TSE начал работать недавно, очень помогла эта тема. Возникло пару вопросов:
1) массив данных находится в памяти(100-500кб), и его надо передат по udp с максимальной скорость, как с минимальной задержкой формировать udp сообщение, имеется ввиду алгоритм, типа сначала десккриптор на заголовок потом на данные и потом уже трансляция в сеть, я правильно мыслю?
2) Как максимально быстро считать контрольную сумму? пробовал через С2H, хороший выйгрыш только на длинных пакетах, также видел в примера встраивание этой функции в sgdma.
vadimuzzz
Цитата
и его надо передат по udp с максимальной скорость

именно по UDP? на raw ethernet сокетах скорость выше, да и с заголовками возни меньше.
по 1) пакет надо передавать TSE целиком, переключать дескриптор с заголовка на данные не получится. напрашивается такой вариант: подготовить буфер, вбить туда заголовок, потом дать смещение и при помощи DMA скопировать данные из массива. после этого пакет можно отдавать в сеть. есть другой вариант: данные в массиве располагать не подряд, а фрагментами, чтобы в свободное место потом вписывать заголовки. тут скорость повыше будет.
по 2) максимально быстро сумма считается компонентом с DMA (не sgdma, а именно компонент с Avalon-MM мастером). по идее, туда же можно прикрутить логику для работы с заголовками
wpost
Цитата(vadimuzzz @ Apr 19 2010, 11:40) *
... при помощи DMA скопировать данные из массива в буфер.


А у вас случайно нет рабочего примерчика данной операции?
vadimuzzz
Цитата(wpost @ Apr 19 2010, 22:47) *
А у вас случайно нет рабочего примерчика данной операции?

а чем из примеров в Software Developer`s Handbok не устраивает?
Код
#include <stdio.h>
#include <stdlib.h>
#include "sys/alt_dma.h"
#include "system.h"
static volatile int rx_done = 0;
/*
* Callback function that obtains notification that the data
* is received.
*/
static void done (void* handle, void* data)
{
    rx_done++;
}
/*
*
*/
int main (int argc, char* argv[], char* envp[])
{
    int rc;
    alt_dma_txchan txchan;
    alt_dma_rxchan rxchan;
    void* tx_data = (void*) 0x901000; /* pointer to data to send */
    void* rx_buffer = (void*) 0x902000; /* pointer to rx buffer */
    /* Create the transmit channel */
    if ((txchan = alt_dma_txchan_open("/dev/dma_0")) == NULL)
    {
        printf ("Failed to open transmit channel\n");
        exit (1);
    }
    /* Create the receive channel */
    if ((rxchan = alt_dma_rxchan_open("/dev/dma_0")) == NULL)
    {
        printf ("Failed to open receive channel\n");
        exit (1);
    }
    /* Post the transmit request */
    if ((rc = alt_dma_txchan_send (txchan,
        tx_data,
        128,
        NULL,
        NULL)) < 0)
    {
        printf ("Failed to post transmit request, reason = %i\n", rc);
        exit (1);
    }
...
wpost
Цитата(vadimuzzz @ Apr 20 2010, 02:54) *
а чем из примеров в Software Developer`s Handbok не устраивает?


Да, я тоже думал, что вот оно счастье... но...
к инициализации обоих каналов DMA притензий нет - всё чисто... а вот с приемом и передачей не получается

Код
    int psize = 528; // размер передаваемого массива
    alt_u8 *rx_buf;
    alt_u8 *tx_buf;
   int rc;
    
    

tx_buf = packet+34;  // указатель на место откуда
rx_buf = 34+pkt_pointer+offset; // указатель куда

     if ((rc = alt_dma_txchan_send ( txchan,
                                    tx_buf,
                                    psize,
                                        NULL,
                                        NULL)) < 0)
        {
        printf ("Failed to post transmit request, reason = %i\n", rc);
        exit (1);
        }
      
    if ((rc = alt_dma_rxchan_prepare (  rxchan,
                                       rx_buf,
                                       psize,
                                        done,
                                        NULL)) < 0)
        {
        printf ("Failed to post read request, reason = %i\n", rc); // вот тут вылетаем с кодом -22
        exit (1);
        }
        /* wait for transfer to complete */
        while (!rx_done);
                      #ifdef DEBUG_IP
                      printf ("DMA transfer successful!\n");
                      #endif

Вылетаем на приеме с rc = -22
DASM
"по 2) максимально быстро сумма считается компонентом с DMA (не sgdma, а именно компонент с Avalon-MM мастером). по идее, туда же можно прикрутить логику для работы с заголовками" - а нету ли примерчика как КС считать одновременно с передачей по DMA ?
vadimuzzz
Цитата(wpost @ Apr 20 2010, 15:32) *
Вылетаем на приеме с rc = -22

похоже на то, что данные не выровнены. попробуйте так:
Код
    void* tx_data = (void*) ...; /* pointer to data to send */
    void* rx_buffer = (void*) ...; /* pointer to rx buffer */


Цитата(DASM @ Apr 20 2010, 16:12) *
а нету ли примерчика как КС считать одновременно с передачей по DMA ?

на альтере есть пример nios crc acceleration. не вижу проблем приделать к нему передачу по DMA
vadimuzzz
наконец-то дошли руки до альтеровского TSE. накидал проект NIOS+Ethernet и к нему драйвер. код, который приводили в этой ветке читать было лень, написал с нуля + кастрировал по возможности. что нужно, чтобы собрать и запустить: проверить в system.h имена/адреса компонентов, убрать Init_SDR (это для железа на моей плате), закомментировать alt_printf`ы (если нет jtag_uart). в network.c есть огрызок ARP+ICMP, так что проц может отвечать на пинги. пропажи/размножения пакетов не замечено.
int MAC_init() - инициализация
int tse_sgdmaRx_isr(void * context, alt_u32 irqnum) - обработчик прерывания на прием
int tse_mac_raw_send(char * data, unsigned data_bytes) - отсылка пакета (синхронная транзакция)
wpost
vadimuzzz огромное спасибо! посмотрим внимательно!

Есть вопрос не совсем по TSE... с подобной проблемой ранее сталкивался dim99 - по шагам программа работает как надо, в "бегущем" режиме в памяти нули... но в моем случае проблемы уже с DMA... кеширование не использую, так что alt_dcache_flush не помогает... интересна природа явления...
ставлю контрольную точку за циклом передачи DMA после снятия сигнала bysy. и смотрю память - часть данных есть и где нужно, а часть данных нули (неизмененная)... через несколько шагов в низ по программе в памяти появляются пропавшие данные, но уже поздно... по шагам прохожу все данные оказываются на своих местах как нужно... в чем может быть фишка?
vadimuzzz
Цитата(wpost @ Apr 29 2010, 22:56) *
в чем может быть фишка?

трудно сказать, слишком неопределенно. если дело не в кэшах, то м.б. флаги оптимизации компилятора (наблюдал "интересные" вещи, если -Os включен). ну, а если проблема именно с DMA, то выбросить все лишнее и код смотреть. какой режим, память-память или с периферией?
Reanimator++
Теперь и у меня встал вопрос Ethernet-a.

Есть своя отладочная плата с циклоном 2 и SDRAM, к ней можно прицепить все что угодно. Есть Nios2.
Нужен TCP порядка 16-32 сессий одновременно, поток данных небольшой (1 Мбит максимум).

Собственно, какой наикратчайший путь получения результата?
Т.е. какую выбрать микросхему, какую корку к ниосу прицепить и какую ось ставить чтобы у нее были драйвера к этой корке?
Есть ли накатанное решение или все с нуля пишут?
vadimuzzz
Цитата(Reanimator++ @ Jan 15 2011, 09:25) *
Т.е. какую выбрать микросхему, какую корку к ниосу прицепить и какую ось ставить чтобы у нее были драйвера к этой корке?
Есть ли накатанное решение или все с нуля пишут?

если ориентироваться NicheStack TCP/IP, то список поддерживаемых PHY можно посмотреть в драйверах. добавить свою микросхему - пару десятков строчек, если это простенькие чипы, а не монстры а-ля марвел.

если же хочется ось, то посмотрите тут:
http://www.alterawiki.com/wiki/UCOSII
http://www.alterawiki.com/wiki/ECos
http://www.alterawiki.com/wiki/FreeRTOS
http://www.alterawiki.com/wiki/UClinux
Reanimator++
Почитал доки от альтеры, да все у них уже есть. Triple Speed Ethernet корка для работы с PHY (считай любым ибо стандартный интерфейс), для нее драйвера в BSP и NicheStack, завязанный на UCOS. Базовое решение есть, будем изучать.
Закажу DP83848C как первую микросхему из доки по TSE.
Очередной раз спасибо, ув. vadimuzz sm.gif
Reanimator++
Увы, TSE в мой дизайн уже не влезает (
С точки зрения стоимости выгоднее помещать MAC в плис (lan91c111 стоит почти тыщу, в то время как любой другой PHY порядка двух сотен).
С точки зрения простоты прицепляния по идее лучше внешний MAC. Есть ли альтернативы lan91c111 по цене? И если у PHY интерфейс стандартизирован, то как обстоит дело с внешним MAC?
У меня есть старый Ethernet модуль на основе Wiznet W5100 (там есть и PHY и MAC и TCP и даже PPPoE), можно ли к нему прицепить NicheStack? (просто надо больше чем 4 сокета визнетовских)

Или не морочать себе голову и развести плату с DP83848C и плисиной пожирнее?
avacs
Цитата(vadimuzzz @ Apr 29 2010, 10:09) *
наконец-то дошли руки до альтеровского TSE. накидал проект NIOS+Ethernet и к нему драйвер. код, который приводили в этой ветке читать было лень, написал с нуля + кастрировал по возможности. что нужно, чтобы собрать и запустить: проверить в system.h имена/адреса компонентов, убрать Init_SDR (это для железа на моей плате), закомментировать alt_printf`ы (если нет jtag_uart). в network.c есть огрызок ARP+ICMP, так что проц может отвечать на пинги. пропажи/размножения пакетов не замечено.
int MAC_init() - инициализация
int tse_sgdmaRx_isr(void * context, alt_u32 irqnum) - обработчик прерывания на прием
int tse_mac_raw_send(char * data, unsigned data_bytes) - отсылка пакета (синхронная транзакция)


Респект vadimuzzz за выложенный проект (я так понял это что то наподобие SDR приемника с Eth), очень помог в освении TSE.
Теперь вопрос ближе, ни кто не реализовывал Telnet server, без использования OS, на базе данного проекта. Я попытался... но чет не очень разобрался в протоколе Telnet... laughing.gif Для анализа TCP\IP использую Wireshark, но наложение протокола Telnet на IP-TCP не понял. может кто подскажет где искать или кто делал или делает? Собственно нужен упрощенный телнет, с авторизацией и настройкой 5-10 параметров. Спасибо всем кто откликнется.
vadimuzzz
Цитата(Reanimator++ @ Jan 17 2011, 00:00) *
Увы, TSE в мой дизайн уже не влезает

TSE - это слишком неоднозначно, какую версию его вы пробовали? еще есть опенкоровский MAC. Сколько ресурсов доступно?
Цитата
С точки зрения простоты прицепляния по идее лучше внешний MAC. Есть ли альтернативы lan91c111 по цене? И если у PHY интерфейс стандартизирован, то как обстоит дело с внешним MAC?
У меня есть старый Ethernet модуль на основе Wiznet W5100 (там есть и PHY и MAC и TCP и даже PPPoE), можно ли к нему прицепить NicheStack? (просто надо больше чем 4 сокета визнетовских)

я в свое время отказался от внешнего MAC именно из-за цены, ничего не нашел. даже сложилось мнение (личное), что внешние MAC`и в принципе непопулярны, потому и дороги. т.к. практически в любом семействе современных контроллеров/процессоров есть модификации с MAC на борту. ну и насчет простоты прицепляния поспорю - RMII - 6 проводов.

тут смотрели?
http://www.smsc.com/index.php?tid=145
http://www.smsc.com/index.php?tid=149

Цитата(avacs @ Jan 18 2011, 00:54) *
Теперь вопрос ближе, ни кто не реализовывал Telnet server, без использования OS, на базе данного проекта.

я видел, но не на базе этого проекта. поищите на alterawiki.com по superloop-что-то-там-сервер. смысл такой: в NicheStack есть возможность работать без оси (тот самый superloop). соответственно, для проекта будет достаточно собрать его с 2-мя либами: NicheStack и LibTSE. подозреваю, что это будет жрать довольно много памяти, как раз от этого я уходил, поэтому в том моем проекте код такой куцый.
avacs
А реализовать сервер Telnet, как у вас реализован был запрос ЭХО и АРП без использования NicheStack не пробовали (или может кто другой пробовал или сталкивался с подобной проблемой)? А то в принципе минималистически получилось бы... можно было бы написать свой клиент к своему своеобразному серверу... но хотелось бы сделать что-то ближе к стандартным вещам (типа стандартных протоколов)...
Reanimator++
TSE - это слишком неоднозначно, какую версию его вы пробовали?
Я пока остановился на чтении документации ) там вроде как даже самый минимальный вариант больше 1500 LE требует.
Сколько ресурсов доступно?
Код
; Device                            ; EP2C8Q208C8                                  ;
; Total logic elements              ; 6,484 / 8,256 ( 79 % )                       ;
;     Total combinational functions ; 5,844 / 8,256 ( 71 % )                       ;
;     Dedicated logic registers     ; 4,199 / 8,256 ( 51 % )                       ;
; Total registers                   ; 4267                                         ;
; Total pins                        ; 127 / 138 ( 92 % )                           ;
; Total memory bits                 ; 50,944 / 165,888 ( 31 % )                    ;
; Embedded Multiplier 9-bit elements; 4 / 36 ( 11 % )                              ;
; Total PLLs                        ; 1 / 2 ( 50 % )                               ;

Ну впрочем заниматься уталкиванием до предела не хочется для первой пробы - я для этого проекта могу и обойтись интерфейсом попроще, просто хотелось уже на нем попробовать Ethernet.

отказался от внешнего MAC именно из-за цены
Ну кстати те же W5100 и DP83848 стоят одинаково (~200р), хотя в первом все хардварное, даже ТСР, а второй только PHY.
Выглядит нелогично. Хотя мне важнее софтовая поддержка и время разработки ибо устройства практически единичные.
Мысль насчет контроллеров понял, PHY из них выносят насколько понимаю из-за потребления.

Собственно как всегда на рынке есть десятки решений, и информация о них может быть представлена одинаково красиво, но одно из них мейнстрим, а другие тупик - потому и спрашиваю что лучше осваивать )

будет жрать довольно много памяти, как раз от этого я уходил, поэтому в том моем проекте код такой куцый
Для onchip_mem делали? А какая плис?

avacs
А реализовать сервер Telnet без использования NicheStack
Ну вам же все-равно TCP нужен, так что без стека (хотя бы зарезанного) не получится.
Я когда использовал микрочиповский стек без оси то все по большому счету сводилось к периодическому вызову StackTask(), причем время между вызовами практически любое (ну, естественно, ограничивается объемами ходящей информации).
Полагаю что здесь что-то похожее.
vadimuzzz
Цитата(Reanimator++ @ Jan 19 2011, 04:56) *
Ну впрочем заниматься уталкиванием до предела не хочется для первой пробы - я для этого проекта могу и обойтись интерфейсом попроще, просто хотелось уже на нем попробовать Ethernet.

есть еще вариант - свой MAC написать, огрызок. как-нибудь займусь.
Цитата
Ну кстати те же W5100 и DP83848 стоят одинаково (~200р), хотя в первом все хардварное, даже ТСР, а второй только PHY.

а w5100 может пакеты напрямую, минуя стек выдавать?
Цитата
Для onchip_mem делали? А какая плис?

да, тогда была только внутренняя память, 3c25. в новом варианте уже есть sdram
Reanimator++
свой MAC написать
Для меня пока проблемно счетчики с регистрами соединять в верилоге )

а w5100 может пакеты напрямую, минуя стек выдавать?
Да, может. MAC RAW mode.
vadimuzzz
Цитата(Reanimator++ @ Jan 19 2011, 13:21) *
Да, может. MAC RAW mode.

значит, нет проблем. можно взять за основу драйвер lan91c111 и модифицировать его под этот чип
inco
Люди помогите разобраться с передачей по Ethernet.

Есть кит 4 циклона DK-START-4CGX15N.
Беру проект который выкладывал тут ув. vadimuzzz, ОГРОМНОЕ ему за это спасибо!

Немного подправил его под проект кита "board_update_portal". Компилирую его запускаю... и естественно
ничего не работает.

Долго не мог въехать что именно не работает не было ни передачи ни приёма (светодиоды кита rx, tx мигали), при этом пример кита со стеком IP от iniche работал.

Начал по шагам сравнивать инициализацию PHY и MAC, нашел одно отличие у себя и у примера из кита. После добавления такой строки в инициализацию MAC - приём заработал.

IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE, 0, ALTERA_TSE_PCS_IF_MODE, 0x03); // PCS SGMII mode enabled

А вот с передачей полная засада!

Уже не пойму куда смотреть. Лампочка tx на PHY (88E1111) мигает. Дескриптор возвращает
actual_bytes_transferred 0xc8, то есть вроде всё передал. Смотрю а пакета НЕТ!

Немного о конфигурации ПК. Для отладки Etherneta, стоит отдельная сетевая карта (вторая), IP прописал ей статический.

Приём на ките смотрю по запросам карточки. Она чего-то просит по широковещательному адресу FFFFFFFFFFFF у кита.
А на приёме у карточки из кита ничего нет! Может я ей неправильные пакеты шлю, хотя как я понял Wireshark должен показывать любые пакеты. Может чего-то на карточке в ПК надо сконфигурировать? Уже не знаю куда смотреть!!!

Прошу помощи у народа!

Файлы проекта (soft) прилагаю.
vadimuzzz
Цитата(inco @ Jan 24 2011, 20:38) *
А вот с передачей полная засада!

сейчас под рукой нет примера, но это точно связано с конфигурацией марвеловского PHY.
Последовательность запуска такая:

  1. Запись по адресу 0 значения 0x8000 (SwRst==1)
  2. Задержка
  3. Запись по адресу 0 значения 0х1000 (AutoNeg==1)
  4. Задержка
  5. Чтение значения из адреса 1, проверка бита 2 (Link==1), если не установлен - 1)
  6. Запись по адресу 27 нижних бит [3:0] == 4'b1111 (GMII,copper)//смотреть доки на плату, это для девборды циклон-3!
  7. При RGMII IF - запись по адресу 20 прочитанного значения с установленными битами 7,1//смотреть доки на плату, это для девборды циклон-3!
  8. Повторять пункты 1-5, до установления линка. (SwRst)


в принципе, все это есть в альтеровском драйвере, поищите процедуру с названием чипа
inco
Спасибо за направление! Завтра буду смотреть дальше.

А вы посмотрите пожалуйста, может найдете свой пример инициализации этого PHY.
И какой у Вас кит для 3 циклона, чтобы попробовать сравнить их?
Кстати описание этого марвела у меня есть, его тут выкладывали.

Еще раз большое спасибо, особенно за Ваш пример!!!
vadimuzzz
CODE

alt_u32 t2;
IOWR_ALTERA_TSEMAC_MDIO_ADDR0(TSE_MAC_BASE,PHY);
t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x1B);//Extended PHY Specific Status Register
t2 &= 0xFFF0;
IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x1B,t2|0xB);//RGMII to Copper
t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x14);//Extended PHY Specific Control Register
IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,0x14,t2|0x82);//Add Delay to RX_CLK for RXD Outputs; Add Delay to GTX_CLK for TXD Inputs
t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_CONTROL);
IOWR_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_CONTROL,t2|PCS_CTL
_sw_reset);//Previous Operations Require SW Reset
do
{
t2 = IORD_ALTERA_TSEMAC_MDIO(TSE_MAC_BASE,0,ALTERA_TSEMAC_PHY_ADDR_STATUS);
}
while((t2&0x04)==0);//wait for link-up

этот код проверялся на http://www.altera.com/products/devkits/altera/kit-cyc3.html
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.