cancel
Showing results for 
Search instead for 
Did you mean: 

HTTP server on NetX and AZRTOS - disable DHCP when using fixed IP address?

GreenGuy
Lead

In another project using FreeRTOS and LwIP, cubeMX allowed the ability to disable DHCP and set a fixed IP address like 192.168.1.10. But I don't see a way to do that using AZRTOS.

9 REPLIES 9
GreenGuy
Lead

Having reviewed the STM32H743-Eval example application for LwIP_HTTP_Server_Netconn_RTOS, which works on my eval board, the application looks for a DHCP server and not seeing one after the time out period, falls back to a default 192.168.0.10 address and the PC connects to it with a browser. However nx_webserver example just gives up with "No cable connected" and does nothing. So please if someone has been able to achieve the same result with Nx_Webserver; let me know.

MSG_ST
ST Employee

Hi,

Could you please refer to the X-CUBE-AZRTOS-H7 3.0.0 and use CubeMX 6.7.0 (or newer).

There's a new feature implemented : "Common init" where the Azure RTOS MW initialization is generated automatically if you enable the feature.

And, under NetXDuo section, you could disable DHCP and set your fixed IP address.

Please do no hesitate to give us your feedback.

Regards

Mahdy

GreenGuy
Lead

Here is my feedback:

1) I Do Not see a "Common Init" feature, but I do see in the NetXDuo Core Init this:

0693W00000aIcG2QAK.pngAs you can see here, I do not see a check box to disable DHCP.

Perhaps I need an updated version of CubeIDE/MX or perhaps there is significant detail you have not revealed.

2) Have you tried this using my code or is this an untested suggestion?

You need to update CubeMX/IDE.

GreenGuy
Lead

Done.

CubeIDE: Version: 2.0.100.202301271415

CubeMX: Version: 6.8.0-RC4

Re-Built - No errors

Did not fix the problem.

GreenGuy
Lead

And this is the worst part. Now every time I generate code CubeMX is removing the Utilities Folder from the root of my project. I need that for the LCD utility functions. Is there some new check box to tell CubeMX not to do that?

GreenGuy
Lead

Had to move the utilities folder into the source folder so CubeMX leaves it alone.

ineeve-omst
Associate

I'm trying to disable DHCP on X-CUBE-AZRTOS-F7 for a STM32F767ZI6 MCU and there's no option in STM32CubeMx...

Paine
Associate

Hi GreenGuy,

I also wanted to get a static IP working with my NX_Webserver DHCP implementation on the STM32H573 -- and I figured it out with the help of some nice LLMs! Here's for anyone running into the same issue:

