on
2026-04-28
7:23 AM
- edited on
2026-04-29
5:14 AM
by
Laurids_PETERSE
This guide explains how to bring up Ethernet TCP/IP on an STM32H7 board using the lightweight Mongoose networking library, with the NUCLEO-H723ZG used as the reference platform. We walk through creating a STM32CubeMX project, configuring the key peripherals needed for Ethernet, UART debug, LEDs, and RNG. Additionally, adding Mongoose through the STM32CubeMX software pack so the project gets the required source files and include paths automatically.
This guide provides step-by-step instructions to integrate the Mongoose networking library into STM32H7 firmware for Ethernet connectivity. After integration, Mongoose enables a full set of networking features, including an embedded web dashboard, remote device control using MQTT, TLS security, and over-the-air (OTA) firmware updates. The goal of this guide is to bring up TCP/IP on STM32H7 and run a simple "Hello world" embedded web server as a foundation for more advanced connected applications.
Mongoose is a lightweight, open-source, dual-licensed network library that consists of two files. It includes a built-in embedded web server and networking stack. Mongoose works with existing TCP/IP stacks such as lwIP, or it can run independently using its built-in network stack. The same flexibility applies to TLS: you can use external libraries such as Mbed TLS or WolfSSL, or use the built-in TLS support provided by Mongoose.
For a quick and reliable start, use the built-in network stack. This approach reduces dependencies and makes integration easier. This guide uses the NUCLEO-H723ZG development board, but the same approach applies to any STM32 microcontroller with a built-in Ethernet MAC.
A preconfigured h723.ioc STM32CubeMX is included. If you want to get the result fast, generate the project from that *.ioc file, replace Core/Src/main.c with the provided main.c and adjust the linker script (STM32H723XG_FLASH.ld) with the provided STM32H723XG_FLASH.ld, build, and flash.
Install the following tools:
The hardware used in this tutorial is the NUCLEO-H723ZG board.
Use STM32CubeMX to configure all required peripherals from scratch. This approach sets up the project correctly and helps you understand how to integrate Mongoose into existing STM32 projects.
Open STM32CubeMX. In File → New project, type "H723ZG" in the part number field, select the microcontroller from the list at the bottom, and click [Start project] at the top right.
When the memory protection unit dialog appears, click [Yes]. In the "Project Manager" tab, select the project directory and enter a project name.
In the "Clock Configuration" tab, select the maximum system frequency and press Enter to auto-configure it.
Now, configure the following peripherals: LEDs, Ethernet MAC, UART for serial debug output, and RNG for TLS. For each development board, the pins for these peripherals are described in the respective User Manuals. The table below provides a quick overview of the required pins and links to the respective user manuals:
| Board | UART,TX,RX | Ethernet | LED |
|---|---|---|---|
| Nucleo-H723ZG | USART3,PD8,PD9 | PA1,PA2,PA7,PC1,PC4,PC5,PB13,PG11,PG13 | PB0,PE1,PB14 |
| STM32H747I-DISCO | USART1,PA9,PA10 | PA1,PA2,PA7,PC1,PC4,PC5,PG11,PG12,PG13 | PI12,PI13,PI14 |
| STM32H735G-DK | USART3,PD8,PD9 | PA1,PA2,PA7,PC1,PC4,PC5,PB11,PB12,PB13 | PC3,PC2 |
| STM32H573I-DK | USART1,PA9,PA10 | PA1,PA2,PA7,PC1,PC4,PC5,PG11,PG12,PG13 | PI8,PI9,PF1 |
| NUCLEO-N657X0-Q | USART1,PE5,PE6 | PF4,PF5,PF7,PF10,PF11,PF12,PF13,PF14,PF15 | PG0,PG8,PG10 |
| NUCLEO-H563ZI | USART3,PD8,PD9 | PA1,PA2,PA7,PC1,PC4,PC5,PB15,PG11,PG13 | PB0,PF4,PG4 |
| NUCLEO-H7S3L8 | USART3,PD8,PD9 | PA2,PA7,PB6,PG4,PG5,PG6,PG11,PG12,PG13 | PD10,PD13,PB7 |
| NUCLEO-H745ZI-Q | USART3,PB10,PB11 | PA1,PA2,PA7,PC1,PC4,PC5,PB13,PG11,PG13 | PI13,PJ2,PD3 |
| NUCLEO-H755ZI-Q | USART3,PD8,PD9 | PA1,A2,A7,C1,C4,C5,G11,G12,PG13 | PB0,PE1,PB14 |
| NUCLEO-H753ZI | USART3,PD8,PD9 | PA1,PA2,PA7,PC1,PC4,PC5,PB11,PB12,PB13 | PC3,PC2,PC2 |
| NUCLEO-H743ZI | USART3,PD8,PD9 | PA1,PA2,PA7,PC1,PC4,PC5,PB13,PG11,PG13 | PB0,PE1,PB14 |
| NUCLEO-Fxxxxx | USART3,PD8,PD9 | PA1,PA2,PA7,PC1,PC4,PC5,PB13,PG11,PG13 | PB0,PB7,PB14 |
In "Pinout & Configuration" → "System Core" → "GPIO", configure the LED pins as [GPIO_Output].
In "Pinout & Configuration" → "Security", select RNG and set the mode to [Activated].
In "Pinout & Configuration" → "Connectivity", set USART to [Asynchronous mode] and configure the Tx and Rx pins.
In "Pinout & Configuration" → "Connectivity", set "ETH" to [RMII mode] and configure the Ethernet pins.
In the Project Manager tab, choose the target IDE and click [Generate Code]. You can select any available option, such as CMake or STM32CubeIDE. This guide uses VS Code STM32, so select CMake.
After the project is generated in your target directory, open that directory in VS Code.
It's time to add Mongoose to the project.
There are multiple ways to do this. One option is to copy mongoose.c and mongoose.h from the GitHub repository: https://github.com/cesanta/mongoose. Then, add a mongoose_config.h file with one line in it.
However, the best way is to use STM32CubeMX, since Mongoose is available as STM32CubeMX middleware. Adding middleware also automatically configures include paths and provides additional modules such as web dashboard and MQTT, which will be covered in future articles.
In STM32CubeMX, click "Pinouts & Configuration" → "Software Packs" → "Manage Software Packs."
In the window, click [Cesanta], then click [Refresh]. Install the latest "I-CUBE-Mongoose" pack. Ensure it is version 7.21.4 or later.
This action adds the Middlewares/Third_Party/Cesanta_Mongoose/ directory with three files: mongoose.c, mongoose.h, and mongoose_config.h.
/* USER CODE BEGIN Includes */
#include "mongoose.h"
/* USER CODE END Includes */
Add the _write override to redirect printf debug output to the serial console. Also, add the HTTP event handler function that implements a basic web server. Insert these in the user code block:
/* USER CODE BEGIN 0 */
int _write(int fd, unsigned char *buf, int len) {
HAL_UART_Transmit(&huart3, buf, len, HAL_MAX_DELAY);
return len;
}
static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_MSG) {
mg_http_reply(c, 200, "", "Hi from Mongoose! Tick %lu\r\n", HAL_GetTick());
}
}
/* USER CODE END 0 */
Add the following to the main function to initialize and run Mongoose. This runs the TCP/IP stack and the web server:
/* USER CODE BEGIN WHILE */
struct mg_mgr mgr;
mg_mgr_init(&mgr);
mg_http_listen(&mgr, "http://0.0.0.0:80", http_ev_handler, NULL);
while (1)
{
mg_mgr_poll(&mgr, 0);If you use an RTOS, run the Mongoose event loop in a separate task. Allocate about 8 KB of stack space. Mongoose can run in both RTOS and bare-metal environments.
Open STM32H723XG_FLASH.ld and add the following line before the .bss (NOLOAD) line:
.eth_ram : { *(.eth_ram .eth_ram*) } > RAM_D2 AT > FLASHIf this is not done, .eth_ram ends up in the same region as .bss, which might not be accessible by the Ethernet DMA. The memory regions and their accessibility are described in the reference manual.
For STM32H723, see RM0468, section 2.4.
Rebuild the firmware.
Open a serial console. On Windows, use your favorite terminal, either the integrated one in VS Code or others, such as putty.exe utility or Tera Term. On Linux or macOS, using the cu utility is recommended.
$ sudo cu -l /dev/cu.usb* -s 115200
Ensure that your board is connected to an Ethernet network with a DHCP server. The easiest option is to use a USB to Ethernet dongle and enable internet sharing on the Ethernet interface.
Start STM32CubeProgrammer and flash the firmware.
{
"version": "2.0.0",
"tasks": [
{
"label": "Flash STM32",
"type": "shell",
"command": "STM32_Programmer_CLI",
"args": [
"-c", "port=SWD",
"-w", "${workspaceFolder}/build/Debug/*.elf",
"-v",
"-rst"
],
"problemMatcher": []
}
]
}0 2 mongoose.c:26153:mg_phy_init PHY ID: 0x07 0xc131 (LAN87x)
6 2 mongoose.c:5834:mg_mgr_init Driver: stm32h, MAC: 2a:37:94:03:d5:74
d 3 mongoose.c:5841:mg_mgr_init MG_IO_SIZE: 512, TLS: builtin
13 3 mongoose.c:5758:mg_listen 1 0 http://0.0.0.0:80
19 1 mongoose.c:6260:onstatechange Link down
1e 1 mongoose.c:7795:mg_tcpip_poll Network is down
3ee 1 mongoose.c:6260:onstatechange Link down
3f2 1 mongoose.c:7795:mg_tcpip_poll Network is down
7d6 3 mongoose.c:28424:mg_tcpip_driv Link is 100M full-duplex
7db 3 mongoose.c:6404:tx_dhcp_discov DHCP discover sent. Our MAC: 2a:37:94:03:d5:74
831 3 mongoose.c:6382:tx_dhcp_reques DHCP req sent
836 2 mongoose.c:6559:rx_dhcp_client Lease: 3600 sec (3602)
83c 2 mongoose.c:6249:onstatechange READY, IP: 192.168.2.31
842 2 mongoose.c:6250:onstatechange GW: 192.168.2.1
847 2 mongoose.c:6253:onstatechange MAC: 2a:37:94:03:d5:74Open the IP address in your browser. You should see the output from the web server.
Congratulations! Your STM32 device is now running Ethernet TCP/IP and a simple web server. Mongoose enables many possibilities, which will be covered in future articles.