ESP32-S3 firmware acting as BMC for another board, controlling an ATX power supply and providing access to UART. Co-authored with GLM-5
8.6 KiB
8.6 KiB
ESP32-S3 BMC Firmware Plan
Overview
This project creates a Baseboard Management Controller (BMC) firmware for ESP32-S3 that provides remote management capabilities for an external board via Ethernet.
Framework Decision: ESP-IDF
Selected Framework: ESP-IDF (Espressif IoT Development Framework)
Rationale:
- Native W5500 SPI Ethernet driver support
- Excellent HTTP server performance with
esp_http_server - FreeRTOS enables efficient multitasking for concurrent operations
- Production-ready with long-term support
- Good balance between development speed and performance
System Architecture
flowchart TB
subgraph ESP32-S3
subgraph Software
WEB[HTTP Web Server]
API[REST API Handler]
GPIO[GPIO Controller]
UART[UART Serial Module]
ETH[Ethernet Manager - W5500]
NET[Network Stack - LwIP]
end
subgraph Hardware
SPI[SPI Bus]
GP_IO[GPIO Pins 8-16]
UART_HW[UART Hardware]
end
end
subgraph External
CLIENT[Web Browser Client]
BOARD[Target Board]
W5500[W5500 Ethernet Module]
end
CLIENT -->|HTTP| WEB
WEB --> API
API --> GPIO
API --> UART
GPIO --> GP_IO --> BOARD
UART --> UART_HW --> BOARD
ETH --> SPI --> W5500
NET --> ETH
Project Structure
esp32-bmc/
├── CMakeLists.txt
├── sdkconfig.defaults
├── main/
│ ├── CMakeLists.txt
│ ├── main.c # Application entry point
│ ├── gpio_controller.c # GPIO management
│ ├── gpio_controller.h
│ ├── uart_handler.c # UART serial communication
│ ├── uart_handler.h
│ ├── ethernet_manager.c # W5500 Ethernet setup
│ ├── ethernet_manager.h
│ ├── web_server.c # HTTP server and routes
│ ├── web_server.h
│ └── html/
│ └── index.html # Embedded web interface
├── components/
│ └── w5500/ # W5500 driver component if needed
├── include/
│ └── config.h # Pin definitions and settings
└── docs/
└── README.md
Hardware Configuration
Pin Assignments (ESP32-S3)
| Function | GPIO Pin | Description |
|---|---|---|
| SPI for W5500 | ||
| MOSI | GPIO 11 | SPI MOSI |
| MISO | GPIO 13 | SPI MISO |
| SCLK | GPIO 12 | SPI Clock |
| CS | GPIO 10 | Chip Select |
| RST | GPIO 9 | W5500 Reset |
| INT | GPIO 14 | W5500 Interrupt |
| UART Serial | ||
| TX | GPIO 43 | UART0 TX to target board |
| RX | GPIO 44 | UART0 RX from target board |
| BMC GPIOs | ||
| POWER_ON | GPIO 4 | Power control output |
| POWER_OFF | GPIO 5 | Power control output |
| RESET | GPIO 6 | Reset control output |
| STATUS_LED | GPIO 7 | Status LED output |
| PWR_GOOD | GPIO 15 | Power good input |
| TEMP_ALERT | GPIO 16 | Temperature alert input |
| FAN_CTRL | GPIO 17 | Fan control PWM |
| USER_GPIO_1-8 | GPIO 18-25 | User configurable GPIOs |
REST API Endpoints
GPIO Control
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/gpio |
Get all GPIO states |
| GET | /api/gpio/{pin} |
Get specific GPIO state |
| POST | /api/gpio/{pin} |
Set GPIO state |
| PUT | /api/gpio/{pin}/config |
Configure GPIO mode |
Example Request/Response:
// GET /api/gpio
{
"gpios": [
{"pin": 4, "name": "POWER_ON", "mode": "output", "value": 1},
{"pin": 5, "name": "POWER_OFF", "mode": "output", "value": 0},
{"pin": 15, "name": "PWR_GOOD", "mode": "input", "value": 1}
]
}
// POST /api/gpio/4
// Request body:
{"value": 1}
// Response:
{"success": true, "pin": 4, "value": 1}
Power Control
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/power/on |
Turn board power on |
| POST | /api/power/off |
Turn board power off |
| POST | /api/power/reset |
Reset the board |
| GET | /api/power/status |
Get power status |
Serial Console
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/serial |
WebSocket for serial console |
| POST | /api/serial/send |
Send data to serial |
| GET | /api/serial/config |
Get serial configuration |
| PUT | /api/serial/config |
Configure serial settings |
System
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/system/info |
Get system information |
| GET | /api/system/status |
Get BMC status |
Web Interface
A simple HTML/CSS dashboard will be embedded in the firmware providing:
- Power Control Panel - Buttons for power on/off/reset with status indicators
- GPIO Monitor - Real-time display of GPIO states
- Serial Console - Web-based terminal for serial communication
- System Info - Display BMC status and network information
flowchart LR
subgraph Web Interface
PWR[Power Control Panel]
GPIO[GPIO Monitor]
SER[Serial Console]
SYS[System Info]
end
PWR -->|REST API| API[REST Endpoints]
GPIO -->|REST API| API
SER -->|WebSocket| WS[Serial Bridge]
SYS -->|REST API| API
Implementation Details
1. Ethernet Manager (W5500)
The W5500 will be configured using SPI interface:
// Key configuration steps
1. Initialize SPI driver
2. Configure W5500 MAC address
3. Set up DHCP client or static IP
4. Handle network events (connect/disconnect)
5. Register network callbacks
2. GPIO Controller
// GPIO configuration structure
typedef struct {
gpio_num_t pin;
const char* name;
gpio_mode_t mode;
int default_value;
bool inverted; // For active-low signals
} bmc_gpio_config_t;
// Functions
void gpio_controller_init(void);
int gpio_read(gpio_num_t pin);
esp_err_t gpio_write(gpio_num_t pin, int value);
esp_err_t gpio_configure(gpio_num_t pin, gpio_mode_t mode);
3. UART Handler
// UART configuration
#define UART_NUM UART_NUM_1
#define UART_BAUD_RATE 115200
#define UART_BUF_SIZE 2048
// Functions
void uart_handler_init(void);
int uart_read_bytes(uint8_t* buf, size_t len);
int uart_write_bytes(const uint8_t* buf, size_t len);
4. Web Server
Using esp_http_server component:
// Server setup
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
// Register URI handlers
httpd_register_uri_handler(server, &gpio_get_uri);
httpd_register_uri_handler(server, &gpio_post_uri);
httpd_register_uri_handler(server, &power_on_uri);
httpd_register_uri_handler(server, &serial_ws_uri);
5. Serial WebSocket Bridge
The serial endpoint will use WebSocket for bidirectional communication:
sequenceDiagram
participant Browser
participant WebSocket
participant UART Buffer
participant Target Board
Browser->>WebSocket: Connect to /api/serial
WebSocket->>UART Buffer: Start reading task
loop Serial Data
Target Board->>UART Buffer: Serial data
UART Buffer->>WebSocket: Data available
WebSocket->>Browser: Send data frame
end
Browser->>WebSocket: Send command
WebSocket->>Target Board: Write to UART
Configuration Options
The firmware will support configuration via sdkconfig and a runtime config file:
| Option | Default | Description |
|---|---|---|
| BMC_ETHERNET_DHCP | true | Use DHCP for IP |
| BMC_STATIC_IP | 192.168.1.100 | Static IP if DHCP disabled |
| BMC_NETMASK | 255.255.255.0 | Network mask |
| BMC_GATEWAY | 192.168.1.1 | Default gateway |
| BMC_HTTP_PORT | 80 | Web server port |
| BMC_UART_BAUD | 115200 | Serial baud rate |
| BMC_GPIO_COUNT | 16 | Number of GPIOs to manage |
Development Phases
Phase 1: Core Infrastructure
- Initialize ESP-IDF project
- Set up W5500 Ethernet connectivity
- Basic GPIO read/write functionality
Phase 2: Web Server
- Implement HTTP server
- Create REST API endpoints for GPIO
- Add power control endpoints
Phase 3: Serial Console
- Implement UART handler
- Create WebSocket bridge
- Add serial configuration endpoints
Phase 4: Web Interface
- Design and implement HTML/CSS dashboard
- Embed files in firmware
- Add JavaScript for dynamic updates
Phase 5: Polish and Testing
- Error handling and recovery
- Documentation
- Testing on hardware
Dependencies
- ESP-IDF v5.0+
- esp_http_server component
- driver component (SPI, GPIO, UART)
- lwIP stack
Next Steps
- Initialize the ESP-IDF project structure
- Configure W5500 SPI Ethernet
- Implement GPIO controller module
- Build and test incrementally