FreeRTOS+TCP: vApplicationIPNetworkEventHook_Multi keeps being called with eNetworkDown event

Hi.
It’s my first time using FreeRTOS+TCP.
I’m using STM32F207 chip. The FreeRTOS code works OK.
I went through all points in “Adding FreeRTOS-Plus-TCP To a FreeRTOS Project” and “Initialising the TCP/IP Stack and Start Up” topics.
I initialize the TCP endpoint the following way:

static const uint8_t ucIPAddress[ 4 ] = { 10, 10, 10, 200 };
    static const uint8_t ucNetMask[ 4 ] = { 255, 0, 0, 0 };
    static const uint8_t ucGatewayAddress[ 4 ] = { 10, 10, 10, 1 };
    static uint8_t ucMACAddress[ 6 ] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
    static const uint8_t ucDNSServerAddress[ 4 ] = { 208, 67, 222, 222 };
    
    pxSTM32Fxx_FillInterfaceDescriptor( 0, &( xInterfaces[ 0 ] ) );
    FreeRTOS_FillEndPoint( &( xInterfaces[ 0 ] ), &( xEndPoints[ 0 ] ), ucIPAddress,
                                ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
    
    FreeRTOS_IPInit_Multi();

after this (after starting the scheduler) the vApplicationIPNetworkEventHook_Multi() hook function is being called periodically with eNetworkDown event (I see it in the debugger).

What am I doing wrong?
Thanks.

Are you using a supported PHY, and have you assured that the PHY config matches your board? Is your board custom made or commercial?

My board is a custom one. It already works with Keil RTX RTOS and Keil’s TCP library. I’m working to migrate it to FreeRTOS.
What do you mean by PHY config? Where do I find it?

you need to adapt the PHY address and protocol (RMII vs. MII) according to your strapping in the PHY driver.

@michaelv

Which ethernet driver are you using? Is it the one that is found in this path of your +TCP library path: source\portable\NetworkInterface\STM32Fxx\stm32fxx_hal_eth.c?

Also, as @RAc suggested, verify which interface is used to connect your MAC with PHY. Define the macro ipconfigUSE_RMII accordingly in your FreeRTOSIPConfig.h

Make sure that the HAL_ETH_MspInit (and HAL_ETH_MspDeInit) definition is initialising the GPIO pins and interrupts as per the layout of your custom board.

Another debugging suggestion is to step through the code and find where the initialisation is failing inside the pxInterface->pfInitialise( pxInterface )? [xSTM32F_NetworkInterfaceInitialise]

2 Likes
  • I’m using the stm32fxx_hal_eth.c from the path that you’ve written.
  • My PHY is connected with MII interface ( ipconfigUSE_RMII = 0 ).
  • HAL_ETH_MspInit is created using CubeMX, so every initialization is done correctly.
  • I went through the code with debugger and saw that xSTM32F_NetworkInterfaceInitialise fails at
if( xPhyObject.ulLinkStatusMask != 0U )
        {
            xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;
            xResult = pdPASS;
            FreeRTOS_printf( ( "Link Status is high\n" ) );
        }
        else
        {
            /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
             * and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
            xResult = pdFAIL;
        }

(xPhyObject.ulLinkStatusMask is 0).

Since you are using a custom board, is the configuration thats opted in the CubeMX as per your custom board layout? You can check those with the PINs used in the project that were tested to work.

Can you check if the PHY chip you use in your custom board supported in the source/portable/NetworkInterface/Common/phyHandling.c?

The configuration in CubeMX is as the pinout of my custom board (I’ve checked it again).
As I’ve mentioned, the board already works with Keil RTX and TCP library, so the pinout must be correct.
In phyHandling.h I’ve found
#define PHY_ID_MV88E6071 0xFF000710
So I guess my PHY is supported.

Can you check if the PHY discovery and configuration are successful? Probably you can step through the code here: FreeRTOS-Plus-TCP/source/portable/NetworkInterface/STM32Fxx/NetworkInterface.c at main · FreeRTOS/FreeRTOS-Plus-TCP · GitHub

@tony-josi-aws
xPhyDiscover() returns 4
xPhyConfigure() returns 0

(Don’t know if it helps) I defined ipconfigPHY_MAX_PORTS to 10 (instead of default 4) and now xPhyDiscover() returns 7.
(MV88E6071 is a switch which is connected to the MCU with MII interface)

xPhyDiscover() returns 4

So communication with PHY is okay.

Does the PHY auto negotiation succeed? [refer]

when it gets to the following line (in xPhyStartAutoNegotiation() )

if( ulDoneMask != ( uint32_t ) 0U )

ulDoneMask = 0. So I guess auto negotiation fails (?)

My next step would be to read out all PHY registers on the working platform once the stack is up and then compare the registers to those under FreeRTOS. That should give you a quick hint as to where the problem might be. You could even do that in an application task.

@RAc
Thanks for your reply.
Sounds like I need to start debugging the PHY access code of FreeRTOS+TCP.
Even if I’ll have the differences in registers between the working platform and FreeRTOS, I wouldn’t know what makes those differences.
It looks like a big task for something that should work “out of the box” (because the PHY is already supported by the current version of FreeRTOS+TCP).

That should relatively straightforward to determine with the PHY documentation. You can also publish your findings here, I am sure that there are several people on this forum who can help you interpret the data.

Re Out of the box: Well, in theory, I agree, but the old adage “In theory, there is no difference between theory and practice, but in practice, there is” proves correct time and again. The community will try its best to iron out your problems.

Did you check that the strapped PHY address matches the configured address (not only the (R)MII protocol)?

If by “strapped PHY address” you mean an address which is hardware defined (with chip’s pins) - there are no pins for address in the chip.
If I understand correctly, xPhyDiscover() finds 7 ports - all of type PHY_ID_MV88E6071 (which is the correct type) - from address 0x18 and on

unfortunately, I can not locate any information about the chip, not even on Marvell’s HP. If the chip does support auto discovery, then you are correct and there is no need for software configuration. Most PHYs I have seen, however, appear to require some kind of strapped address configuration on an MII bus.

Don’t know what to say… I know nothing about PHYs…

@michaelv

Have you tried disabling the PHY auto-negotiation? [ipconfigETHERNET_AN_ENABLE]

Even if I’ll have the differences in registers between the working platform and FreeRTOS, I wouldn’t know what makes those differences.

Essentially, xPhyDiscover and xPhyConfigure should configure those registers. If you get the register values of your working project and compare them with the current project’s register values once the configuration is done, you can check what register fields differ in both cases and refer to your PHY datasheet to see what’s incorrectly configured. That will give you a better idea of what change to look for. Unfortunately, I cannot find a datasheet for MV88E6071