Files
llgo/internal/firmware/firmware.go

115 lines
3.0 KiB
Go
Raw Normal View History

package firmware
import (
"fmt"
"io"
"os"
"strings"
)
// makeFirmwareImage creates a firmware image from the given input file.
func makeFirmwareImage(infile, outfile, format, fmtDetail string) error {
fmt.Fprintf(os.Stderr, "Generating firmware image: %s -> %s (format: %s, detail: %s)\n", infile, outfile, format, fmtDetail)
if strings.HasPrefix(format, "esp") {
return makeESPFirmareImage(infile, outfile, format)
2025-08-23 10:24:18 +08:00
} else if format == "uf2" {
uf2Family := fmtDetail
return convertELFFileToUF2File(infile, outfile, uf2Family)
} else if format == "nrf-dfu" {
return makeDFUFirmwareImage(infile, outfile)
}
return fmt.Errorf("unsupported firmware format: %s", format)
}
// ExtractFileFormatFromCommand extracts file format from command template
2025-09-05 17:47:34 +08:00
// Returns the format if found (e.g. "bin", "hex", "zip", "img"), empty string if not found
func ExtractFileFormatFromCommand(cmd string) string {
2025-09-05 17:47:34 +08:00
formats := []string{"bin", "hex", "zip", "img", "uf2"}
for _, format := range formats {
if strings.Contains(cmd, "{"+format+"}") {
2025-09-05 17:47:34 +08:00
return format
}
}
return ""
}
// ConvertFormats processes format conversions for embedded targets only
func ConvertFormats(binFmt, fmtDetail string, envMap map[string]string) error {
// Convert to bin format first (needed for img)
if envMap["bin"] != "" {
err := makeFirmwareImage(envMap["out"], envMap["bin"], binFmt, fmtDetail)
if err != nil {
return fmt.Errorf("failed to convert to bin format: %w", err)
}
}
// Convert to hex format
if envMap["hex"] != "" {
err := makeFirmwareImage(envMap["out"], envMap["hex"], binFmt, fmtDetail)
if err != nil {
return fmt.Errorf("failed to convert to hex format: %w", err)
}
}
// Convert to img format
if envMap["img"] != "" {
err := makeFirmwareImage(envMap["out"], envMap["img"], binFmt+"-img", fmtDetail)
if err != nil {
return fmt.Errorf("failed to convert to img format: %w", err)
}
}
// Convert to uf2 format
if envMap["uf2"] != "" {
err := makeFirmwareImage(envMap["out"], envMap["uf2"], binFmt, fmtDetail)
if err != nil {
return fmt.Errorf("failed to convert to uf2 format: %w", err)
}
}
// Convert to zip format
if envMap["zip"] != "" {
err := makeFirmwareImage(envMap["out"], envMap["zip"], binFmt, fmtDetail)
if err != nil {
return fmt.Errorf("failed to convert to zip format: %w", err)
}
}
return nil
}
// convertToHex converts binary file to hex format (each byte as two hex characters)
func convertToHex(infile, outfile string) error {
srcFile, err := os.Open(infile)
if err != nil {
return err
}
defer srcFile.Close()
dstFile, err := os.Create(outfile)
if err != nil {
return err
}
defer dstFile.Close()
// Read input file and convert each byte to two hex characters
buf := make([]byte, 4096) // Read in chunks
for {
n, err := srcFile.Read(buf)
if n > 0 {
for i := 0; i < n; i++ {
if _, writeErr := fmt.Fprintf(dstFile, "%02x", buf[i]); writeErr != nil {
return writeErr
}
}
}
if err == io.EOF {
break
}
if err != nil {
return err
}
}
return nil
}