In app_netxduo.h add in your own defines for IP. for this to work with your own network use ipconfig (for windows, sorry I don't know the linux equivalent) in the command line to get the right gateway and subnet mask you need to use:

 

#define NX_APP_DEFAULT_IP_ADDRESS                   0

#define NX_APP_DEFAULT_NET_MASK                     0

/* USER CODE BEGIN 1 */

#define STATIC_IP_ADDRESS     IP_ADDRESS(192,168,16,130)
#define SUBNET_MASK           IP_ADDRESS(255,255,252,0)
#define GATEWAY_ADDRESS       IP_ADDRESS(192,168,16,1)

/* USER CODE END 1 */

 

make sure that the first 3 numbers you use for STATIC_IP_ADDRESS matches the first three of GATEWAY_ADDRESS, and then we can change the last digit of static to any free addresses on your network (I think this is 0-255, someone please correct me if that's wrong).

In app_netxduo.c we will be removing all calls to the DHCP client in App_Link_Thread_Entry and the nx app main thread entry:

 

static void App_Link_Thread_Entry(ULONG thread_input)
{
  ULONG actual_status;
  UINT linkdown = 0, status;
  printf("Entering app_link_thread_entry.\n");
  while(1)
  {
    /* Get Physical Link stackavailtus. */
    status = nx_ip_interface_status_check(&NetXDuoEthIpInstance, 0, NX_IP_LINK_ENABLED,
                                      &actual_status, 10);

    if(status == NX_SUCCESS)
    {
      if(linkdown == 1)
      {
        linkdown = 0;
        status = nx_ip_interface_status_check(&NetXDuoEthIpInstance, 0, NX_IP_ADDRESS_RESOLVED,
                                      &actual_status, 10);
        if(status == NX_SUCCESS)
        {
          /* The network cable is connected again. */
          printf("The network cable is connected again.\n");
          /* Print Webserver Client is available again. */
          printf("Webserver Client is available again.\n");
        }
        else
        {
          /* The network cable is connected. */
          printf("The network cable is connected.\n");
          /* Send command to Enable Nx driver. */
          nx_ip_driver_direct_command(&NetXDuoEthIpInstance, NX_LINK_ENABLE,
                                      &actual_status);
          /* Restart DHCP Client. */
//          nx_dhcp_stop(&DHCPClient);
//          nx_dhcp_start(&DHCPClient);
        }
      }
    }
    else
    {
      if(0 == linkdown)
      {
        linkdown = 1;
        /* The network cable is not connected. */
        printf("The network cable is not connected.\n");
      }
    }

    tx_thread_sleep(NX_APP_CABLE_CONNECTION_CHECK_PERIOD);
  }
}

 

and

 

static VOID nx_app_thread_entry (ULONG thread_input)
{
  /* USER CODE BEGIN Nx_App_Thread_Entry 0 */

  /* USER CODE END Nx_App_Thread_Entry 0 */

  UINT ret = NX_SUCCESS;

  /* USER CODE BEGIN Nx_App_Thread_Entry 1 */
//  ret = nx_ip_address_change_notify(&NetXDuoEthIpInstance, ip_address_change_notify_callback, NULL);
//  if (ret != NX_SUCCESS)
//  {
//    /* USER CODE BEGIN IP address change callback error */
//    Error_Handler();
//
//    /* USER CODE END IP address change callback error */
//  }

  /* USER CODE END Nx_App_Thread_Entry 1 */


//  /* start the DHCP client */
//  ret = nx_dhcp_start(&DHCPClient);
//  if (ret != NX_SUCCESS)
//  {
//    /* USER CODE BEGIN DHCP client start error */
//    Error_Handler();
//
//    /* USER CODE END DHCP client start error */
//  }
//
//  /* wait until an IP address is ready */
//  if(tx_semaphore_get(&DHCPSemaphore, NX_APP_DEFAULT_TIMEOUT) != TX_SUCCESS)
//  {
//    /* USER CODE BEGIN DHCPSemaphore get error */
//    Error_Handler();
//
//    /* USER CODE END DHCPSemaphore get error */

 

and in MX_NetXDuo_Init we will change the ip_creation call, as well as add our own "nx_ip_gateway_address_set" function call, both using our IP defines:

 

UINT MX_NetXDuo_Init(VOID *memory_ptr)
{
  UINT ret = NX_SUCCESS;
  TX_BYTE_POOL *byte_pool = (TX_BYTE_POOL*)memory_ptr;

   /* USER CODE BEGIN App_NetXDuo_MEM_POOL */
  /* USER CODE END App_NetXDuo_MEM_POOL */
  /* USER CODE BEGIN 0 */
 printf("Nx_Webserver application started..\n");
  /* USER CODE END 0 */

  /* Initialize the NetXDuo system. */
  CHAR *pointer;
  nx_system_initialize();

    /* Allocate the memory for packet_pool.  */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer, NX_APP_PACKET_POOL_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }

  /* Create the Packet pool to be used for packet allocation,
   * If extra NX_PACKET are to be used the NX_APP_PACKET_POOL_SIZE should be increased
   */
  ret = nx_packet_pool_create(&NxAppPool, "NetXDuo App Pool", DEFAULT_PAYLOAD_SIZE, pointer, NX_APP_PACKET_POOL_SIZE);

  if (ret != NX_SUCCESS)
  {
    return NX_POOL_ERROR;
  }

    /* Allocate the memory for Ip_Instance */
  if (tx_byte_allocate(byte_pool, (VOID **) &pointer, Nx_IP_INSTANCE_THREAD_SIZE, TX_NO_WAIT) != TX_SUCCESS)
  {
    return TX_POOL_ERROR;
  }

   /* Create the main NX_IP instance */ //default
//  ret = nx_ip_create(&NetXDuoEthIpInstance, "NetX Ip instance", NX_APP_DEFAULT_IP_ADDRESS, NX_APP_DEFAULT_NET_MASK, &NxAppPool, nx_stm32_eth_driver,
//                     pointer, Nx_IP_INSTANCE_THREAD_SIZE, NX_APP_INSTANCE_PRIORITY);
    ret = nx_ip_create(&NetXDuoEthIpInstance, "NetX Ip instance", STATIC_IP_ADDRESS, SUBNET_MASK, &NxAppPool, nx_stm32_eth_driver,
                       pointer, Nx_IP_INSTANCE_THREAD_SIZE, NX_APP_INSTANCE_PRIORITY);

  if (ret != NX_SUCCESS)
  {
    return NX_NOT_SUCCESSFUL;
  }

  //custom stuff
  ret = nx_ip_gateway_address_set(&NetXDuoEthIpInstance, STATIC_IP_ADDRESS);

  if (ret != NX_SUCCESS)
  {
    return NX_NOT_SUCCESSFUL;
  }

 

I thought ip_gateway_address_set would need GATEWAY_ADDRESS in its second argument, but I did debugging into that function and it was looking for the static ip address, so that's what worked.

 

And one last thing. For some reason if you don't add a HAL_Delay in main after HAL_Init(), the netxduo app fails to grab an IP. I tried 1000 and that didn't work but 5000 works consistently, I haven't tested what would be the minimum amount of time needed:

 

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();


  /* USER CODE BEGIN Init */
  HAL_Delay(5000);
  /* USER CODE END Init */

 

I think this is because the PHY ethernet interface takes a second or two to get setup, and if you try to immediately jump to IP initialization, the code is not talking to anything. I guess if you didn't want to do this, you might be able to call a a delay at the beginning of MX_NetXDuo_Init, but I haven't tested it.

Also if you want to be able to change the IP address on the fly you probably will need that ip_address_change_notify thread that I commented out, but I haven't figured out how to implement that yet.


In terms of .IOC settings, I made these changes from the default STM32H5 NX_Webserver example .IOC settings/code, but you probably could uncheck DHCP in the netxduo settings and save yourself some commenting things out. Good luck future embedded designers!