cancel
Showing results for 
Search instead for 
Did you mean: 

NOT SEND ARP Gratuitous. STM32CubeMX semantic error in NET driver ethernetif.c

drachev
Associate II
Posted on October 28, 2015 at 14:24

STM32CubeF4 Firmware Package V1.8.0 / 14-August-2015

using board STM3240G-eval.(stm32f407IGH)

1) enable  LWIP_ARP in project, 

2) setttings call: ''ethernetif_update_config()'' and ''ethernetif_set_link()''.

Problem

: not work protocol ARP Gratuitous

Description

When the device to be connected(connection is via cable) to the network must send ARP packet for detecting duplicate IP. lwip stack does not send ARP packet.

Additional Information

 

First error in function ethernetif_update_config() :

 

1) When the link is activated, lwip stack trying to send ARP packet from netif_set_link_up ().

2) From netif_set_link_up () after the call etharp_gratuitous (), the function is called ethernetif_update_config ().

3) In function ethernetif_update_config () is tuned physics. HAL_ETH_ConfigMAC () and HAL_ETH_Start ()

Mistake is that first there is an attempt to send an ARP packet and then going on reconfiguring the physical layer. ARP packet does not have time to go becauseIt is tuned physical layer

.

void netif_set_link_up(struct netif *netif )

{

  if (!(netif->flags & NETIF_FLAG_LINK_UP)) {

    netif->flags |= NETIF_FLAG_LINK_UP;

#if LWIP_DHCP

    if (netif->dhcp) {

      dhcp_network_changed(netif);

    }

#endif /* LWIP_DHCP */

#if LWIP_AUTOIP

    if (netif->autoip) {

      autoip_network_changed(netif);

    }

#endif /* LWIP_AUTOIP */

    if (netif->flags & NETIF_FLAG_UP) {

#if LWIP_ARP

      /* For Ethernet network interfaces, we would like to send a ''gratuitous ARP'' */ 

      if (netif->flags & NETIF_FLAG_ETHARP) {

        etharp_gratuitous(netif);        

//TODO here it goes ARP packet

      }

#endif /* LWIP_ARP */

#if LWIP_IGMP

      /* resend IGMP memberships */

      if (netif->flags & NETIF_FLAG_IGMP) {

        igmp_report_groups( netif);

      }

#endif /* LWIP_IGMP */

    }

    NETIF_LINK_CALLBACK(netif); 

// TODO here called ethernetif_update_config () and resets physics.

  }

}

Second error in ethernetif_set_link() :

When linkup occurs, the semaphore is released. lwip stack trying to send ARP packet from netif_set_link_up (), but the physics is not yet time to tune and ARP packet is not sent to the set.

an example of a positive result:

 

void ethernetif_set_link(void const *argument)

{

  uint32_t regvalue = 0;

  struct link_str *link_arg = (struct link_str *)argument;  

  for(;;)

  {

    if (osSemaphoreWait( link_arg->semaphore, 100)== osOK)

    {

    

  

HAL_Delay(300);//TODO 

delay helps, but you need to think. 

      /* Read PHY_MISR*/

      HAL_ETH_ReadPHYRegister(&heth, PHY_MISR, &regvalue);

      /* Check whether the link interrupt has occurred or not */

      if((regvalue & PHY_LINK_INTERRUPT) != (uint16_t)RESET)

      {

        /* Read PHY_SR*/

        HAL_ETH_ReadPHYRegister(&heth, PHY_SR, &regvalue);

        

        /* Check whether the link is up or down*/

        if((regvalue & PHY_LINK_STATUS)!= (uint16_t)RESET)

        {          

          netif_set_link_up(link_arg->netif);  

//TODO here can not send ARP packet

        }

        else

        {

          netif_set_link_down(link_arg->netif);

        }

      }

    }

  }

}

7 REPLIES 7
Oussema Hajjem_O
Associate III
Posted on October 29, 2015 at 15:33

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6W3&d=%2Fa%2F0X0000000bpi%2F2h8h69ZSDI.8TzzxkSNLQCSRWAcH7vkSJbZps7scXo8&asPdf=false
drachev
Associate II
Posted on October 30, 2015 at 06:18

There is 2 use case:

First:

The device

is connected

to the network.

You turn on the device.

The device must send an ARP packet.

Second:

The device

is not connected

to the network.

You turn on the device.

Wait a full initialization.

Then connect the cable.

The device must send an ARP packet.

These use case can be viewed using wireshark

First use case is work, and the second not work. If you turn off and then turn on the cable, the ARP packets are sent. This is a problem I encountered.

NOT SEND ARP

packets in

first

connection cable.

You have this problem in your source code?

Oussema Hajjem_O
Associate III
Posted on October 30, 2015 at 11:27

Hi Andrei,

The second case has to be managed by the user callback 

ethernetif_notify_conn_changed(

)

,

that's why I recommended you to implement it (please refer to the last post)

The MX generated code supports only the initialisation sequence. what happens after (exp cable connection/disconnection) had to be managed by the user.

drachev
Associate II
Posted on November 03, 2015 at 05:45

Ok.

Im download new vercion CubeMx 4.00

and new library Firmaware Package for Family STM32F4 1.9.0.

During setup of the project, identified the

bug

CubeMX.

In output file: ../Inc/stm32f4xx_hal_conf.h

line

Generete

#define PHY_MICR_INT_OE ((uint16_t)

0x0002

) /*!< PHY Enable output interrupt events */

must be

#define PHY_MICR_INT_OE ((uint16_t)

0x0001

) /*!< PHY Enable output interrupt events */

Last version generete is correct.

Im fix this problem.

Enable interrupt link up, and add

void ethernetif_notify_conn_changed(struct netif *netif)

{

if (netif_is_link_up(netif))

{

/* When the netif is fully configured this function must be called.*/

netif_set_up(netif);

}

else

{

/* When the netif link is down this function must be called */

netif_set_down(netif);

}

}

This is

dont

work.

function ethernetif_notify_conn_changed()is

called.

then called

netif_set_up()?but the ARP packet is not sent.

Im go to inside function and find next:

the reason for not sending:

when call functionHAL_ETH_TransmitFrame()

work next ''if'' in code:

/* When Tx Buffer unavailable flag is set: clear it and resume transmission */

if (((heth->Instance)->DMASR & ETH_DMASR_TBUS) != (uint32_t)RESET)

{

/* Clear TBUS ETHERNET DMA flag */

(heth->Instance)->DMASR = ETH_DMASR_TBUS;

/* Resume DMA transmission*/

(heth->Instance)->DMATPDR = 0;

}

because this is not an ARP, goingClear TBUS ETHERNET DMA flag ,Resume DMA transmission.

Im add file from CubeMX

________________

Attachments :

CubeMX-STM3240G-EVAL.ioc : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006Htpt&d=%2Fa%2F0X0000000aXX%2FNd4RwOwByz_RkdXFgrwFSlY0P.rV7zs8FC4yCfhO75w&asPdf=false
drachev
Associate II
Posted on November 03, 2015 at 09:58

I find error. 

My antiwirus(NOD32)

filtering only

''ARP gratuitous'' packages.

Other

ARP packages do not filter.

Im disable antivirus.

New works 

ethernetif_notify_conn_changed().

The main issue is closed.

 

1)Remains only bug in generate file ../Inc/stm32f4xx_hal_conf.h ( #define PHY_MICR_INT_OE ).

2)And little comment from:

  hal_eth_init_status = HAL_ETH_Init(&heth);

/*Comment next code*/

//  if (hal_eth_init_status == HAL_OK)

//  {

//    /* Set netif link flag */

//    netif->flags |= NETIF_FLAG_LINK_UP;

//  }

Based on the value returned by HAL_ETH_Init (), can not be said that the ''link up''.

Link up can identify read

PHY_LINK_STATUS

 

 /*Add next code*/

  HAL_ETH_ReadPHYRegister(&heth, PHY_SR, &regvalue);

  if((regvalue & PHY_LINK_STATUS)!= (uint16_t)RESET)

because if AutoNegotiation Disable function 

HAL_ETH_Init () does not check 

PHY_LINK_STATUS.

drachev
Associate II
Posted on November 03, 2015 at 10:25

need to be redon:

//  if (hal_eth_init_status == HAL_OK)

//  {

//    /* Set netif link flag */

//    netif->flags |= NETIF_FLAG_LINK_UP;

//  }

if you do not remake, then there will be bug:

NOT SEND ARP

 packets in 

first 

connection cable.

1) power down from device.

2) disconnect cable ethernet.

3) power up from device.

4) connect cable ethernet.

NOT SEND ARP

 packets Gratuitous.

This situation is typical use of the device at the first connection.

If add 

 HAL_ETH_ReadPHYRegister(&heth, PHY_SR, &regvalue);

  if((regvalue & PHY_LINK_STATUS)!= (uint16_t)RESET)

      {

      netif_set_link_up(netif);

      }

All ok.