cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H563ZI (NUCLEO-H563ZI) and NETXDUO DHCP CLIENT

Isidre Sole
Associate II

Hello 
I am developing on the NUCLEO-H563ZI board a system in which I need to obtain an IP address via DHCP.
I have implemented the client following the guidelines of the documentation provided by ST as well as THREADX and NETXDUO and, I have strange behavior.
The system rarely completes all message transaction between the NUCLEO board and the DHCP server on my system. It usually stays alltime in a loop sending a DISCOVER and  ignoring the server's OFFER response.

IsidreSole_0-1706869870722.png

From time to time, it succeds to perform the full message cycle DISCOVER-OFFER-REQUEST-ACK, but then remains in a loop continuously performing a REQUEST and ignoring the ACK.

IsidreSole_1-1706871066701.png

I think I have a runtime or thread priority problem. I've tried everything and I can't get out of this dynamic.
The hardware works with other codes (not using DHCP).

I'm stalled here. 

This is the code that I'm using:

NX_PACKET_POOL dhcp_client_pool;
NX_IP client_ip;
NX_DHCP dhcp_client;
TX_THREAD dhcp_client_thread;
CHAR *pointer;

UCHAR message[50] = "Hello from DHCP Client";
ULONG dhcp_client_thread_counter;
ULONG dhcp_client_state_changes;
ULONG dhcp_client_error_counter;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
void dhcp_client_thread_entry(ULONG thread_input);
void dhcp_state_change_CB(NX_DHCP *dhcp_ptr,UCHAR new_state);
/* USER CODE END PFP */

/**
* @brief Application NetXDuo Initialization.
* @PAram memory_ptr: memory pointer
* @retval int
*/

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

/* USER CODE BEGIN App_NetXDuo_MEM_POOL */
(void)byte_pool;
/* USER CODE END App_NetXDuo_MEM_POOL */
/* USER CODE BEGIN 0 */
pointer = (CHAR *)(byte_pool->tx_byte_pool_start);
tx_thread_create(&dhcp_client_thread, "DHCP Client Thread", dhcp_client_thread_entry, 0,
pointer, DEMO_STACK_SIZE,
2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
pointer = pointer + DEMO_STACK_SIZE;
status = nx_packet_pool_create(&dhcp_client_pool, "DHCP Client Packet Pool",
NX_PACKET_SIZE, pointer, NX_PACKET_POOL_SIZE);
if (status != NX_SUCCESS) {
/* USER CODE BEGIN NX_Packet_Pool_Error */
Error_Handler();
/* USER CODE END NX_Packet_Pool_Error */
}
pointer = pointer + NX_PACKET_POOL_SIZE;

status = nx_ip_create(&client_ip, "DHCP Client IP Instance", IP_ADDRESS(0, 0, 0, 0),
IP_ADDRESS(255, 255, 255, 0), &dhcp_client_pool, nx_stm32_eth_driver,
pointer, 2048, 1);
if (status != NX_SUCCESS) {
/* USER CODE BEGIN NX_IP_Create_Error */
Error_Handler();
/* USER CODE END NX_IP_Create_Error */
}
pointer = pointer + 2048;

status = nx_arp_enable(&client_ip, pointer, 1024);
if (status != NX_SUCCESS) {
/* USER CODE BEGIN NX_ARP_Enable_Error */
Error_Handler();
/* USER CODE END NX_ARP_Enable_Error */
}
pointer = pointer + 1024;

status = nx_udp_enable(&client_ip);
if (status != NX_SUCCESS) {
/* USER CODE BEGIN NX_UDP_Enable_Error */
Error_Handler();
/* USER CODE END NX_UDP_Enable_Error */
}

// status =nx_icmp_enable(&client_ip);
// if (status != NX_SUCCESS) {
// /* USER CODE BEGIN NX_ICMP_Enable_Error */
// Error_Handler();
// /* USER CODE END NX_ICMP_Enable_Error */
// }

/* USER CODE END 0 */

/* USER CODE BEGIN MX_NetXDuo_Init */
/* USER CODE END MX_NetXDuo_Init */

return status;
}

