Add mass deployment system with static IP and WiFi configuration

- Add static IP configuration via Kconfig
- Add WiFi console command for runtime reconfiguration
- Add mass flash script for automated deployment
- Add device detection script
- Add comprehensive deployment documentation
This commit is contained in:
Bob 2025-11-08 23:10:07 +00:00
parent b9a4a7c45e
commit 49dc6962ba
5 changed files with 900 additions and 1 deletions

363
MASS_DEPLOY.md Normal file
View File

@ -0,0 +1,363 @@
# Mass ESP32 Deployment Guide
Complete guide for flashing 32+ ESP32 devices with unique static IPs.
## Overview
This system allows you to:
- Flash multiple ESP32/ESP32-S2/ESP32-S3 devices automatically
- Assign unique static IP addresses to each device (192.168.1.50-192.168.1.81)
- Configure WiFi credentials during build
- Reconfigure WiFi after flashing via console
## Prerequisites
```bash
# Install Python dependencies
pip install pyserial
# Ensure ESP-IDF is installed with all targets
cd ~/Code/esp32/esp-idf
./install.sh esp32,esp32s2,esp32s3
# Activate ESP-IDF environment
. ~/Code/esp32/esp-idf/export.sh
```
## Method 1: Automated Mass Flash (Recommended)
### Prepare Your Devices
1. Connect all ESP32 devices to USB hubs
2. Verify detection:
```bash
cd ~/Code/esp32/esp32-iperf
python3 detect_esp32.py
```
### Flash All Devices
```bash
cd ~/Code/esp32/esp32-iperf
# Dry run to see the plan
python3 flash_all.py \
--ssid "YourWiFiSSID" \
--password "YourPassword" \
--start-ip 192.168.1.50 \
--gateway 192.168.1.1 \
--dry-run
# Actually flash (this will take a while!)
python3 flash_all.py \
--ssid "YourWiFiSSID" \
--password "YourPassword" \
--start-ip 192.168.1.50 \
--gateway 192.168.1.1
# With chip probing (slower but more accurate)
python3 flash_all.py \
--ssid "YourWiFiSSID" \
--password "YourPassword" \
--start-ip 192.168.1.50 \
--probe
```
### Script Options
- `--ssid`: WiFi network name (required)
- `--password`: WiFi password (required)
- `--start-ip`: Starting IP address (default: 192.168.1.50)
- `--gateway`: Gateway IP (default: 192.168.1.1)
- `--probe`: Probe each device to detect exact chip type (slower)
- `--dry-run`: Show plan without flashing
- `--project-dir`: Custom project directory
### What the Script Does
For each device:
1. Detects chip type (ESP32/ESP32-S2/ESP32-S3)
2. Calculates unique IP address (increments from start IP)
3. Creates custom sdkconfig.defaults with WiFi and IP settings
4. Sets the correct target (esp32/esp32s2/esp32s3)
5. Builds firmware with custom configuration
6. Flashes the device
## Method 2: Manual Configuration Per Device
If you want to flash devices one at a time or need custom settings:
### Create sdkconfig.defaults
```bash
cd ~/Code/esp32/esp32-iperf
cat > sdkconfig.defaults << EOF
# WiFi Configuration
CONFIG_WIFI_SSID="YourSSID"
CONFIG_WIFI_PASSWORD="YourPassword"
CONFIG_WIFI_MAXIMUM_RETRY=5
# Static IP Configuration
CONFIG_USE_STATIC_IP=y
CONFIG_STATIC_IP_ADDR="192.168.1.50"
CONFIG_STATIC_GATEWAY_ADDR="192.168.1.1"
CONFIG_STATIC_NETMASK_ADDR="255.255.255.0"
EOF
```
### Build and Flash
```bash
# Set target (choose one)
idf.py set-target esp32 # for ESP32
idf.py set-target esp32s2 # for ESP32-S2
idf.py set-target esp32s3 # for ESP32-S3
# Build
idf.py build
# Flash to specific device
idf.py -p /dev/ttyUSB0 flash monitor
# For next device, edit sdkconfig.defaults with new IP
# Then clean and rebuild
idf.py fullclean
# ... edit sdkconfig.defaults ...
idf.py build
idf.py -p /dev/ttyUSB1 flash
```
## Method 3: Reconfigure After Flashing
If devices are already flashed but need different WiFi credentials:
### Via Console
```bash
# Connect to device
idf.py -p /dev/ttyUSB0 monitor
# At the prompt
iperf> wifi -s "NewSSID" -p "NewPassword"
```
### Via Script (Multiple Devices)
Create a script to update all devices:
```bash
#!/bin/bash
for port in /dev/ttyUSB{0..31}; do
echo "Updating $port..."
# Send commands via screen or minicom
screen -S esp_config $port 115200 -X stuff "wifi -s \"NewSSID\" -p \"NewPassword\"\n"
done
```
## IP Address Assignment
Based on your 32 detected devices:
```
Device 1 -> /dev/ttyUSB0 -> 192.168.1.50
Device 2 -> /dev/ttyUSB1 -> 192.168.1.51
Device 3 -> /dev/ttyUSB2 -> 192.168.1.52
...
Device 32 -> /dev/ttyUSB31 -> 192.168.1.81
```
## Testing Your Deployment
### Check Device Connectivity
```bash
# Ping all devices
for i in {50..81}; do
ping -c 1 -W 1 192.168.1.$i && echo "192.168.1.$i is UP" || echo "192.168.1.$i is DOWN"
done
```
### Run iperf Tests
```bash
# Start all devices as iperf servers
# (via console on each device)
iperf> iperf -s
# From your PC, test each device
for i in {50..81}; do
echo "Testing 192.168.1.$i"
iperf -c 192.168.1.$i -t 5
done
```
### Batch iperf Test Script
```python
#!/usr/bin/env python3
import subprocess
import sys
start_ip = "192.168.1.50"
end_ip = "192.168.1.81"
base = start_ip.rsplit('.', 1)[0]
start = int(start_ip.rsplit('.', 1)[1])
end = int(end_ip.rsplit('.', 1)[1])
results = []
for i in range(start, end + 1):
ip = f"{base}.{i}"
print(f"Testing {ip}...", end=' ', flush=True)
result = subprocess.run(
['iperf', '-c', ip, '-t', '5', '-f', 'm'],
capture_output=True,
text=True,
timeout=10
)
if result.returncode == 0:
# Parse bandwidth from output
for line in result.stdout.split('\n'):
if 'Mbits/sec' in line:
bandwidth = line.split()[-2]
print(f"✓ {bandwidth} Mbits/sec")
results.append((ip, bandwidth))
break
else:
print("✗ FAILED")
print(f"\nTested {len(results)}/{end-start+1} devices successfully")
```
## Troubleshooting
### Device Not Detected
```bash
# Check USB connection
lsusb
# Check permissions
sudo usermod -a -G dialout $USER
# Log out and back in
# Check if port exists
ls -la /dev/ttyUSB*
```
### Flash Failed
```bash
# Try holding BOOT button during flash
idf.py -p /dev/ttyUSB0 flash
# Lower baud rate
idf.py -p /dev/ttyUSB0 -b 115200 flash
# Erase flash first
idf.py -p /dev/ttyUSB0 erase-flash
idf.py -p /dev/ttyUSB0 flash
```
### WiFi Not Connecting
```bash
# Monitor the device
idf.py -p /dev/ttyUSB0 monitor
# Check logs for WiFi errors
# Try reconfiguring via console:
iperf> wifi -s "YourSSID" -p "YourPassword"
```
### IP Address Conflict
```bash
# Check what's using the IP
ping 192.168.1.50
arp -a | grep 192.168.1.50
# Reflash with different IP range
python3 flash_all.py \
--ssid "YourSSID" \
--password "YourPassword" \
--start-ip 192.168.1.100
```
## Console Commands Reference
### WiFi Configuration
```
wifi -s <ssid> -p <password>
```
### iperf Commands
```bash
# TCP server
iperf -s
# TCP client
iperf -c <ip>
# UDP server
iperf -s -u
# UDP client
iperf -c <ip> -u
# Custom port
iperf -s -p 5002
# Custom duration
iperf -c <ip> -t 30
# Stop running test
iperf -a
```
## Advanced: Parallel Flashing
To flash multiple devices simultaneously:
```bash
#!/bin/bash
# flash_parallel.sh
# Flash 4 devices at once
idf.py -p /dev/ttyUSB0 flash &
idf.py -p /dev/ttyUSB1 flash &
idf.py -p /dev/ttyUSB2 flash &
idf.py -p /dev/ttyUSB3 flash &
wait
echo "Batch complete"
```
Note: Each device still needs its own build with unique IP.
## Production Deployment Workflow
1. **Prepare**: Connect all devices, verify detection
2. **Flash**: Run mass flash script with dry-run first
3. **Verify**: Ping all IPs to confirm connectivity
4. **Test**: Run iperf from PC to each device
5. **Deploy**: Mount devices in test locations
6. **Monitor**: Use iperf console to run tests
## File Structure
```
esp32-iperf/
├── main/
│ ├── main.c # Main app with WiFi
│ ├── iperf.c # iperf implementation
│ ├── iperf.h # iperf header
│ └── Kconfig.projbuild # Configuration options
├── CMakeLists.txt
├── README.md
├── flash_all.py # Mass flash script
├── detect_esp32.py # Device detection
└── sdkconfig.defaults # Auto-generated config
```

115
detect_esp32.py Executable file
View File

@ -0,0 +1,115 @@
#!/usr/bin/env python3
"""
ESP32 USB Device Detection Script
Detects and lists ESP32 devices connected via USB
"""
import serial.tools.list_ports
def detect_esp32_devices():
"""
Detect ESP32 devices connected via USB.
Returns a list of tuples containing (port, description, hwid)
"""
esp32_devices = []
# Common USB vendor IDs used by ESP32 boards
ESP32_VID_PIDS = [
('10C4', 'EA60'), # Silicon Labs CP210x
('1A86', '7523'), # CH340
('1A86', '55D4'), # CH9102
('0403', '6001'), # FTDI FT232
('0403', '6010'), # FTDI FT2232
('303A', '1001'), # Espressif USB JTAG/serial debug unit (ESP32-C3, ESP32-S3)
('303A', '1002'), # Espressif USB JTAG/serial debug unit
]
# Keywords that might appear in ESP32 device descriptions
ESP32_KEYWORDS = [
'CP210',
'CH340',
'CH9102',
'UART',
'USB-SERIAL',
'USB SERIAL',
'JTAG',
'ESP32',
]
# Get all available ports
ports = serial.tools.list_ports.comports()
for port in ports:
# Check by VID:PID
if port.vid is not None and port.pid is not None:
vid = f"{port.vid:04X}"
pid = f"{port.pid:04X}"
if any((vid == v and pid == p) for v, p in ESP32_VID_PIDS):
esp32_devices.append(port)
continue
# Check by description keywords
description_upper = port.description.upper()
if any(keyword in description_upper for keyword in ESP32_KEYWORDS):
esp32_devices.append(port)
return esp32_devices
def main():
print("=" * 60)
print("ESP32 USB Device Detection")
print("=" * 60)
print()
# Detect ESP32 devices
esp32_devices = detect_esp32_devices()
if esp32_devices:
print(f"Found {len(esp32_devices)} ESP32 device(s):\n")
for idx, device in enumerate(esp32_devices, 1):
print(f"Device {idx}:")
print(f" Port: {device.device}")
print(f" Description: {device.description}")
print(f" Hardware ID: {device.hwid}")
if device.vid is not None and device.pid is not None:
print(f" VID:PID: {device.vid:04X}:{device.pid:04X}")
if device.manufacturer:
print(f" Manufacturer: {device.manufacturer}")
if device.serial_number:
print(f" Serial: {device.serial_number}")
print()
print("=" * 60)
print(f"Total ESP32 devices detected: {len(esp32_devices)}")
print("=" * 60)
else:
print("No ESP32 devices detected.")
print()
print("Available USB serial devices:")
all_ports = serial.tools.list_ports.comports()
if all_ports:
for port in all_ports:
print(f" - {port.device}: {port.description}")
if port.vid is not None and port.pid is not None:
print(f" VID:PID = {port.vid:04X}:{port.pid:04X}")
else:
print(" No USB serial devices found.")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\nDetection interrupted by user.")
except Exception as e:
print(f"\nError: {e}")
print("\nMake sure pyserial is installed: pip install pyserial")

308
flash_all.py Executable file
View File

@ -0,0 +1,308 @@
#!/usr/bin/env python3
"""
ESP32 Mass Flash Script
Automatically detects, configures, and flashes multiple ESP32 devices with unique IPs
"""
import subprocess
import sys
import os
import time
import argparse
from pathlib import Path
# Import the detection script
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
try:
import detect_esp32
except ImportError:
print("Error: detect_esp32.py must be in the same directory")
sys.exit(1)
# Device type detection based on USB chip
def detect_device_type(port_info):
"""
Try to detect ESP32 variant based on USB chip and other heuristics.
Returns: 'esp32', 'esp32s2', 'esp32s3', or 'unknown'
"""
# Espressif's own USB JTAG is used in ESP32-C3 and ESP32-S3
if port_info.vid == 0x303A:
if port_info.pid == 0x1001:
return 'esp32s3' # Most likely S3
return 'esp32s3' # Default to S3 for Espressif USB
# For FTDI and CP210x, we need to probe the chip
# Default assumption based on quantity in your setup
# You may need to adjust this logic
return 'esp32' # Default to ESP32 for FTDI/CP210x
def probe_chip_type(port):
"""
Probe the actual chip type using esptool.py
"""
try:
result = subprocess.run(
['esptool.py', '--port', port, 'chip_id'],
capture_output=True,
text=True,
timeout=10
)
output = result.stdout + result.stderr
if 'ESP32-S3' in output:
return 'esp32s3'
elif 'ESP32-S2' in output:
return 'esp32s2'
elif 'ESP32-C3' in output:
return 'esp32c3'
elif 'ESP32' in output:
return 'esp32'
except Exception as e:
print(f" Warning: Could not probe {port}: {e}")
return 'unknown'
def create_sdkconfig(project_dir, ssid, password, ip_addr, gateway='192.168.1.1', netmask='255.255.255.0'):
"""
Create sdkconfig.defaults file with WiFi and IP configuration
"""
sdkconfig_path = os.path.join(project_dir, 'sdkconfig.defaults')
config_content = f"""# WiFi Configuration
CONFIG_WIFI_SSID="{ssid}"
CONFIG_WIFI_PASSWORD="{password}"
CONFIG_WIFI_MAXIMUM_RETRY=5
# Static IP Configuration
CONFIG_USE_STATIC_IP=y
CONFIG_STATIC_IP_ADDR="{ip_addr}"
CONFIG_STATIC_GATEWAY_ADDR="{gateway}"
CONFIG_STATIC_NETMASK_ADDR="{netmask}"
"""
with open(sdkconfig_path, 'w') as f:
f.write(config_content)
print(f" Created sdkconfig.defaults with IP {ip_addr}")
def flash_device(port, chip_type, device_num, ssid, password, base_ip, project_dir):
"""
Configure and flash a single device
"""
print(f"\n{'='*60}")
print(f"Device {device_num}: {port} ({chip_type})")
print(f"{'='*60}")
# Calculate IP address
base_parts = base_ip.split('.')
ip_last_octet = int(base_parts[3]) + device_num - 1
if ip_last_octet > 254:
print(f" ERROR: IP address overflow! Device {device_num} would exceed .254")
return False
ip_addr = f"{base_parts[0]}.{base_parts[1]}.{base_parts[2]}.{ip_last_octet}"
print(f" Assigned IP: {ip_addr}")
# Create sdkconfig.defaults
create_sdkconfig(project_dir, ssid, password, ip_addr)
# Clean previous build if target changed
print(" Cleaning previous build...")
subprocess.run(['idf.py', 'fullclean'], cwd=project_dir,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# Set target
print(f" Setting target to {chip_type}...")
result = subprocess.run(
['idf.py', 'set-target', chip_type],
cwd=project_dir,
capture_output=True,
text=True
)
if result.returncode != 0:
print(f" ERROR: Failed to set target: {result.stderr}")
return False
# Build
print(f" Building for {chip_type}...")
result = subprocess.run(
['idf.py', 'build'],
cwd=project_dir,
capture_output=True,
text=True
)
if result.returncode != 0:
print(f" ERROR: Build failed!")
print(result.stderr[-1000:]) # Print last 1000 chars of error
return False
print(f" Build successful!")
# Flash
print(f" Flashing to {port}...")
result = subprocess.run(
['idf.py', '-p', port, 'flash'],
cwd=project_dir,
capture_output=True,
text=True
)
if result.returncode != 0:
print(f" ERROR: Flash failed!")
print(result.stderr[-1000:])
return False
print(f" ✓ Successfully flashed device {device_num} at {ip_addr}")
return True
def main():
parser = argparse.ArgumentParser(description='Mass flash ESP32 devices with unique IPs')
parser.add_argument('--ssid', required=True, help='WiFi SSID')
parser.add_argument('--password', required=True, help='WiFi password')
parser.add_argument('--start-ip', default='192.168.1.50',
help='Starting IP address (default: 192.168.1.50)')
parser.add_argument('--gateway', default='192.168.1.1',
help='Gateway IP (default: 192.168.1.1)')
parser.add_argument('--project-dir', default=None,
help='ESP32 iperf project directory')
parser.add_argument('--probe', action='store_true',
help='Probe each device to detect exact chip type (slower)')
parser.add_argument('--dry-run', action='store_true',
help='Show what would be done without flashing')
args = parser.parse_args()
# Find project directory
if args.project_dir:
project_dir = args.project_dir
else:
# Try to find it relative to script location
script_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.join(script_dir, 'esp32-iperf')
if not os.path.exists(project_dir):
project_dir = os.path.join(os.path.expanduser('~/Code/esp32'), 'esp32-iperf')
if not os.path.exists(project_dir):
print(f"ERROR: Project directory not found: {project_dir}")
print("Please specify --project-dir")
sys.exit(1)
print(f"Using project directory: {project_dir}")
# Detect devices
print("\nDetecting ESP32 devices...")
devices = detect_esp32.detect_esp32_devices()
if not devices:
print("No ESP32 devices detected!")
sys.exit(1)
print(f"Found {len(devices)} device(s)")
# Detect chip types
device_list = []
for idx, device in enumerate(devices, 1):
if args.probe:
print(f"Probing {device.device}...")
chip_type = probe_chip_type(device.device)
else:
chip_type = detect_device_type(device)
device_list.append({
'number': idx,
'port': device.device,
'chip': chip_type,
'info': device
})
# Display plan
print(f"\n{'='*60}")
print("FLASH PLAN")
print(f"{'='*60}")
print(f"SSID: {args.ssid}")
print(f"Starting IP: {args.start_ip}")
print(f"Gateway: {args.gateway}")
print()
base_parts = args.start_ip.split('.')
for dev in device_list:
ip_last = int(base_parts[3]) + dev['number'] - 1
ip = f"{base_parts[0]}.{base_parts[1]}.{base_parts[2]}.{ip_last}"
print(f"Device {dev['number']:2d}: {dev['port']} -> {dev['chip']:8s} -> {ip}")
if args.dry_run:
print("\nDry run - no devices will be flashed")
return
# Confirm
print(f"\n{'='*60}")
response = input("Proceed with flashing? (yes/no): ").strip().lower()
if response != 'yes':
print("Aborted.")
return
# Flash devices
success_count = 0
failed_devices = []
for dev in device_list:
try:
success = flash_device(
dev['port'],
dev['chip'],
dev['number'],
args.ssid,
args.password,
args.start_ip,
project_dir
)
if success:
success_count += 1
else:
failed_devices.append(dev['number'])
time.sleep(1) # Brief pause between devices
except KeyboardInterrupt:
print("\n\nFlashing interrupted by user!")
break
except Exception as e:
print(f"\n ERROR: Exception during flash: {e}")
failed_devices.append(dev['number'])
# Summary
print(f"\n{'='*60}")
print("FLASH SUMMARY")
print(f"{'='*60}")
print(f"Successfully flashed: {success_count}/{len(device_list)} devices")
if failed_devices:
print(f"Failed devices: {', '.join(map(str, failed_devices))}")
print(f"{'='*60}")
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print("\n\nInterrupted by user")
sys.exit(1)
except Exception as e:
print(f"\nFATAL ERROR: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

View File

@ -18,4 +18,31 @@ menu "ESP32 iperf Configuration"
help help
Set the Maximum retry to prevent station reconnecting to the AP unlimited when the AP doesn't exist. Set the Maximum retry to prevent station reconnecting to the AP unlimited when the AP doesn't exist.
config USE_STATIC_IP
bool "Use static IP address"
default n
help
Enable static IP address configuration instead of DHCP.
config STATIC_IP_ADDR
string "Static IP address"
default "192.168.1.50"
depends on USE_STATIC_IP
help
Static IP address for this device.
config STATIC_GATEWAY_ADDR
string "Gateway address"
default "192.168.1.1"
depends on USE_STATIC_IP
help
Gateway IP address.
config STATIC_NETMASK_ADDR
string "Netmask"
default "255.255.255.0"
depends on USE_STATIC_IP
help
Netmask for the network.
endmenu endmenu

View File

@ -54,7 +54,24 @@ void wifi_init_sta(void)
ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
#ifdef CONFIG_USE_STATIC_IP
// Configure static IP
ESP_LOGI(TAG, "Configuring static IP: %s", CONFIG_STATIC_IP_ADDR);
esp_netif_dhcpc_stop(sta_netif);
esp_netif_ip_info_t ip_info;
memset(&ip_info, 0, sizeof(esp_netif_ip_info_t));
ip_info.ip.addr = ipaddr_addr(CONFIG_STATIC_IP_ADDR);
ip_info.gw.addr = ipaddr_addr(CONFIG_STATIC_GATEWAY_ADDR);
ip_info.netmask.addr = ipaddr_addr(CONFIG_STATIC_NETMASK_ADDR);
ESP_ERROR_CHECK(esp_netif_set_ip_info(sta_netif, &ip_info));
#endif
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg)); ESP_ERROR_CHECK(esp_wifi_init(&cfg));
@ -114,6 +131,74 @@ static struct {
struct arg_end *end; struct arg_end *end;
} iperf_args; } iperf_args;
/* Console command structure for wifi config */
static struct {
struct arg_str *ssid;
struct arg_str *password;
struct arg_end *end;
} wifi_args;
static int cmd_wifi(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **)&wifi_args);
if (nerrors != 0) {
arg_print_errors(stderr, wifi_args.end, argv[0]);
return 1;
}
if (wifi_args.ssid->count == 0) {
ESP_LOGE(TAG, "Please provide SSID with -s option");
return 1;
}
wifi_config_t wifi_config;
memset(&wifi_config, 0, sizeof(wifi_config_t));
// Set SSID
strncpy((char *)wifi_config.sta.ssid, wifi_args.ssid->sval[0], sizeof(wifi_config.sta.ssid) - 1);
// Set password if provided
if (wifi_args.password->count > 0) {
strncpy((char *)wifi_config.sta.password, wifi_args.password->sval[0], sizeof(wifi_config.sta.password) - 1);
wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
}
ESP_LOGI(TAG, "Updating WiFi configuration...");
ESP_LOGI(TAG, "SSID: %s", wifi_config.sta.ssid);
// Stop WiFi
esp_wifi_disconnect();
esp_wifi_stop();
// Update config
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
// Restart WiFi
ESP_ERROR_CHECK(esp_wifi_start());
esp_wifi_connect();
ESP_LOGI(TAG, "WiFi configuration updated. Attempting to connect...");
return 0;
}
static void register_wifi(void)
{
wifi_args.ssid = arg_str1("s", "ssid", "<ssid>", "WiFi SSID");
wifi_args.password = arg_str0("p", "password", "<password>", "WiFi password");
wifi_args.end = arg_end(1);
const esp_console_cmd_t wifi_cmd = {
.command = "wifi",
.help = "Configure WiFi credentials (wifi -s <ssid> -p <password>)",
.hint = NULL,
.func = &cmd_wifi,
.argtable = &wifi_args
};
ESP_ERROR_CHECK(esp_console_cmd_register(&wifi_cmd));
}
static int cmd_iperf(int argc, char **argv) static int cmd_iperf(int argc, char **argv)
{ {
int nerrors = arg_parse(argc, argv, (void **)&iperf_args); int nerrors = arg_parse(argc, argv, (void **)&iperf_args);
@ -215,6 +300,7 @@ static void initialize_console(void)
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl)); ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
register_iperf(); register_iperf();
register_wifi();
ESP_ERROR_CHECK(esp_console_start_repl(repl)); ESP_ERROR_CHECK(esp_console_start_repl(repl));
} }