LWIP 1.4.1, FreeRTOS, kdepak, nejde...
Jaroslav Buchta
jaroslav.buchta na hascomp.cz
Sobota Říjen 19 21:58:17 CEST 2013
Ha uz to asi mam, ono se nejak rozhodi poradi a odpovedi na pakety n to
odesila az pri prijmu paketu n+x, takze to vypada treba takhle
No. Time Source Destination Protocol Length
Info
11 14.408727000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9691/56101, ttl=128 (reply in 21)
15 19.390221000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9692/56357, ttl=128 (reply in 24)
16 21.434476000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9693/56613, ttl=128 (reply in 27)
17 24.901624000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9694/56869, ttl=128 (reply in 29)
20 27.210004000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9695/57125, ttl=128 (reply in 31)
21 27.211617000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9691/56101, ttl=255 (request
in 11)
23 30.030601000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9696/57381, ttl=128 (reply in 33)
24 30.032255000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9692/56357, ttl=255 (request
in 15)
26 33.399941000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9697/57637, ttl=128 (reply in 35)
27 33.401526000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9693/56613, ttl=255 (request
in 16)
28 37.627961000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9698/57893, ttl=128 (reply in 37)
29 37.629555000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9694/56869, ttl=255 (request
in 17)
31 38.191036000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9695/57125, ttl=255 (request
in 20)
33 39.191060000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9696/57381, ttl=255 (request
in 23)
34 40.171452000 192.168.0.29 192.168.0.9 ICMP
74 Echo (ping) request id=0x0001, seq=9699/58149, ttl=128 (reply in 49)
35 40.173069000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9697/57637, ttl=255 (request
in 26)
37 40.191099000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9698/57893, ttl=255 (request
in 28)
49 60.374202000 192.168.0.9 192.168.0.29 ICMP
74 Echo (ping) reply id=0x0001, seq=9699/58149, ttl=255 (request
in 34)
Problem je zda se v tom, ze funkce ISR inkrementuje semafor a extra task
na nej ceka a zpracuje presne stejny pocet paketu, takze pokud dojde k
promeskani jednoho preruseni, tak se zacne zpracovani paketu zpozdovat
(mam aktualne 5 prijimacich bufferu)
Tomu se da tezko zabranit u slozitejsiho systemu, cili reseni vidim v
tom, ze pri obsluze ISR zpracuju vsechny pakety ktere jsou k dispozici
(semafor by se asi nahradil mutexem)
Vyzkousel jsem modifikaci a pokud se nekdo vyzna v praci Eth. MAC a DMA
u STM32F4xxx tak se prosim podivejte, jestli je to takto korektne a co
pripadne upravit, nerad bych se ted snazil ten ukrutny system registru,
deskriptoru a bufferu pochopit... Takhle to zda se funguje OK:
ISR na prijem je beze zmeny:
if ( ETH_GetDMAFlagStatus(ETH_DMA_FLAG_R) == SET)
{
/* Give the semaphore to wakeup LwIP task */
xSemaphoreGiveFromISR( s_xSemaphore, &xHigherPriorityTaskWoken );
ETH_DMAClearITPendingBit(ETH_DMA_IT_R);
}
Zmena je v tasku pro cekani na semafor a zpracovani paketu,
zakomentovana cast na konci je puvodni text
for( ;; )
{
if (xSemaphoreTake( s_xSemaphore,
emacBLOCK_TIME_WAITING_FOR_INPUT)==pdTRUE)
{
while (ETH_CheckFrameReceived())
{
p = low_level_input( s_pxNetIf );
if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))
{
pbuf_free(p);
p=NULL;
}
TXDBGMSG("PKT R FINISH");
}
// p = low_level_input( s_pxNetIf );
// if (ERR_OK != s_pxNetIf->input( p, s_pxNetIf))
// {
// pbuf_free(p);
// p=NULL;
// }
}
}
A ve fci low_level_input jsem upravil jen radek s
frame = ETH_Get_Received_Frame(); //puvodne
ETH_Get_Received_Frame_interrupt
No a ted je otazka, jestli zbytek funkce nedela neco spatne, kdyz se
zmenila funkce pro cteni frame... Prikladam komplet:
static struct pbuf * low_level_input(struct netif *netif)
{
struct pbuf *p, *q;
u16_t len;
uint32_t l=0,i =0;
FrameTypeDef frame;
u8 *buffer;
__IO ETH_DMADESCTypeDef *DMARxNextDesc;
p = NULL;
// STM32F4_Discovery_LEDToggle(LEDO);
/* Get received frame */
frame = ETH_Get_Received_Frame();//terrupt();
/* check that frame has no error */
if ((frame.descriptor->Status & ETH_DMARxDesc_ES) == (uint32_t)RESET)
{
/* Obtain the size of the packet and put it into the "len" variable. */
len = frame.length;
buffer = (u8 *)frame.buffer;
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
/* Copy received frame from ethernet driver buffer to stack buffer */
if (p != NULL)
{
for (q = p; q != NULL; q = q->next)
{
memcpy((u8_t*)q->payload, (u8_t*)&buffer[l], q->len);
l = l + q->len;
}
}
}
/* Release descriptors to DMA */
/* Check if received frame with multiple DMA buffer segments */
if (DMA_RX_FRAME_infos->Seg_Count > 1)
{
DMARxNextDesc = DMA_RX_FRAME_infos->FS_Rx_Desc;
}
else
{
DMARxNextDesc = frame.descriptor;
}
/* Set Own bit in Rx descriptors: gives the buffers back to DMA */
for (i=0; i<DMA_RX_FRAME_infos->Seg_Count; i++)
{
DMARxNextDesc->Status = ETH_DMARxDesc_OWN;
DMARxNextDesc = (ETH_DMADESCTypeDef
*)(DMARxNextDesc->Buffer2NextDescAddr);
}
/* Clear Segment_Count */
DMA_RX_FRAME_infos->Seg_Count =0;
/* When Rx Buffer unavailable flag is set: clear it and resume
reception */
if ((ETH->DMASR & ETH_DMASR_RBUS) != (u32)RESET)
{
/* Clear RBUS ETHERNET DMA flag */
ETH->DMASR = ETH_DMASR_RBUS;
/* Resume DMA reception */
ETH->DMARPDR = 0;
}
return p;
}
----------------------------------------------------------------------------------------------------------------------------------------------
Další informace o konferenci Hw-list