Vitaliy_ARM 0 6 октября, 2012 Опубликовано 6 октября, 2012 · Жалоба Всем доброго времени. Сегодня выявил следующий баг. DWORD EmacTxData(DWORD *Buf, DWORD Len) { pEMACDATA pEthData = &Data; DWORD idx; DWORD produce, consume; if(Len>0) { do { produce = LPC_EMAC->TxProduceIndex; consume = LPC_EMAC->TxConsumeIndex; } while(produce != consume); //////-------------- индексы равны даже, когда пакет еще отправляется!!!!!!!! // опеределяем номер текущего дескриптора idx = LPC_EMAC->TxProduceIndex; pEthData->DmaTx[idx].addr = Buf; pEthData->DmaTx[idx].ctrl = (Len-1) | 0xF4000000; //(1<<30) | (1<<31) | (1<<29) | (1<<28) | (1<<26); // прерывание включено (бит 31) if (++idx == ENET_DMA_TXDESC_NUMB) idx = 0; if(idx > LPC_EMAC->TxDescriptorNumber) return (FALSE); LPC_EMAC->TxProduceIndex = idx; } return(TRUE); } Когда запускаю эту функцию в цикле, например из 15 пакетов, то половина пакетов не отправляется, это хорошо видно при помощи WireShark. Стоит между отправкой поставить задержку в 100 мкс, то после этого все пакеты отправляются исправно. Т.е. похоже происходит "нахлест" между пакетами. Подскажите, в чем может быть дело? Ошибка процессора или PHY? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 6 октября, 2012 Опубликовано 6 октября, 2012 · Жалоба do { produce = LPC_EMAC->TxProduceIndex; consume = LPC_EMAC->TxConsumeIndex; } while(produce != consume); //////-------------- индексы равны даже, когда пакет еще отправляется!!!!!!!! Эээ, пардон, так вроде правильно сравнивать consume с (produce+1)%(TXDESCRIPTORNUMBER-1). Т.е. пока равны - ждать. Типа вот у меня: L_SENDETH: if (len<60) len=60; { UREG i,j; j=(i=TXPRODUCEINDEX)+1; if (j>TXDESCRIPTORNUMBER) j=0; while(j==TXCONSUMEINDEX); //Ждем освобождения передатчика - хотя бы один буфер FreeTXbufs(); EnetDmaTx[i].pBuffer=(EnetBuffer *)(ep->hdr.dst_mac); EnetDmaTx[i].EnetTxCtrl.Size = len-1; TXPRODUCEINDEX=j; //Стартуем посылку Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 6 октября, 2012 Опубликовано 6 октября, 2012 · Жалоба Эээ, пардон, так вроде правильно сравнивать consume с (produce+1)%(TXDESCRIPTORNUMBER-1). Т.е. пока равны - ждать. Типа вот у меня: L_SENDETH: if (len<60) len=60; { UREG i,j; j=(i=TXPRODUCEINDEX)+1; if (j>TXDESCRIPTORNUMBER) j=0; while(j==TXCONSUMEINDEX); //Ждем освобождения передатчика - хотя бы один буфер FreeTXbufs(); EnetDmaTx[i].pBuffer=(EnetBuffer *)(ep->hdr.dst_mac); EnetDmaTx[i].EnetTxCtrl.Size = len-1; TXPRODUCEINDEX=j; //Стартуем посылку К сожалению не совсем так, PRODUCE убегающий индекс, а CONSUME - догоняющий. Инкрементом PRODUCE мы запускаем DMA, который начинает отправлять пакет. По завершению отправки этого пакета DMA инкрементирует CONSUME индекс. Т.е. DMA будет передавать пакеты до тех пор, пока индексы не равны. If the TxConsumeIndex equals TxProduceIndex the descriptor array is empty and the transmit channel will stop transmitting until software produces new descriptors. В Вашем случае дается разрешение заполнить TXDESCRIPTORNUMBER дескрипторов, пока DMA отправляет один пакет. В моем случае я следующий покет не отправлю, пока не отправился предыдущий. Проблема осталась. Начинаю думать, что это PHY не отдает команды процессору об успешной отправке, в то время, как он отправить данные не успел. Разбираюсь дальше... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 6 октября, 2012 Опубликовано 6 октября, 2012 · Жалоба Начинаю думать, что это PHY не отдает команды процессору об успешной отправке, в то время, как он отправить данные не успел. Разбираюсь дальше... А причем тут PHY? Он, вообще-то, ничего никому не сообщает. И решение о конце отправки принимает MAC, о чем сигнализирует в PHY снятием сигнала TXEN. А вообще я бы на Вашем месте проверил правильность настроек RX/TX flow controll и Half/Full Duplex. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 17 октября, 2012 Опубликовано 17 октября, 2012 · Жалоба А причем тут PHY? Он, вообще-то, ничего никому не сообщает. И решение о конце отправки принимает MAC, о чем сигнализирует в PHY снятием сигнала TXEN. А вообще я бы на Вашем месте проверил правильность настроек RX/TX flow controll и Half/Full Duplex. Спасибо за наводку. В общем ошибка была в том, что неправильно инициализировался процессор. В режиме 100 Мбит FULL Duplex процессор у меня инициализировался в HALF Duplex. После исправления кода все заработало как надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться