Valentin Haudiquet e678ccb8b3
All checks were successful
Build ESP32 BMC Firmware / build (push) Successful in 57s
fix: use max connection count as max client count
2026-03-12 18:12:36 +01:00
2026-03-11 17:39:43 +01:00
2026-03-11 17:39:43 +01:00
2026-03-11 17:39:43 +01:00
2026-03-11 17:39:43 +01:00
2026-03-11 17:39:43 +01:00
2026-03-11 17:39:43 +01:00

ESP32-S3 BMC Firmware

A Baseboard Management Controller (BMC) firmware for ESP32-S3 that provides remote management capabilities for external boards via Ethernet.

Features

  • Ethernet Connectivity: W5500 SPI Ethernet module support
  • GPIO Control: 16 GPIO pins for power control, status monitoring, and user functions
  • Serial Console: UART bridge with WebSocket support for remote console access
  • Web Interface: Modern HTML/CSS dashboard for easy management
  • REST API: Full REST API for programmatic control

Hardware Requirements

  • ESP32-S3 development board
  • W5500 SPI Ethernet module
  • Target board to manage

Pin Connections

W5500 SPI Ethernet

ESP32-S3 W5500
GPIO 11 MOSI
GPIO 13 MISO
GPIO 12 SCLK
GPIO 10 CS
GPIO 9 RST
GPIO 14 INT

UART Serial

ESP32-S3 Target Board
GPIO 43 TX
GPIO 44 RX

BMC GPIOs

GPIO Name Description
37 POWER ATX power supply "PS_ON#" signal

Building

Prerequisites

  • ESP-IDF v5.0 or later
  • Python 3.8+
  • CMake 3.16+

Setup ESP-IDF

# Install ESP-IDF (if not already installed)
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32s3
source export.sh

Build and Flash

# Navigate to project directory
cd esp32-bmc

# Configure the project (optional)
idf.py menuconfig

# Build
idf.py build

# Flash to ESP32-S3
idf.py -p /dev/ttyUSB0 flash

# Monitor serial output
idf.py -p /dev/ttyUSB0 monitor

Configuration

Network Settings

By default, the firmware uses DHCP. To configure static IP:

  1. Run idf.py menuconfig
  2. Navigate to "BMC Configuration"
  3. Disable "Use DHCP" and set static IP, netmask, and gateway

Or use the REST API to change network settings at runtime.

GPIO Configuration

GPIO pins can be configured in main/config.h. Modify the bmc_gpio_defaults array to change pin assignments, names, and default modes.

REST API

GPIO Endpoints

Method Endpoint Description
GET /api/gpio Get all GPIO states
POST /api/gpio/set?pin=X Set GPIO value (body: {"value": 0/1})
PUT /api/gpio/config?pin=X Configure GPIO mode (body: {"mode": "input/output"})

Power Control Endpoints

Method Endpoint Description
GET /api/power/status Get power status
POST /api/power/on Turn board power on
POST /api/power/off Turn board power off
POST /api/power/reset Reset the board

Serial Endpoints

Method Endpoint Description
GET /api/serial/config Get serial configuration
PUT /api/serial/config Set serial configuration
POST /api/serial/send Send data to serial
GET /api/serial/ws WebSocket for serial console

System Endpoints

Method Endpoint Description
GET /api/system/info Get system information
GET /api/system/status Get BMC status

OTA Endpoints

Method Endpoint Description
GET /api/ota/status Get OTA status and running partition
POST /api/ota/update Start OTA update from URL
POST /api/ota/upload Upload firmware file directly

Logs Endpoints

Method Endpoint Description
GET /api/logs Get system logs
POST /api/logs/clear Clear system logs

Web Interface

Access the web interface by navigating to http://<ip-address>/ in your browser.

Features:

  • Power control panel with on/off/reset buttons
  • Real-time GPIO monitoring
  • Serial console with WebSocket support
  • System information display
  • OTA firmware update
  • System logs viewer

Example Usage

Power On

curl -X POST http://192.168.1.100/api/power/on

Set GPIO

curl -X POST "http://192.168.1.100/api/gpio/set?pin=18" \
  -H "Content-Type: application/json" \
  -d '{"value": 1}'

Get System Info

curl http://192.168.1.100/api/system/info

Serial Console via WebSocket

const ws = new WebSocket('ws://192.168.1.100/api/serial/ws');
ws.onmessage = (event) => console.log(event.data);
ws.send('command\n');

OTA Firmware Update

# Check OTA status
curl http://192.168.1.100/api/ota/status

# Start OTA update from URL
curl -X POST http://192.168.1.100/api/ota/update \
  -H "Content-Type: application/json" \
  -d '{"url": "http://server/firmware.bin"}'

# Upload firmware file directly
curl -X POST http://192.168.1.100/api/ota/upload \
  -F "firmware=@firmware.bin"

The web interface also supports drag-and-drop firmware upload - simply drag a .bin file onto the upload zone.

Project Structure

esp32-bmc/
├── CMakeLists.txt           # Project CMake configuration
├── partitions.csv           # Partition table for OTA
├── sdkconfig.defaults       # Default SDK configuration
├── .clang-format            # Code formatter configuration
├── main/
│   ├── CMakeLists.txt       # Main component CMake
│   ├── main.c               # Application entry point
│   ├── config.h             # Pin definitions and settings
│   ├── gpio_controller.c/h  # GPIO management
│   ├── uart_handler.c/h     # UART serial communication
│   ├── ethernet_manager.c/h # W5500 Ethernet setup
│   ├── web_server.c/h       # HTTP server and routes
│   ├── ota_handler.c/h      # OTA update handling
│   └── html/
│       └── index.html       # Web interface
└── README.md

Code Quality Tools

This project uses clang-format for code formatting.

clang-format

Format all C source files:

# Format all files in-place
find main -name "*.c" -o -name "*.h" | xargs clang-format -i

# Format a specific file
clang-format -i main/web_server.c

# Check formatting without modifying (dry run)
clang-format --dry-run --Werror main/web_server.c

VS Code Integration

The project includes VS Code settings for automatic formatting on save. Install the following extensions:

  • C/C++ (ms-vscode.cpptools) - IntelliSense and debugging
  • clang-format (xaver.clang-format) - Code formatting
  • ESP-IDF (espressif.esp-idf-extension) - ESP-IDF development

With these extensions installed, code will be automatically formatted when you save files.

Troubleshooting

Ethernet Not Connecting

  1. Check W5500 module connections
  2. Verify SPI pins are correct
  3. Check Ethernet cable and link lights
  4. Monitor serial output for error messages

GPIO Not Working

  1. Verify pin is not input-only (GPIO 35-38 on ESP32-S3)
  2. Check pin is not already used by Ethernet or UART
  3. Ensure proper GPIO mode is set

Serial Console Issues

  1. Verify UART TX/RX connections
  2. Check baud rate matches target board
  3. Ensure WebSocket connection is established

License

MIT License

Contributing

Contributions are welcome! Please submit pull requests or open issues for any improvements.

Description
No description provided
Readme 213 KiB
Languages
C 63.7%
HTML 35.7%
CMake 0.6%