From c0afe199c22bba60412f00392845107fab8f57d6 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Sun, 7 Sep 2025 10:06:01 +0800 Subject: [PATCH] refactor: move device types definition into flash --- cmd/internal/monitor/monitor.go | 2 +- internal/build/build.go | 8 +-- internal/build/outputs.go | 8 +-- internal/build/outputs_test.go | 81 +++++++++++++++++---------- internal/crosscompile/crosscompile.go | 59 +++++++------------ internal/flash/flash.go | 52 +++++++++++++---- 6 files changed, 118 insertions(+), 92 deletions(-) diff --git a/cmd/internal/monitor/monitor.go b/cmd/internal/monitor/monitor.go index af7bab30..6c5bd5af 100644 --- a/cmd/internal/monitor/monitor.go +++ b/cmd/internal/monitor/monitor.go @@ -59,7 +59,7 @@ func runMonitor(cmd *base.Command, args []string) { fmt.Fprintf(os.Stderr, "llgo monitor: %v\n", err) os.Exit(1) } - serialPort = conf.Flash.SerialPort + serialPort = conf.Device.SerialPort } config := monitor.MonitorConfig{ diff --git a/internal/build/build.go b/internal/build/build.go index 68242e55..05451b20 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -344,7 +344,7 @@ func Do(args []string, conf *Config) ([]Package, error) { case ModeInstall: // Native already installed in linkMainPkg if conf.Target != "" { - err = flash.Flash(ctx.crossCompile, finalApp, ctx.buildConf.Port, verbose) + err = flash.FlashDevice(ctx.crossCompile.Device, finalApp, ctx.buildConf.Port, verbose) if err != nil { return nil, err } @@ -356,7 +356,7 @@ func Do(args []string, conf *Config) ([]Package, error) { } else if conf.Emulator { err = runInEmulator(ctx.crossCompile.Emulator, finalApp, pkg.Dir, pkg.PkgPath, conf, mode, verbose) } else { - err = flash.Flash(ctx.crossCompile, finalApp, ctx.buildConf.Port, verbose) + err = flash.FlashDevice(ctx.crossCompile.Device, finalApp, ctx.buildConf.Port, verbose) if err != nil { return nil, err } @@ -365,9 +365,7 @@ func Do(args []string, conf *Config) ([]Package, error) { Target: conf.Target, Executable: finalApp, BaudRate: conf.BaudRate, - } - if ctx.crossCompile.Flash.Method != "openocd" { - monitorConfig.SerialPort = ctx.crossCompile.Flash.SerialPort + SerialPort: ctx.crossCompile.Device.SerialPort, } err = monitor.Monitor(monitorConfig, verbose) } diff --git a/internal/build/outputs.go b/internal/build/outputs.go index 0eaa2e6f..d00c0e63 100644 --- a/internal/build/outputs.go +++ b/internal/build/outputs.go @@ -84,11 +84,11 @@ func determineFlashFormat(crossCompile *crosscompile.Export) string { return "" } - flashMethod := crossCompile.Flash.Method + flashMethod := crossCompile.Device.Flash.Method switch flashMethod { case "command", "": // Extract format from flash command tokens - flashCommand := crossCompile.Flash.Command + flashCommand := crossCompile.Device.Flash.Command switch { case strings.Contains(flashCommand, "{hex}"): return ".hex" @@ -106,10 +106,10 @@ func determineFlashFormat(crossCompile *crosscompile.Export) string { return "" } case "msd": - if crossCompile.MSD.FirmwareName == "" { + if crossCompile.Device.MSD.FirmwareName == "" { return "" } - return filepath.Ext(crossCompile.MSD.FirmwareName) + return filepath.Ext(crossCompile.Device.MSD.FirmwareName) case "openocd": return ".hex" case "bmp": diff --git a/internal/build/outputs_test.go b/internal/build/outputs_test.go index c37638dd..5f5a528f 100644 --- a/internal/build/outputs_test.go +++ b/internal/build/outputs_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/goplus/llgo/internal/crosscompile" + "github.com/goplus/llgo/internal/flash" ) func TestGenOutputs(t *testing.T) { @@ -315,9 +316,11 @@ func TestGenOutputs(t *testing.T) { pkgName: "hello", crossCompile: &crosscompile.Export{ BinaryFormat: "esp32", - Flash: crosscompile.Flash{ - Method: "command", - Command: "esptool.py --chip esp32 write_flash 0x10000 {hex}", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "command", + Command: "esptool.py --chip esp32 write_flash 0x10000 {hex}", + }, }, }, wantOutPath: "", // temp file @@ -336,9 +339,11 @@ func TestGenOutputs(t *testing.T) { pkgName: "hello", crossCompile: &crosscompile.Export{ BinaryFormat: "esp32", - Flash: crosscompile.Flash{ - Method: "command", - Command: "esptool.py --chip esp32 write_flash 0x10000 {bin}", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "command", + Command: "esptool.py --chip esp32 write_flash 0x10000 {bin}", + }, }, }, wantOutPath: "", // temp file @@ -357,8 +362,10 @@ func TestGenOutputs(t *testing.T) { pkgName: "hello", crossCompile: &crosscompile.Export{ BinaryFormat: "arm", - Flash: crosscompile.Flash{ - Method: "openocd", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "openocd", + }, }, }, wantOutPath: "", // temp file @@ -377,11 +384,13 @@ func TestGenOutputs(t *testing.T) { pkgName: "hello", crossCompile: &crosscompile.Export{ BinaryFormat: "uf2", - Flash: crosscompile.Flash{ - Method: "msd", - }, - MSD: crosscompile.MSD{ - FirmwareName: "firmware.uf2", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "msd", + }, + MSD: flash.MSD{ + FirmwareName: "firmware.uf2", + }, }, }, wantOutPath: "", // temp file @@ -400,8 +409,10 @@ func TestGenOutputs(t *testing.T) { pkgName: "hello", crossCompile: &crosscompile.Export{ BinaryFormat: "arm", - Flash: crosscompile.Flash{ - Method: "bmp", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "bmp", + }, }, }, wantOutPath: "", // temp file @@ -510,9 +521,11 @@ func TestDetermineFormat(t *testing.T) { name: "flash method command - extract hex", conf: &Config{Mode: ModeRun, Target: "esp32"}, crossCompile: &crosscompile.Export{ - Flash: crosscompile.Flash{ - Method: "command", - Command: "esptool.py --chip esp32 write_flash 0x10000 {hex}", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "command", + Command: "esptool.py --chip esp32 write_flash 0x10000 {hex}", + }, }, }, wantFmt: "hex", @@ -522,9 +535,11 @@ func TestDetermineFormat(t *testing.T) { name: "flash method command - extract bin", conf: &Config{Mode: ModeRun, Target: "esp32"}, crossCompile: &crosscompile.Export{ - Flash: crosscompile.Flash{ - Method: "command", - Command: "esptool.py --chip esp32 write_flash 0x10000 {bin}", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "command", + Command: "esptool.py --chip esp32 write_flash 0x10000 {bin}", + }, }, }, wantFmt: "bin", @@ -534,8 +549,10 @@ func TestDetermineFormat(t *testing.T) { name: "flash method openocd", conf: &Config{Mode: ModeRun, Target: "stm32"}, crossCompile: &crosscompile.Export{ - Flash: crosscompile.Flash{ - Method: "openocd", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "openocd", + }, }, }, wantFmt: "hex", @@ -545,11 +562,13 @@ func TestDetermineFormat(t *testing.T) { name: "flash method msd - extract from firmware name", conf: &Config{Mode: ModeRun, Target: "rp2040"}, crossCompile: &crosscompile.Export{ - Flash: crosscompile.Flash{ - Method: "msd", - }, - MSD: crosscompile.MSD{ - FirmwareName: "firmware.uf2", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "msd", + }, + MSD: flash.MSD{ + FirmwareName: "firmware.uf2", + }, }, }, wantFmt: "uf2", @@ -559,8 +578,10 @@ func TestDetermineFormat(t *testing.T) { name: "flash method bmp", conf: &Config{Mode: ModeRun, Target: "stm32"}, crossCompile: &crosscompile.Export{ - Flash: crosscompile.Flash{ - Method: "bmp", + Device: flash.Device{ + Flash: flash.Flash{ + Method: "bmp", + }, }, }, wantFmt: "elf", diff --git a/internal/crosscompile/crosscompile.go b/internal/crosscompile/crosscompile.go index 9da1cf98..d22624e5 100644 --- a/internal/crosscompile/crosscompile.go +++ b/internal/crosscompile/crosscompile.go @@ -12,32 +12,11 @@ import ( "github.com/goplus/llgo/internal/crosscompile/compile" "github.com/goplus/llgo/internal/env" + "github.com/goplus/llgo/internal/flash" "github.com/goplus/llgo/internal/targets" "github.com/goplus/llgo/internal/xtool/llvm" ) -// Flash contains configuration for device flashing -type Flash struct { - Method string // Flash method: "command", "openocd", "msd", "bmp" - Command string // Flash command template - Serial string // Serial communication settings - SerialPort []string // Available serial ports - Flash1200BpsReset bool // Whether to use 1200bps reset -} - -// MSD contains configuration for Mass Storage Device flashing -type MSD struct { - VolumeName []string // Names of the volumes - FirmwareName string // Firmware file name pattern -} - -// OpenOCD contains configuration for OpenOCD debugging/flashing -type OpenOCD struct { - Interface string // Interface configuration (e.g., "stlink") - Transport string // Transport protocol (e.g., "swd", "jtag") - Target string // Target configuration (e.g., "stm32f4x") -} - type Export struct { CC string // Compiler to use CCFLAGS []string @@ -59,9 +38,7 @@ type Export struct { Emulator string // Emulator command template (e.g., "qemu-system-arm -M {} -kernel {}") // Flashing/Debugging configuration - Flash Flash // Flash configuration for device programming - MSD MSD // Mass Storage Device configuration - OpenOCD OpenOCD // OpenOCD configuration for debugging/flashing + Device flash.Device // Device configuration for flashing/debugging } // URLs and configuration that can be overridden for testing @@ -530,21 +507,23 @@ func UseTarget(targetName string) (export Export, err error) { export.Emulator = config.Emulator // Set flashing/debugging configuration - export.Flash = Flash{ - Method: config.FlashMethod, - Command: config.FlashCommand, - Serial: config.Serial, - SerialPort: config.SerialPort, - Flash1200BpsReset: config.Flash1200BpsReset == "true", - } - export.MSD = MSD{ - VolumeName: config.MSDVolumeName, - FirmwareName: config.MSDFirmwareName, - } - export.OpenOCD = OpenOCD{ - Interface: config.OpenOCDInterface, - Transport: config.OpenOCDTransport, - Target: config.OpenOCDTarget, + export.Device = flash.Device{ + Serial: config.Serial, + SerialPort: config.SerialPort, + Flash: flash.Flash{ + Method: config.FlashMethod, + Command: config.FlashCommand, + Flash1200BpsReset: config.Flash1200BpsReset == "true", + }, + MSD: flash.MSD{ + VolumeName: config.MSDVolumeName, + FirmwareName: config.MSDFirmwareName, + }, + OpenOCD: flash.OpenOCD{ + Interface: config.OpenOCDInterface, + Transport: config.OpenOCDTransport, + Target: config.OpenOCDTarget, + }, } // Build environment map for template variable expansion diff --git a/internal/flash/flash.go b/internal/flash/flash.go index 68b75e1a..5d20b029 100644 --- a/internal/flash/flash.go +++ b/internal/flash/flash.go @@ -11,12 +11,40 @@ import ( "strings" "time" - "github.com/goplus/llgo/internal/crosscompile" "github.com/goplus/llgo/internal/env" "go.bug.st/serial" "go.bug.st/serial/enumerator" ) +// Device contains all flashing/debugging configuration for a device +type Device struct { + Serial string // Serial communication settings + SerialPort []string // Available serial ports + Flash Flash // Flash configuration for device programming + MSD MSD // Mass Storage Device configuration + OpenOCD OpenOCD // OpenOCD configuration for debugging/flashing +} + +// Flash contains configuration for device flashing +type Flash struct { + Method string // Flash method: "command", "openocd", "msd", "bmp" + Command string // Flash command template + Flash1200BpsReset bool // Whether to use 1200bps reset +} + +// MSD contains configuration for Mass Storage Device flashing +type MSD struct { + VolumeName []string // Names of the volumes + FirmwareName string // Firmware file name pattern +} + +// OpenOCD contains configuration for OpenOCD debugging/flashing +type OpenOCD struct { + Interface string // Interface configuration (e.g., "stlink") + Transport string // Transport protocol (e.g., "swd", "jtag") + Target string // Target configuration (e.g., "stm32f4x") +} + // From tinygo/main.go getDefaultPort // GetPort returns the default serial port depending on the operating system and USB interfaces. func GetPort(portFlag string, usbInterfaces []string) (string, error) { @@ -163,9 +191,9 @@ func touchSerialPortAt1200bps(port string) (err error) { return fmt.Errorf("opening port: %s", err) } -// Flash flashes firmware to a device based on the crosscompile configuration -func Flash(crossCompile crosscompile.Export, app string, port string, verbose bool) error { - method := crossCompile.Flash.Method +// FlashDevice flashes firmware to a device based on the device configuration +func FlashDevice(device Device, app string, port string, verbose bool) error { + method := device.Flash.Method if method == "" { method = "command" } @@ -173,7 +201,7 @@ func Flash(crossCompile crosscompile.Export, app string, port string, verbose bo // Resolve port for methods that need it (all except openocd) if method != "openocd" { var err error - port, err = GetPort(port, crossCompile.Flash.SerialPort) + port, err = GetPort(port, device.SerialPort) if err != nil { return fmt.Errorf("failed to find port: %w", err) } @@ -185,7 +213,7 @@ func Flash(crossCompile crosscompile.Export, app string, port string, verbose bo } // Execute 1200bps reset before flashing if needed (except for openocd) - if method != "openocd" && crossCompile.Flash.Flash1200BpsReset { + if method != "openocd" && device.Flash.Flash1200BpsReset { if verbose { fmt.Fprintf(os.Stderr, "Triggering 1200bps reset on port: %s\n", port) } @@ -198,11 +226,11 @@ func Flash(crossCompile crosscompile.Export, app string, port string, verbose bo switch method { case "command": - return flashCommand(crossCompile.Flash, app, port, verbose) + return flashCommand(device.Flash, app, port, verbose) case "openocd": - return flashOpenOCD(crossCompile.OpenOCD, app, verbose) + return flashOpenOCD(device.OpenOCD, app, verbose) case "msd": - return flashMSD(crossCompile.MSD, app, verbose) + return flashMSD(device.MSD, app, verbose) case "bmp": return flashBMP(app, verbose) default: @@ -211,7 +239,7 @@ func Flash(crossCompile crosscompile.Export, app string, port string, verbose bo } // flashCommand handles command-based flashing -func flashCommand(flash crosscompile.Flash, app string, port string, verbose bool) error { +func flashCommand(flash Flash, app string, port string, verbose bool) error { if flash.Command == "" { return fmt.Errorf("flash command not specified") } @@ -241,7 +269,7 @@ func flashCommand(flash crosscompile.Flash, app string, port string, verbose boo } // flashOpenOCD handles OpenOCD-based flashing -func flashOpenOCD(openocd crosscompile.OpenOCD, app string, verbose bool) error { +func flashOpenOCD(openocd OpenOCD, app string, verbose bool) error { if openocd.Interface == "" { return fmt.Errorf("OpenOCD interface not specified") } @@ -279,7 +307,7 @@ func flashOpenOCD(openocd crosscompile.OpenOCD, app string, verbose bool) error } // flashMSD handles Mass Storage Device flashing -func flashMSD(msd crosscompile.MSD, app string, verbose bool) error { +func flashMSD(msd MSD, app string, verbose bool) error { if len(msd.VolumeName) == 0 { return fmt.Errorf("MSD volume names not specified") }