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:
- Run
idf.py menuconfig - Navigate to "BMC Configuration"
- 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 |
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
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
- Check W5500 module connections
- Verify SPI pins are correct
- Check Ethernet cable and link lights
- Monitor serial output for error messages
GPIO Not Working
- Verify pin is not input-only (GPIO 35-38 on ESP32-S3)
- Check pin is not already used by Ethernet or UART
- Ensure proper GPIO mode is set
Serial Console Issues
- Verify UART TX/RX connections
- Check baud rate matches target board
- Ensure WebSocket connection is established
License
MIT License
Contributing
Contributions are welcome! Please submit pull requests or open issues for any improvements.