Skip to main content
drachev
Associate II
October 28, 2015
Question

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

  • October 28, 2015
  • 7 replies
  • 1627 views
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);

        }

      }

    }

  }

}

    This topic has been closed for replies.

    7 replies

    Oussema Hajjem_O
    Visitor II
    October 29, 2015
    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
    drachevAuthor
    Associate II
    October 30, 2015
    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
    Visitor II
    October 30, 2015
    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
    drachevAuthor
    Associate II
    November 3, 2015
    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
    drachevAuthor
    Associate II
    November 3, 2015
    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
    drachevAuthor
    Associate II
    November 3, 2015
    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.