cancel
Showing results for 
Search instead for 
Did you mean: 

LwIP problems from code generated via STM32CubeMX (SMT32H7)

KR1
Associate III

Hello,

I seem to be having some problems with the code generated via STM32CubeMX on the NUCLEO-H743ZI development board. I want to configure it to run on LwIP/RAW API. I can create such a configuration for its close relative: the NUCLEO F767ZI development board. In the latter case I take the following steps:

  1.  Set the HCLK to 216 MHz (clocked from the HSI);
  2. Enable the ETH peripheral, set it to RMII mode, and set ETH_TXD0 and ETH_TX_EN pins to PG13 and PG11 (others are mapped appropriately);
  3.  Set the PHY address to 0 in ETH Configuration>General: Ethernet Configuration
  4.  Enable the LwIP middleware;
  5. Enable ICMP (LWIP_BROADCAST_PING and LWIP_MULTICAST_PING in LwIP Key Options>IPMP Options). This step is not necessary, although it helps to determine if all is well with the device.

After I generate the code, I add an extern variable to my main.c to be able to track whether the device has obtained an IP address:

/* USER CODE BEGIN PV */
 
/* Private variables ---------------------------------------------------------*/
 
extern struct netif gnetif;
 
/* USER CODE END PV */

Moreover, I add the standard LwIP/RAW IP callbacks t the main loop:

/* Infinite loop */
 
 /* USER CODE BEGIN WHILE */
 
 while (1)
 
 {
 
 
 
 /* USER CODE END WHILE */
 
 
 
 /* USER CODE BEGIN 3 */
 
 ethernetif_input(&gnetif);
 
 sys_check_timeouts();
 
 }
 
 /* USER CODE END 3 */

This code works well and I am able to get an IP address (I can determine it frome the gnetif->ip_addr field), I can see all the proper ARP request in WireShark and I am able to ping the device:

0690X000006C7VhQAK.png

Herein, I am filtering only the traffic from/to the appropriate (STM32) MAC address 00:80:E1:00:00:00.

For the NUCLEO-H7432ZI board, I essentially follow the same steps, with a couple of minor deviations:

  1.  Set the HCLK to 400 MHz (clocked from the HSI);
  2. Enable the ETH peripheral, set it to RMII mode, and set ETH_TXD0 and ETH_TX_EN pins to PG13 and PG11 (others are mapped appropriately);
  3. Enable the CPU DCache (under Cortex_M7 Configuration)
  4. Enable the LWIP middleware
  5. Select LAN8742/LAN8742 as the Driver_PHY (under LwIP>Platform Settings)
  6. Enable ICMP (LWIP_BROADCAST_PING and LWIP_MULTICAST_PING in LwIP Key Options>IPMP Options).

I change the code in main.c appropriately as for the F7 example. Moreover, I edit the linker file to partition the RAM from 0x24000000 to 0x2407FFFF (there is an instruction in ETH>Parameter Setting to do so in order to get the ETH peripheral working).

