본문 바로가기

[STM32F746G-DISCO] lwIP를 사용하여 DHCP 서버에서 IP 할당받기

by rudals.kim 2024. 7. 19. 댓글 개
반응형
아래 테스트는 STM32CubeIDE 1.7.0/STM32Cube_FW_F7_V1.16.1를 사용하여 테스트 되었습니다.


lwIP를 사용하여 이더넷 테스트를 하기 위해서는 가장 기본적으로 데모 보드가 IP를 할당받아야 합니다.
여기서는 DHCP 서버에 연결하여 자동으로 IP를 할당받는 테스트를 해 보았습니다.

테스트는 STM32Cube_FW_F7_V1.16.1/Projects/STM32746G-Discovery/Applications/LwIP의 예제를 참고하여 작성되었습니다.

새 프로젝트를 생성하여 핀 초기화 후 SYS/ETH/LWIP/RCC/USART1을 설정하였습니다.
예제에는 LCD를 사용하여 LOG 출력을 사용하였으나 이 테스트에서는 LCD 대신에 USART로 로그를 출력하도록 하였습니다.

ETH은 아래와 같이 기본 설정값을 사용하였습니다.

lwIP는 아래와 같이 설정하였습니다.
대부분의 값은 기본값을 사용하였으며 HTTPD/SNMP/SNTP/SMTP/MDNS/TFTP은 disable로 설정하였습니다.

프로젝트를 생성 후 예제를 참고하여 코드를 추가하였습니다.
제공되는 예제가 RTOS를 사용하여 구현되어 있으나 새 프로젝트에서는 RTOS를 사용하지 않는 NON-OS 형식으로 코드를 새로 작성하여 테스트하였습니다. DHCP 적용 시 중요한 소스코드는 app_ethernet.c를 참고하시면 됩니다.

우선 main.c에 아래와 같이 코드를 적용하였습니다.

/* USER CODE BEGIN 2 */
printf("DHCP test on STM32746G-DISCO board\r\n");
printf("  State: Ethernet Initialization ...\r\n");

lwip_init();
Netif_Config();
User_notification(&gnetif);
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
  /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */
  ethernetif_input(&gnetif);

  /* Handle timeouts */
  sys_check_timeouts();

  DHCP_Periodic_Handle(&gnetif);
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */


관련 코드는 아래 소스를 참고하시기 바랍니다.

/* USER CODE BEGIN 0 */
void Netif_Config(void)
{
  ip_addr_t ipaddr;
  ip_addr_t netmask;
  ip_addr_t gw;

  ip_addr_set_zero_ip4(&ipaddr);
  ip_addr_set_zero_ip4(&netmask);
  ip_addr_set_zero_ip4(&gw);

  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init,
            &ethernet_input);

  /*  Registers the default network interface. */
  netif_set_default(&gnetif);

  if (netif_is_link_up(&gnetif))
  {
    /* When the netif is fully configured this function must be called.*/
    netif_set_up(&gnetif);
  }
  else
  {
    /* When the netif link is down this function must be called */
    netif_set_down(&gnetif);
  }
}

void User_notification(struct netif *netif)
{
  if (netif_is_up(netif))
  {
    /* Update DHCP state machine */
    DHCP_state = DHCP_START;
  }
  else
  {
    /* Update DHCP state machine */
    DHCP_state = DHCP_LINK_DOWN;
    printf("The network cable is not connected \r\n");
  }
}

void DHCP_Process(struct netif *netif)
{
  ip_addr_t ipaddr;
  ip_addr_t netmask;
  ip_addr_t gw;
  struct dhcp *dhcp;
  uint8_t iptxt[20];

  switch (DHCP_state)
  {
  case DHCP_START:
  {
    ip_addr_set_zero_ip4(&netif->ip_addr);
    ip_addr_set_zero_ip4(&netif->netmask);
    ip_addr_set_zero_ip4(&netif->gw);
    DHCP_state = DHCP_WAIT_ADDRESS;
    dhcp_start(netif);

    printf("  State: Looking for DHCP server ...\r\n");
  }
  break;

  case DHCP_WAIT_ADDRESS:
  {
    if (dhcp_supplied_address(netif))
    {
      DHCP_state = DHCP_ADDRESS_ASSIGNED;

      sprintf((char *)iptxt, "%s",
              ip4addr_ntoa((const ip4_addr_t *)&netif->ip_addr));
      printf("IP address assigned by a DHCP server: %s\r\n", iptxt);
    }
    else
    {
      dhcp = (struct dhcp *)netif_get_client_data(netif,
                                                  LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);

      /* DHCP timeout */
      if (dhcp->tries > MAX_DHCP_TRIES)
      {
        DHCP_state = DHCP_TIMEOUT;

        /* Stop DHCP */
        dhcp_stop(netif);

        /* Static address used */
        IP_ADDR4(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
        IP_ADDR4(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2,
                 NETMASK_ADDR3);
        IP_ADDR4(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
        netif_set_addr(netif, &ipaddr, &netmask, &gw);

        sprintf((char *)iptxt, "%s",
                ip4addr_ntoa((const ip4_addr_t *)&netif->ip_addr));
        printf("DHCP Timeout !! \r\n");
        printf("Static IP address: %s\r\n", iptxt);
      }
    }
  }
  break;
  case DHCP_LINK_DOWN:
  {
    /* Stop DHCP */
    dhcp_stop(netif);
    DHCP_state = DHCP_OFF;
  }
  break;
  default:
    break;
  }
}

void DHCP_Periodic_Handle(struct netif *netif)
{
  /* Fine DHCP periodic process every 500ms */
  if (HAL_GetTick() - DHCPfineTimer >= DHCP_FINE_TIMER_MSECS)
  {
    DHCPfineTimer = HAL_GetTick();
    /* process DHCP state machine */
    DHCP_Process(netif);
  }
}
/* USER CODE END 0 */


빌드 후 실행해 보면 공유기에서 IP를 정상적으로 할당받아 옵니다.

IP를 할당받아 왔으니 TCP/UDP/HTTP등의 테스트를 해 봐야겠습니다.

반응형

댓글