/* USER CODE BEGIN 1 */
void dhcp_client_thread_entry(ULONG thread_input){
UINT status = TX_SUCCESS;
ULONG actual_status;
UINT length;
UINT ping = NX_TRUE;
UINT run_dhcp_client = NX_TRUE;
NX_PACKET *my_packet;

NX_PARAMETER_NOT_USED(thread_input);
do {
/* Get the link status. */
status = nx_ip_status_check(&client_ip, NX_IP_LINK_ENABLED,
&actual_status, 100);
} while (status != NX_SUCCESS);
status = nx_ip_interface_mtu_set(&client_ip,NX_DHCP_INTERFACE_INDEX, 1600);
if(status != NX_SUCCESS) {
Error_Handler();
}
status = nx_dhcp_create(&dhcp_client,&client_ip, "DHCP Client");
if(status != NX_SUCCESS) {
Error_Handler();
}
// status = nx_dhcp_state_change_notify(&dhcp_client, dhcp_state_change_CB);
// if(status != NX_SUCCESS) {
// Error_Handler();
// }
// status = nx_dhcp_set_interface_index(&dhcp_client, NX_DHCP_INTERFACE_INDEX);
// if(status != NX_SUCCESS) {
// Error_Handler();
// }
// status = nx_dhcp_interface_enable(&dhcp_client, NX_DHCP_INTERFACE_INDEX);
// if(status != NX_SUCCESS && status != NX_DHCP_INTERFACE_ALREADY_ENABLED) {
// Error_Handler();
// }
nx_dhcp_start(&dhcp_client);
while(run_dhcp_client) {
do{
status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED,
&actual_status, NX_IP_PERIODIC_RATE);
if(actual_status){
tx_thread_sleep(NX_IP_PERIODIC_RATE);
}
}while(actual_status != NX_SUCCESS || status != NX_SUCCESS);
length = sizeof(message);
BSP_LED_On(LED_GREEN);

while(ping){
status = nx_icmp_ping(&client_ip, NX_DHCP_DEFAULT_GATEWAY, (char *)message, length, &my_packet, NX_IP_PERIODIC_RATE);
if(status == NX_SUCCESS) {
nx_packet_release(my_packet);
}else{
dhcp_client_error_counter++;
}
dhcp_client_thread_counter++;
tx_thread_sleep(NX_IP_PERIODIC_RATE);
}
}
nx_dhcp_delete(&dhcp_client);
}

// void dhcp_state_change_CB(NX_DHCP *dhcp_ptr, UCHAR new_state){
// ULONG server_address;
// UINT status = TX_SUCCESS;
// NX_PARAMETER_NOT_USED(dhcp_ptr);
// NX_PARAMETER_NOT_USED(new_state);
// dhcp_client_state_changes++;
//
// if(new_state == NX_DHCP_STATE_SELECTING){
// status = nx_dhcp_request_client_ip(dhcp_ptr);
// }
// }

The commented code has been used in the different test to find what happends.

Thanks in advance for the help

Isidre

 

 

7 REPLIES 7
Isidre Sole
Associate II

I forget to say that only additional thread with lees priority is working and sleeps itself each second. Now it is doing a dummy led on led off operation.

 

Pavel A.
Evangelist III

What is the network interface? ETH, wi-fi with some module, Bluetooth, slip? If ETH, note that getting it to work is not trivial. Before trying a higher protocol such as DHCP, test the MAC layer well: send and receive packets of various sizes & payloads, unicast and broadcast. Make sure packets are not lost or delayed for too long time, and data is not corrupted. If you are optimistic, maybe instead of the MAC test use iperf, with fixed IP addresses. 

 

Hi Pavel

Is the LAN8742

Board NUCLEO-H563ZI

BR

Isidre

Hi again Pavel

This hardware works fine with other firmware. With an old one based on FreeRTOS and using LwIP  I can connect with no problems with my host (IP hardcoded).

This is why I'm very confident with this board, and thats the reason because I think is more a problem related with the firmware.

BR

Isidre

 

There are example projects for Nucleo H563 in STM32 Cube H5 package that use DHCP. Try to compare with them. Example:

STM32CubeH5/Projects/NUCLEO-H563ZI/Applications/NetXDuo/Nx_SNTP_Client at main · STMicroelectronics/STM32CubeH5 · GitHub

 

Note: is it correct to set the MTU to 1600 ? it is larger than ethernet packet size.

 

status = nx_ip_interface_mtu_set(&client_ip,NX_DHCP_INTERFACE_INDEX, 1600);

 

  

Pavel A.
Evangelist III

> is it correct to set the MTU to 1600 ?

Depends on other devices on the routing path. The ETH IP itself supports large sizes, even "jumbo packets".

Orabnetax
Associate

Hi Isidre Sole,

have you found a solution yet?

Potentially I had a similar problem but found a way to solve this.

I debugged a few days ago the non working DHCP on my setup.
Proprietary board with STM32H743 and LAN interface dp8326e from TI.

To get the stackup working stable I had to fine tune the cache regions - disabling data cache for a test worked as well.
Otherwise it started working, e.g. with a FTP server, but stopped after a while.

Then I experienced a problem with DHCP server.
Linux Laptop got an offer with an IP from the defined range.
Linux Laptop requests that IP address and got a NAK.
Then some retries started and the process stops.

After debugging the DHCP process I found the reason in the nx configuration parameter: NX_DHCP_CLIENT_OPTIONS_MAX = 12 (nxd_dhcp_server.h)

Your DHCP packet shows a lot of options as well. Each listed option cost one or more entries.
The selected IP is requested in option 50. If this is late in the list and the option count of 12 is exhausted, the DHCP server to not see a request for a specific IP and send the NAK.

I set the value to 32 and voilá DHCP worked as expected.

In my setting the MTU was default to 1500.

Best Regards

Orabnetax