If I upload this (nearly identical) build to the NUCLEAO-H743ZI board, I get no network activity (No ARP requests to get an IP address.

Now I know that the issue is somewhere in the STM32CubeMX generated configuration. The hardware itself is good. There is an example of a LwIP HTTP server in STM32Cube_FW_H7_V1.1.0 which works just fine if I upload it to the board. The LwIP_HTTP_Server_Netconn_RTOS example in STM32Cube_FW_H7_V1.1.0 is somewhat different: it uses a RTOS and the Netconn API. For my application I want to stick with Raw API (and no RTOS). So my question would be, what am I missing in my microcontroller configuration?

23 REPLIES 23

Dear Wael,

I did not miss your last post, I just wanted to test a new .ioc file.

But it did not work. I am sorry for the delay.

The last working project was by using the added file: myproject_V132.ioc

It was generated by an oder version of CubeMX.

I am still missing a working example including files like: "app_ethernet.c"

"httpserver_netconn.c" and "fsdata.c" to test complete working project.

I am using AC6 tools (SW4STM32) and Nucleo-144 board NUCLEO-H743ZI

Thank you very much for investigation.

Best Regards,

Roland

KR1
Associate III

Dear Wael,

I seem to have deleted the project files a while ago. Nonetheless, you can simply follow the instructions provided in my original post. All of the configuration steps are outlined there.

Cheers,

KR

KR1
Associate III

Edit:

I think I have found a backup of the said project (or at least a version that I tried to recompile some time later, hence the project name). I would also like to point out one thing that I have discovered while working with the F7 series. STM32CubeMX can generate improper Ethernet PHY configuration:

https://community.st.com/s/question/0D50X0000ADB5iZSQT/networking-issues-for-lwipfreertos-code-generated-via-stm32cubemx-nucleof746zg

WBOUG
Senior

Hi @KR​ 

I apologize for the delay and I have the honor to inform you that I finally had a solution to run the LWIP on H7

1- You must activate the MPU control mode in Background Region Access Not Allowed + MPU Disabled during hard fault, NMI and FAULTMASK handlers

2- You must configure the region 0 and 1 according to the configuration found in the code

You will find a screen print for the simulation and generate code

I will remain at your disposal for any other questions.

0690X000006Dt51QAC.png

Hi @RMuel.18.303​ 

I apologize for the delay and I have the honor to inform you that I finally had a solution to run the LWIP on H7

1- You must activate the MPU control mode in Background Region Access Not Allowed + MPU Disabled during hard fault, NMI and FAULTMASK handlers

2- You must configure the region 0 and 1 according to the configuration found in the code

You will find a screen print for the simulation and generate code

I will remain at your disposal for any other questions.0690X000006Dt51QAC.png

Dear Wael,

Sorry for the delay. The suggestions did not work, but now I have managed it without using RTOS:

I changed to LwiP TCP/IP stack without RTOS (Raw API), because this did work for us.

Using Raw API worked mostly well, but there were also some crashes remaining, if too much Ajax requests were fired

at once and the LwIP Server had to receive and to send too much data without any time of idling.

The problem seems to be the instruction - cache! The data - cache is not the problem.

Finally, I made following changes in module "ethernetif.c" (LwIP Raw API):

static err_t low_level_output(struct netif *netif, struct pbuf *p)

{

 SCB_DisableICache();   // Disable Instruction-cache at beginning of function

 for (....)

 ...

 SCB_EnableICache();   // Enable Instruction-cache at end of function

 return errval;

 }

static struct pbuf * low_level_input(struct netif *netif)

{

 (HAL_ETH_IsRxDataAvailable(&heth))

 {

   SCB_DisableICache(); // Disable Instruction-cache at beginning of function in case of success!

   ...

   SCB_EnableICache();   // Enable Instruction-cache at end of function

   return p;

 }

 else

  {

   return NULL;

  }

}

I do not use main-loop for Lwip-Process polling.

// while (1)

//   {

//      MX_LWIP_Process();   // in lwip.c this function calls: ethernetif_input() in ethernetif.c

//   }

I simply use Ethernet - Interrupt for Lwip-Process instead include in "stm32h7xx_it.c":

void ETH_IRQHandler(void)

{

 uint32_t rest;

 do

 {

    rest = ethernetif_input(&gnetif);                     

 } while (rest );

 // --------------- Clear the flags, when done ------------------------

  __HAL_ETH_DMA_CLEAR_IT(&heth, ETH_DMACSR_RI | ETH_DMACSR_NIS);

  __HAL_ETH_DMA_CLEAR_IT(&heth, ETH_DMACSR_TI | ETH_DMACSR_NIS);

  __HAL_ETH_DMA_CLEAR_IT(&heth, (ETH_DMACSR_CDE | ETH_DMACSR_ETI | ETH_DMACSR_RWT |

                         ETH_DMACSR_RBU | ETH_DMACSR_AIS));

  __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG(ETH_WAKEUP_EXTI_LINE);

}

This gives a more comfortable "RTOS" feeling and works perfectly now.

In main-loop something else can be performed.

NOW IT IS WORKING PERFECTLY!

Best Regards,

Roland

KFili
Associate

Hi everybody and @WBOUG​ 

I tried to use LwIP_HTTP_Server_Netconn_RTOS example on STM32CubeIDE. (STM32F767ZI-NUCLEO BOARD) but it could not run properly.

it works for 2 mins then stucks. (Sometimes it effects the other tasks sometimes it doesn't)

I share all configurations' screenshots.

I would be grateful if you show me where I have the mistake.

void StartDefaultTask(void *argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();
  /* USER CODE BEGIN 5 */
  http_server_netconn_init();
  /* Infinite loop */
  for(;;)
  {
 
	  osThreadTerminate(NULL);
	  osDelay(1);
  }
  /* USER CODE END 5 */ 
}
 
/* MPU Configuration */
 
void MPU_Config(void)
{
  MPU_Region_InitTypeDef MPU_InitStruct = {0};
 
  /* Disables the MPU */
  HAL_MPU_Disable();
  /** Initializes and configures the Region and the memory to be protected 
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER0;
  MPU_InitStruct.BaseAddress = 0x2007C000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /** Initializes and configures the Region and the memory to be protected 
  */
  MPU_InitStruct.Enable = MPU_REGION_ENABLE;
  MPU_InitStruct.Number = MPU_REGION_NUMBER1;
  MPU_InitStruct.BaseAddress = 0x20080000;
  MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
  MPU_InitStruct.SubRegionDisable = 0x0;
  MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
  MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
  MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
  MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
  MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
  MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
 
  HAL_MPU_ConfigRegion(&MPU_InitStruct);
  /* Enables the MPU */
  HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
 
}

0690X00000Bud2gQAB.jpg

0690X00000Bud2bQAB.jpg

0690X00000Bud2lQAB.jpg

0690X00000Bud2qQAB.jpg0690X00000Bud2vQAB.jpg0690X00000Bud30QAB.jpg0690X00000Bud3AQAR.jpg0690X00000Bud3FQAR.jpg0690X00000Bud3KQAR.jpg0690X00000Bud3PQAR.jpg

clock.1166
Senior

Hi Everybody,

There are literally hundreds of queries about the 'LwIP_HTTP_Server_Netconn_RTOS' and how to run it on stm32H743Zi2 on this and many other forums.

Why on earth doesn't someone at ST pick up this nucleo board and give a simple explanation on how to get it working using the latest CUBEIDE/compiler/demo software?

They could give a few lines of text on the exact procedure and a zipped project.

Surely this would only take a few minutes?

Its supposed to work 'out of the box'!

Pavel A.
Evangelist III

@clock.1166​ Maybe another example can help you. UDP echo server on the stm32H743Zi2 nucleo.