Bench configs define command and console serial paths; scenarios can reset nodes via esptool before tests. Smoke resets all nodes then waits for ESP-NOW join. Co-authored-by: Cursor <cursoragent@cursor.com>
104 lines
2.5 KiB
Go
104 lines
2.5 KiB
Go
package autotest
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"time"
|
|
)
|
|
|
|
const defaultResetWaitMS = 2000
|
|
|
|
// ResetESP32 toggles EN via esptool (USB-JTAG / ttyACM console port).
|
|
func ResetESP32(port string) error {
|
|
if port == "" {
|
|
return fmt.Errorf("empty console port")
|
|
}
|
|
|
|
tries := [][]string{
|
|
{"python", "-m", "esptool", "--chip", "esp32s3", "-p", port,
|
|
"--before", "default_reset", "--after", "hard_reset", "chip_id"},
|
|
{"esptool.py", "--chip", "esp32s3", "-p", port,
|
|
"--before", "default_reset", "--after", "hard_reset", "chip_id"},
|
|
{"esptool", "--chip", "esp32s3", "-p", port,
|
|
"--before", "default_reset", "--after", "hard_reset", "chip_id"},
|
|
}
|
|
|
|
var lastErr error
|
|
for _, argv := range tries {
|
|
if _, err := exec.LookPath(argv[0]); err != nil {
|
|
lastErr = err
|
|
continue
|
|
}
|
|
cmd := exec.Command(argv[0], argv[1:]...)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
if err := cmd.Run(); err != nil {
|
|
lastErr = err
|
|
continue
|
|
}
|
|
return nil
|
|
}
|
|
if lastErr != nil {
|
|
return fmt.Errorf("esptool reset on %s: %w (install ESP-IDF esptool or python -m esptool)", port, lastErr)
|
|
}
|
|
return fmt.Errorf("esptool not found; cannot reset %s", port)
|
|
}
|
|
|
|
func (b *Bench) resetNode(target string) (string, error) {
|
|
switch target {
|
|
case "master", "":
|
|
if b.UART.MasterConsole == "" {
|
|
return "", fmt.Errorf("uart.master_console not set in config %q", b.ID)
|
|
}
|
|
return b.UART.MasterConsole, nil
|
|
default:
|
|
s, err := b.Slave(target)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if s.Console == "" {
|
|
return "", fmt.Errorf("slave %q has no console port in config", target)
|
|
}
|
|
return s.Console, nil
|
|
}
|
|
}
|
|
|
|
func (b *Bench) ResetTargets(targets []string, waitMS int) error {
|
|
if waitMS <= 0 {
|
|
waitMS = defaultResetWaitMS
|
|
}
|
|
if len(targets) == 0 {
|
|
targets = []string{"master"}
|
|
}
|
|
|
|
for _, t := range targets {
|
|
port, err := b.resetNode(t)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := ResetESP32(port); err != nil {
|
|
return err
|
|
}
|
|
time.Sleep(time.Duration(waitMS) * time.Millisecond)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (b *Bench) ResetAll(waitMS int) error {
|
|
// Slaves first, master last — master discover runs after slaves are booting.
|
|
var targets []string
|
|
for i := range b.Slaves {
|
|
if b.Slaves[i].Console != "" {
|
|
targets = append(targets, b.Slaves[i].ID)
|
|
}
|
|
}
|
|
if b.UART.MasterConsole != "" {
|
|
targets = append(targets, "master")
|
|
}
|
|
if len(targets) == 0 {
|
|
return fmt.Errorf("config %q: no console ports defined for reset", b.ID)
|
|
}
|
|
return b.ResetTargets(targets, waitMS)
|
|
}
|