Посмотрите:
https://forums.xilinx.com/t5/Embedded-Devel...ues/td-p/696975На моей памяти (подробности не вспомню) были проблемы с автосогласованием скорости на некоторых МАС. Решалось установкой фиксированной скорости.
Вот мой код инициализиции модуля Eth0:
Код
int EthTransceiver_Init(XScuGic* INTRCtrl)
{
//============Конфигурируем системный таймер для обновления флагов TCP (требуется lwIP)=========
u32 Status = XST_SUCCESS;
XScuTimer_Config* ConfigPtr;
u32 TimerLoadValue = 0;
LogFileCtrl_PrintF("=======Init Ethernet controller module.=======\n");
ConfigPtr = XScuTimer_LookupConfig(XPAR_SCUTIMER_DEVICE_ID);
Status = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr, ConfigPtr->BaseAddr);
if (Status != XST_SUCCESS) {
LogFileCtrl_PrintF("FAILED init Scutimer, status: %u32 .\n", Status);
return XST_FAILURE;
}
Status = XScuTimer_SelfTest(&TimerInstance);
if (Status != XST_SUCCESS) {
LogFileCtrl_PrintF("FAILED Scutimer selftest, status: %u32 .\n", Status);
return XST_FAILURE;
}
XScuTimer_EnableAutoReload(&TimerInstance);
/*
* Set for 250 milli seconds timeout.
*/
TimerLoadValue = XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ / 8;
XScuTimer_LoadTimer(&TimerInstance, TimerLoadValue);
//================================================================================
==============
//============Конфигурируем прерывания от таймера===============================================
XScuGic_Connect(INTRCtrl, XPAR_SCUTIMER_INTR, (Xil_InterruptHandler)EthTimer_Handler, (void *)&TimerInstance);
XScuGic_Enable(INTRCtrl, XPAR_SCUTIMER_INTR);
//================================================================================
==============
//===========Инициализируем IP - адреса библиотеку Ethernet=====================================
LogFileCtrl_PrintF("Init lwIP.\n");
struct ip_addr MyIP, MyNetMask, MyGW;
IP4_ADDR(&MyIP, Network_Config.IP[0],
Network_Config.IP[1],
Network_Config.IP[2],
Network_Config.IP[3]);
IP4_ADDR(&MyNetMask, Network_Config.Mask[0],
Network_Config.Mask[1],
Network_Config.Mask[2],
Network_Config.Mask[3]);
IP4_ADDR(&MyGW, Network_Config.Gateway[0],
Network_Config.Gateway[1],
Network_Config.Gateway[2],
Network_Config.Gateway[3]);
lwip_init();
if (!xemac_add(&NetItfs, &MyIP, &MyNetMask, &MyGW, (void*)Network_Config.MAC, XPAR_XEMACPS_0_BASEADDR))
{
LogFileCtrl_PrintF("FAILED adding network interface.\n");
return XST_FAILURE;
}
netif_set_default(&NetItfs);
//================================================================================
==============
//===========Включаем контроллер Ethernet=======================================================
netif_set_up(&NetItfs);
//================================================================================
==============
//===========Разрешаем прерывания===============================================================
XScuTimer_EnableInterrupt(&TimerInstance);
XScuTimer_Start(&TimerInstance);
//================================================================================
==============
LogFileCtrl_PrintF("Init lwIP result: OK.\n");
LogFileCtrl_PrintF("=======Init Ethernet controller module result: OK.=======\n\n");
return 0;
}
Вот код создания UDP PCB:
Код
//Создаем порты передачи данных
struct ip_addr IpAddrPC;
IP4_ADDR(&IpAddrPC, Network_Config.Host_IP[0],
Network_Config.Host_IP[1],
Network_Config.Host_IP[2],
Network_Config.Host_IP[3]);
pcbRcv = udp_new();
pcbVideoSnd = udp_new();
pcbDataSnd = udp_new();
udp_bind(pcbRcv, IP_ADDR_ANY, Network_Config.ServiceCtrlPort);
udp_bind(pcbVideoSnd, IP_ADDR_ANY, Network_Config.Host_Video_Port);
udp_bind(pcbDataSnd, IP_ADDR_ANY, Network_Config.Host_Data_Port);
udp_recv(pcbRcv, UDPRcv, NULL);
udp_recv(pcbDataSnd, DataRcvHandler, NULL);
udp_connect(pcbVideoSnd, &IpAddrPC, Network_Config.Host_Video_Port);
udp_connect(pcbDataSnd, &IpAddrPC, Network_Config.Host_Data_Port);
Вот код отправки данных:
Код
while(1)
{
EthTransceiver_ProcInput();
//================================================================================
==================
//====================Проверяем флаг готовности кадрового буффера===================================
if ((FrameReady != 0) & (Streams_Config.Video_En != 0))
{
for (LineIdx = 0; LineIdx < LinesInFrame; LineIdx = LineIdx + 1)
{
memcpy(VideoBuff_Tx->payload, Frame[LineIdx], Streams_Config.Video_PacketSize);
udp_send(pcbVideoSnd, VideoBuff_Tx);
}
//Данные из буффера 1 отправлены, снимаем флаг готовности
FrameReady = 0;
//Запускаем первый трансфер
SensorDriver_ReceiveFrame();
}
}
Вот только пакеты (мой заголовок+данные) у меня формируются в логике и по ДМА отправляются в ДДР. Т.е. в ДДР лежит не картинка, а набор пакетов - так удается существенно увеличить траффик от Цинка и разгрузить его!