Hi Jens, hi Sergio,
Yes that's exactly my problem. Here's the patch I've came up with on my
driver :
int packetCount = 0;
static void eth_notify (ARM_ETH_MAC_EVENT event) {
/* Send notification on RX event */
if (event == ARM_ETH_MAC_EVENT_RX_FRAME) {
packetCount++;
}
}
void ethernetif_poll (struct netif *netif) {
struct ethernetif *eth = netif->state;
if (!eth->phy_ok || eth->link == ARM_ETH_LINK_DOWN) {
return;
}
while (packetCount)
{
ethernetif_input (netif);
atomicDecrement(packetCount);
}
}
It works perfectly !
Thanks a lot for your help !
Julien.
2014-03-20 19:46 GMT+01:00 Jens Nielsen <[email protected]>:
> Alright, I also use the ST drivers (the ones from STM32Cube 1.0.0) on an
> STM32F4
>
> I haven't verified that my fix is 100% accurate but I think it looks safe
> so I'm sending it to ST anyway so they can figure it out if they want to.
>
> My fix goes something like this:
>
>
> At the bottom of HAL_ETH_GetReceivedFrame_IT() I return an error code if I
> don't find a complete packet:
>
> ---
> a/clients/embedded/source/STM32F4XX/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c
> +++
> b/clients/embedded/source/STM32F4XX/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_eth.c
> @@ -868,7 +868,7 @@ HAL_StatusTypeDef
> HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth)
> __HAL_UNLOCK(heth);
>
> /* Return function status */
> - return HAL_OK;
> + return HAL_ERROR;
> }
>
> /**
>
>
>
> And then return NULL from low_level_input() in my ethernetif:
>
> ---
> a/clients/embedded/source/lwip-1.4.1/port/STM32F4x7/FreeRTOS/ethernetif.c
> +++
> b/clients/embedded/source/lwip-1.4.1/port/STM32F4x7/FreeRTOS/ethernetif.c
> @@ -225,7 +224,10 @@ static struct pbuf * low_level_input(struct netif
> *netif)
> uint32_t i=0;
>
> /* get received frame */
> - HAL_ETH_GetReceivedFrame_IT(&EthHandle);
> + if ( HAL_ETH_GetReceivedFrame_IT(&EthHandle) != HAL_OK )
> + {
> + return NULL;
> + }
>
> /* Obtain the size of the packet and put it into the "len" variable. */
> len = EthHandle.RxFrameInfos.length;
>
>
>
> And in my receive task I have this loop (ok yeah this could be prettier...)
>
> + do
> + {
> + p = low_level_input(netif);
> + if (p != NULL)
> + {
> + if (netif->input(p, netif) != ERR_OK)
> + {
> + pbuf_free(p);
> + }
> + }
> + } while (p != NULL);
>
>
> Hope it helps!
>
> BR /Jens
>
>
>
> On 2014-03-20 19:13, Sergio R. Caprile wrote:
>
> Yes Jens, looks like you are absolutely right, missed that, there is no
> frame loss here, the receiving process must be getting only the first
> frame in the "chip" cue.
>
> Julien is using some ST microcontroller, I guess it has a built-in eth
> controller, probably with DMA.
>
> I've studied the Linux drivers for the DM9000 to write my driver, and
> I've seen they read all the packets out of the chip every time; then I
> setup a simple test to see if interrupts would trigger on every frame or
> only on empty buffer, and guess what... empty buffer only (there is no
> int ack here)
>
> Looks like we've got a different situation here, the chip seems to be
> issuing an interrupt after the first one is ACKed, as you Jens described
> for your case.
>
> Julien, can you confirm this from the chip docs ?
> Pitty one has to fix the drivers for a manufacturer, maybe someone in ST
> can lend a hand ?
>
>
>
>
> _______________________________________________
> lwip-users mailing list
> [email protected]
> https://lists.nongnu.org/mailman/listinfo/lwip-users
>
_______________________________________________
lwip-users mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/lwip-users