Skip to content

Commit

Permalink
Merge pull request #24 from arduino/retries
Browse files Browse the repository at this point in the history
Added retries flag
  • Loading branch information
cmaglie committed Apr 27, 2021
2 parents 2ed4c0e + b299e0a commit 117385c
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 72 deletions.
35 changes: 28 additions & 7 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"log"
"os"
"strings"
"time"

"github.com/arduino/FirmwareUploader/modules/nina"
"github.com/arduino/FirmwareUploader/modules/sara"
Expand All @@ -28,11 +29,11 @@ func init() {
flag.StringVar(&ctx.ProgrammerPath, "programmer", "", "path of programmer in use (avrdude/bossac)")
flag.StringVar(&ctx.Model, "model", "", "module model (winc, nina or sara)")
flag.StringVar(&ctx.Compatible, "get_available_for", "", "Ask for available firmwares matching a given board")
flag.IntVar(&ctx.Retries, "retries", 9, "Number of retries in case of upload failure")
}

func main() {
flag.Parse()

if ctx.Compatible != "" {
el, _ := json.Marshal(utils.GetCompatibleWith(ctx.Compatible, ""))
fmt.Println(string(el))
Expand All @@ -43,11 +44,31 @@ func main() {
log.Fatal("Please specify a serial port")
}

if ctx.Model == "nina" || strings.Contains(ctx.FirmwareFile, "NINA") || strings.Contains(ctx.FWUploaderBinary, "NINA") {
nina.Run(ctx)
} else if ctx.Model == "winc" || strings.Contains(ctx.FirmwareFile, "WINC") || strings.Contains(ctx.FWUploaderBinary, "WINC") {
winc.Run(ctx)
} else {
sara.Run(ctx)
retry := 0
for {
var ctxCopy context.Context
ctxCopy = *ctx
var err error
if ctx.Model == "nina" || strings.Contains(ctx.FirmwareFile, "NINA") || strings.Contains(ctx.FWUploaderBinary, "NINA") {
err = nina.Run(&ctxCopy)
} else if ctx.Model == "winc" || strings.Contains(ctx.FirmwareFile, "WINC") || strings.Contains(ctx.FWUploaderBinary, "WINC") {
err = winc.Run(&ctxCopy)
} else {
err = sara.Run(&ctxCopy)
}
if err == nil {
log.Println("Operation completed: success! :-)")
break
}
log.Println("Error: " + err.Error())

if retry >= ctx.Retries {
log.Fatal("Operation failed. :-(")
}

retry++
log.Println("Waiting 1 second before retrying...")
time.Sleep(time.Second)
log.Printf("Retrying upload (%d of %d)", retry, ctx.Retries)
}
}
35 changes: 19 additions & 16 deletions modules/nina/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,18 @@ import (
"strconv"
"strings"

"github.com/arduino/FirmwareUploader/programmers/rp2040load"
"github.com/arduino/FirmwareUploader/programmers/avrdude"
"github.com/arduino/FirmwareUploader/programmers/bossac"
"github.com/arduino/FirmwareUploader/programmers/rp2040load"
"github.com/arduino/FirmwareUploader/utils/context"
"github.com/pkg/errors"
)

var flasher *Flasher
var payloadSize uint16
var programmer context.Programmer

func Run(ctx *context.Context) {
func Run(ctx *context.Context) error {

if ctx.ProgrammerPath != "" {
if strings.Contains(filepath.Base(ctx.ProgrammerPath), "bossac") {
Expand All @@ -48,60 +49,61 @@ func Run(ctx *context.Context) {
} else if strings.Contains(filepath.Base(ctx.ProgrammerPath), "rp2040load") {
programmer = rp2040load.NewRP2040Load(ctx)
} else {
log.Fatal("Programmer path not specified correctly, programmer path set to: " + ctx.ProgrammerPath)
return errors.New("Programmer path not specified correctly, programmer path set to: " + ctx.ProgrammerPath)
}
}

if ctx.FWUploaderBinary != "" {
log.Println("Flashing firmware uploader nina")
if programmer == nil {
log.Fatal("ERROR: You must specify a programmer!")
return errors.New("ERROR: You must specify a programmer!")
}
if err := programmer.Flash(ctx.FWUploaderBinary, nil); err != nil {
log.Fatal(err)
return err
}
}

log.Println("Connecting to programmer")
if f, err := OpenFlasher(ctx.PortName); err != nil {
log.Fatal(err)
return err
} else {
flasher = f
}
defer flasher.Close()

// Synchronize with programmer
log.Println("Sync with programmer")
if err := flasher.Hello(); err != nil {
log.Fatal(err)
return err
}

// Check maximum supported payload size
log.Println("Reading max payload size")
if _payloadSize, err := flasher.GetMaximumPayloadSize(); err != nil {
log.Fatal(err)
return err
} else {
payloadSize = _payloadSize
}
if payloadSize < 1024 {
log.Fatalf("Programmer reports %d as maximum payload size (1024 is needed)", payloadSize)
return errors.Errorf("Programmer reports %d as maximum payload size (1024 is needed)", payloadSize)
}

if ctx.FirmwareFile != "" {
if err := flashFirmware(ctx); err != nil {
log.Fatal(err)
return err
}
}

if ctx.RootCertDir != "" || len(ctx.Addresses) != 0 {
if err := flashCerts(ctx); err != nil {
log.Fatal(err)
return err
}
}

if ctx.ReadAll {
log.Println("Reading all flash")
if err := readAllFlash(); err != nil {
log.Fatal(err)
return err
}
}

Expand All @@ -110,18 +112,19 @@ func Run(ctx *context.Context) {
if ctx.BinaryToRestore != "" {
log.Println("Restoring binary")
if programmer == nil {
log.Fatal("ERROR: You must specify a programmer!")
errors.New("ERROR: You must specify a programmer!")
}
if err := programmer.Flash(ctx.BinaryToRestore, nil); err != nil {
log.Fatal(err)
return err
}
}
return nil
}

func readAllFlash() error {
for i := 0; i < 256; i++ {
if data, err := flasher.Read(uint32(i*1024), 1024); err != nil {
log.Fatal(err)
return err
} else {
os.Stdout.Write(data)
}
Expand All @@ -142,7 +145,7 @@ func flashCerts(ctx *context.Context) error {
}

if len(certificatesData) > 0x20000 {
log.Fatal("Too many certificates! Aborting")
errors.New("Too many certificates! Aborting")
}

// pad certificatesData to flash page
Expand Down
7 changes: 3 additions & 4 deletions modules/sara/flasher.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,9 @@ type Flasher struct {
}

func (flasher *Flasher) Hello() error {

f.Expect("ATE0", "OK", 100)
f.Expect("ATE0", "OK", 100)
f.Expect("ATE0", "OK", 100)
flasher.Expect("ATE0", "OK", 100)
flasher.Expect("ATE0", "OK", 100)
flasher.Expect("ATE0", "OK", 100)
_, err := flasher.Expect("AT", "OK", 100)
return err
}
Expand Down
49 changes: 26 additions & 23 deletions modules/sara/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,48 +21,50 @@ package sara

import (
"fmt"
"github.com/arduino/FirmwareUploader/programmers/bossac"
"github.com/arduino/FirmwareUploader/utils/context"
"io/ioutil"
"log"
"strconv"
"time"

"github.com/arduino/FirmwareUploader/programmers/bossac"
"github.com/arduino/FirmwareUploader/utils/context"
)

var f *Flasher
var flasher *Flasher
var payloadSize uint16
var programmer context.Programmer

func Run(ctx *context.Context) {
func Run(ctx *context.Context) error {
programmer := bossac.NewBossac(ctx)

if ctx.FWUploaderBinary != "" {
log.Println("Flashing firmware uploader sara")
if err := programmer.Flash(ctx.FWUploaderBinary, nil); err != nil {
log.Fatal(err)
return err
}
}

log.Println("Connecting to programmer")
if _f, err := OpenFlasher(ctx.PortName); err != nil {
log.Fatal(err)
if f, err := OpenFlasher(ctx.PortName); err != nil {
return err
} else {
f = _f
flasher = f
}
defer flasher.Close()

time.Sleep(2 * time.Second)

// Synchronize with programmer
log.Println("Sync with programmer")
if err := f.Hello(); err != nil {
log.Fatal(err)
if err := flasher.Hello(); err != nil {
return err
}

// Check maximum supported payload size
log.Println("Reading actual firmware version")

if fwVersion, err := f.GetFwVersion(); err != nil {
log.Fatal(err)
if fwVersion, err := flasher.GetFwVersion(); err != nil {
return err
} else {
log.Println("Initial firmware version: " + fwVersion)
}
Expand All @@ -71,25 +73,26 @@ func Run(ctx *context.Context) {

if ctx.FirmwareFile != "" {
if err := flashFirmware(ctx); err != nil {
log.Fatal(err)
return err
}
}

if fwVersion, err := f.GetFwVersion(); err != nil {
log.Fatal(err)
if fwVersion, err := flasher.GetFwVersion(); err != nil {
return err
} else {
log.Println("After applying update firmware version: " + fwVersion)
}

f.Close()
flasher.Close()

if ctx.BinaryToRestore != "" {
log.Println("Restoring previous sketch")

if err := programmer.Flash(ctx.BinaryToRestore, nil); err != nil {
log.Fatal(err)
return err
}
}
return nil
}

func flashFirmware(ctx *context.Context) error {
Expand All @@ -102,12 +105,12 @@ func flashFirmware(ctx *context.Context) error {
return err
}

_, err = f.Expect("AT+ULSTFILE", "+ULSTFILE:", 1000)
_, err = flasher.Expect("AT+ULSTFILE", "+ULSTFILE:", 1000)
if err != nil {
return err
}

_, err = f.Expect("AT+UDWNFILE=\"UPDATE.BIN\","+strconv.Itoa(len(fwData))+",\"FOAT\"", ">", 20000)
_, err = flasher.Expect("AT+UDWNFILE=\"UPDATE.BIN\","+strconv.Itoa(len(fwData))+",\"FOAT\"", ">", 20000)
if err != nil {
return err
}
Expand All @@ -119,12 +122,12 @@ func flashFirmware(ctx *context.Context) error {

time.Sleep(1 * time.Second)

_, err = f.Expect("", "OK", 1000)
_, err = flasher.Expect("", "OK", 1000)
if err != nil {
return err
}

_, err = f.Expect("AT+UFWINSTALL", "OK", 60000)
_, err = flasher.Expect("AT+UFWINSTALL", "OK", 60000)
if err != nil {
return err
}
Expand All @@ -134,7 +137,7 @@ func flashFirmware(ctx *context.Context) error {
// wait up to 20 minutes trying to ping the module. After 20 minutes signal the error
start := time.Now()
for time.Since(start) < time.Minute*20 {
err = f.Hello()
err = flasher.Hello()
if err == nil {
return nil
}
Expand All @@ -154,7 +157,7 @@ func flashChunk(offset int, buffer []byte) error {
if end > bufferLength {
end = bufferLength
}
if err := f.Write(uint32(offset+i), buffer[start:end]); err != nil {
if err := flasher.Write(uint32(offset+i), buffer[start:end]); err != nil {
return err
}
//time.Sleep(1 * time.Millisecond)
Expand Down

0 comments on commit 117385c

Please sign in to comment.