Need some help to clarify porting network driver for cortex m4 mcu

Hi! As I understand it, I need to fill in all the functions in NetworkInterface.c file. But in porting guide i see a requirement " The network interface port layer must provide a function called px${port_name}_FillInterfaceDescriptor()". What exactly i need to provide:
NetworkInterfaceInitialise(), NetworkInterfaceOutput( ) and vNetworkInterfaceAllocateRAMToBuffers ( this function is not needed because I use scheme 2?). And what about PHY initialisation? I use Dm9162 chip. Do I need to initialize it or library have function to initialize this phy? I can’t figure out where to start porting

@pistoletov1974

What exactly i need to provide:
NetworkInterfaceInitialise(), NetworkInterfaceOutput( ) and vNetworkInterfaceAllocateRAMToBuffers ( this function is not needed because I use scheme 2?).

px${port_name}_FillInterfaceDescriptor() is just another function that has to be defined in the network interface. It initialises the NetworkInterface_t with the other network interface callback functions NetworkInterfaceInitialise(), NetworkInterfaceOutput( ), etc., along with interface name and then adds the network interface to the list of network interfaces via FreeRTOS_AddNetworkInterface. You can refer to the existing network interfaces to see how they are configured. [example]

And what about PHY initialisation? I use Dm9162 chip. Do I need to initialize it or library have function to initialize this phy?

PHY initialization should be done by the network interface as part of the interface initialization; the library doesn’t take care of it.

The source/portable/NetworkInterface/Common provides PHY handling APIs that can be used in your network interface [example], but it doesn’t support/tested with Dm9162 chip. However, you can refer to the implementation of existing/tested chips in that file and add support for Dm9162.

Thank you, @tony-josi-aws. Please clear a moment about endpoints. This is a logical interaces (with own mac address) on the physical emac hardware?

@pistoletov1974

about endpoints. This is a logical interaces (with own mac address) on the physical emac hardware?

Yes, endpoints are logical interfaces that are tied to a physical interface. A physical network interface can have multiple endpoints. Each of them can be either IPv4 or IPv6.

refer

I ran into a problem with phy_reset function (from phy_handling.c). This function call function vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) ). On the call this function system halted in function void prvCheckTasksWaitingTermination( void ). NOTE: phy_reset function executed before the scheduler starts. I try to increase configMINIMAL_STACK_SIZE but this has no effect.

prvCheckTasksWaitingTermination is periodically called by the idle task. Idle task runs if there is nothing else to do means other tasks are blocked/waiting for something.
So the system is not halted, it’s idle.
I think invoking phy_reset using FreeRTOS API calls before scheduler was started doesn’t make much sense. The PHY is usually managed by FreeRTOS network stack resp. task via its network interface layer.

I suppouse use run+breakpoints avoid this situation? The problem appeared during the step-by-step execution. " prvCheckTasksWaitingTermination is periodically called" Who’s calling her?
Systick is inactive until the scheduler is started.

As mentioned prvCheckTasksWaitingTermination is called by the ‘Idle’ task which is part of the FreeRTOS runtime environment. You know, there should be at least 1 task when the scheduler is started and it also does some bookkeeping like cleaning up deleted tasks (hence prvCheckTasksWaitingTermination).
I think this part is not your problem, right ? So what’s the problem you want to solve ?

I porting Freertos TCP stack to cortex m4 mcu. Now i implement NetworkInterfaceInitialise function and in the process of step-by-step debugging, I encountered with this problem. The problem is in link. This code executed before creating tasks, this is part of vMACBProbePhy() init function. Yes this is not problem with my own code, I just added register reading and writing functions PHY registers.

I wonder who is calling vMACBProbePhy before the scheduler including the network stack related tasks are started. That should be part of resp. managed by the network stack via ‘network interface up/down’ transitions. Unfortunately I don’t have my networking code at hand to have a look.

i use example from Freertos for stm32 by recommendation @tony-josi-aws with small changes . vMACBProbePhy call from this example before any task created and scheduler start.

  /* Initialize the MACB and set all PHY properties */
            prvMACBProbePhy();

            /* Force a negotiation with the Switch or Router and wait for LS. */
            prvEthernetUpdateConfig( pdTRUE );

            /* The deferred interrupt handler task is created at the highest
             *  possible priority to ensure the interrupt handler can return directly
             *  to it.  The task's handle is stored in xEMACTaskHandle so interrupts can
             *  notify the task when there is something to process. */
            if( xTaskCreate( prvEMACHandlerTask, niEMAC_HANDLER_TASK_NAME, niEMAC_HANDLER_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &( xEMACTaskHandle ) ) == pdPASS )
            {

But this is a snippet from xNetworkInterfaceInitialise, right ? And isn’t this function called by the network stack init FreeRTOS_IPInit(_Multi) ?
What about starting the stack with FreeRTOS (scheduler) running ? Because very likely network stack including its initialization uses FreeRTOS API internally (like vTaskDelay and many others).
Edit: I don’t get why the Idle task is running as you mentioned before but you say that the scheduler wasn’t started yet. That can’t be right :thinking:

Exactly!!! The vMACBProbePhy function called in FreeRTOS_IPInit(_Multi). I really mistake about scheduler. Thank you very much!!

The problem was in my phy reset function-)))). I reset phy using RST pin:

  gpio_bits_reset(GPIOE, GPIO_PINS_15);
  delay_ms(2);
  gpio_bits_set(GPIOE, GPIO_PINS_15);
  delay_ms(2);

but delay_ms(2) realization function disable systick.

I replace this with:

  gpio_bits_reset(GPIOE, GPIO_PINS_15);
  vTaskDelay(2);
  gpio_bits_set(GPIOE, GPIO_PINS_15);
  vTaskDelay(2);

And everything became good. Thank you very much again

Great :+1: And thanks for reporting back !