Skip to content

Commit f29abe7

Browse files
committed
Added retries flag, that defaults to 2 (3 tries in total)
1 parent 5ce5279 commit f29abe7

File tree

5 files changed

+75
-45
lines changed

5 files changed

+75
-45
lines changed

Diff for: main.go

+28-7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"log"
88
"os"
99
"strings"
10+
"time"
1011

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

3335
func main() {
3436
flag.Parse()
35-
3637
if ctx.Compatible != "" {
3738
el, _ := json.Marshal(utils.GetCompatibleWith(ctx.Compatible, ""))
3839
fmt.Println(string(el))
@@ -43,11 +44,31 @@ func main() {
4344
log.Fatal("Please specify a serial port")
4445
}
4546

46-
if ctx.Model == "nina" || strings.Contains(ctx.FirmwareFile, "NINA") || strings.Contains(ctx.FWUploaderBinary, "NINA") {
47-
nina.Run(ctx)
48-
} else if ctx.Model == "winc" || strings.Contains(ctx.FirmwareFile, "WINC") || strings.Contains(ctx.FWUploaderBinary, "WINC") {
49-
winc.Run(ctx)
50-
} else {
51-
sara.Run(ctx)
47+
retry := 0
48+
for {
49+
var ctxCopy context.Context
50+
ctxCopy = *ctx
51+
var err error
52+
if ctx.Model == "nina" || strings.Contains(ctx.FirmwareFile, "NINA") || strings.Contains(ctx.FWUploaderBinary, "NINA") {
53+
err = nina.Run(&ctxCopy)
54+
} else if ctx.Model == "winc" || strings.Contains(ctx.FirmwareFile, "WINC") || strings.Contains(ctx.FWUploaderBinary, "WINC") {
55+
err = winc.Run(&ctxCopy)
56+
} else {
57+
err = sara.Run(&ctxCopy)
58+
}
59+
if err == nil {
60+
log.Println("Operation completed: success! :-)")
61+
break
62+
}
63+
log.Println("Error: " + err.Error())
64+
65+
if retry >= ctx.Retries {
66+
log.Fatal("Operation failed. :-(")
67+
}
68+
69+
retry++
70+
log.Println("Waiting 1 second before retrying...")
71+
time.Sleep(time.Second)
72+
log.Printf("Retrying upload (%d of %d)", retry, ctx.Retries)
5273
}
5374
}

Diff for: modules/nina/main.go

+19-16
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,18 @@ import (
2828
"strconv"
2929
"strings"
3030

31-
"github.com/arduino/FirmwareUploader/programmers/rp2040load"
3231
"github.com/arduino/FirmwareUploader/programmers/avrdude"
3332
"github.com/arduino/FirmwareUploader/programmers/bossac"
33+
"github.com/arduino/FirmwareUploader/programmers/rp2040load"
3434
"github.com/arduino/FirmwareUploader/utils/context"
35+
"github.com/pkg/errors"
3536
)
3637

3738
var flasher *Flasher
3839
var payloadSize uint16
3940
var programmer context.Programmer
4041

41-
func Run(ctx *context.Context) {
42+
func Run(ctx *context.Context) error {
4243

4344
if ctx.ProgrammerPath != "" {
4445
if strings.Contains(filepath.Base(ctx.ProgrammerPath), "bossac") {
@@ -48,60 +49,61 @@ func Run(ctx *context.Context) {
4849
} else if strings.Contains(filepath.Base(ctx.ProgrammerPath), "rp2040load") {
4950
programmer = rp2040load.NewRP2040Load(ctx)
5051
} else {
51-
log.Fatal("Programmer path not specified correctly, programmer path set to: " + ctx.ProgrammerPath)
52+
return errors.New("Programmer path not specified correctly, programmer path set to: " + ctx.ProgrammerPath)
5253
}
5354
}
5455

5556
if ctx.FWUploaderBinary != "" {
5657
log.Println("Flashing firmware uploader nina")
5758
if programmer == nil {
58-
log.Fatal("ERROR: You must specify a programmer!")
59+
return errors.New("ERROR: You must specify a programmer!")
5960
}
6061
if err := programmer.Flash(ctx.FWUploaderBinary, nil); err != nil {
61-
log.Fatal(err)
62+
return err
6263
}
6364
}
6465

6566
log.Println("Connecting to programmer")
6667
if f, err := OpenFlasher(ctx.PortName); err != nil {
67-
log.Fatal(err)
68+
return err
6869
} else {
6970
flasher = f
7071
}
72+
defer flasher.Close()
7173

7274
// Synchronize with programmer
7375
log.Println("Sync with programmer")
7476
if err := flasher.Hello(); err != nil {
75-
log.Fatal(err)
77+
return err
7678
}
7779

7880
// Check maximum supported payload size
7981
log.Println("Reading max payload size")
8082
if _payloadSize, err := flasher.GetMaximumPayloadSize(); err != nil {
81-
log.Fatal(err)
83+
return err
8284
} else {
8385
payloadSize = _payloadSize
8486
}
8587
if payloadSize < 1024 {
86-
log.Fatalf("Programmer reports %d as maximum payload size (1024 is needed)", payloadSize)
88+
return errors.Errorf("Programmer reports %d as maximum payload size (1024 is needed)", payloadSize)
8789
}
8890

8991
if ctx.FirmwareFile != "" {
9092
if err := flashFirmware(ctx); err != nil {
91-
log.Fatal(err)
93+
return err
9294
}
9395
}
9496

9597
if ctx.RootCertDir != "" || len(ctx.Addresses) != 0 {
9698
if err := flashCerts(ctx); err != nil {
97-
log.Fatal(err)
99+
return err
98100
}
99101
}
100102

101103
if ctx.ReadAll {
102104
log.Println("Reading all flash")
103105
if err := readAllFlash(); err != nil {
104-
log.Fatal(err)
106+
return err
105107
}
106108
}
107109

@@ -110,18 +112,19 @@ func Run(ctx *context.Context) {
110112
if ctx.BinaryToRestore != "" {
111113
log.Println("Restoring binary")
112114
if programmer == nil {
113-
log.Fatal("ERROR: You must specify a programmer!")
115+
errors.New("ERROR: You must specify a programmer!")
114116
}
115117
if err := programmer.Flash(ctx.BinaryToRestore, nil); err != nil {
116-
log.Fatal(err)
118+
return err
117119
}
118120
}
121+
return nil
119122
}
120123

121124
func readAllFlash() error {
122125
for i := 0; i < 256; i++ {
123126
if data, err := flasher.Read(uint32(i*1024), 1024); err != nil {
124-
log.Fatal(err)
127+
return err
125128
} else {
126129
os.Stdout.Write(data)
127130
}
@@ -142,7 +145,7 @@ func flashCerts(ctx *context.Context) error {
142145
}
143146

144147
if len(certificatesData) > 0x20000 {
145-
log.Fatal("Too many certificates! Aborting")
148+
errors.New("Too many certificates! Aborting")
146149
}
147150

148151
// pad certificatesData to flash page

Diff for: modules/sara/main.go

+13-10
Original file line numberDiff line numberDiff line change
@@ -21,48 +21,50 @@ package sara
2121

2222
import (
2323
"fmt"
24-
"github.com/arduino/FirmwareUploader/programmers/bossac"
25-
"github.com/arduino/FirmwareUploader/utils/context"
2624
"io/ioutil"
2725
"log"
2826
"strconv"
2927
"time"
28+
29+
"github.com/arduino/FirmwareUploader/programmers/bossac"
30+
"github.com/arduino/FirmwareUploader/utils/context"
3031
)
3132

3233
var f *Flasher
3334
var payloadSize uint16
3435
var programmer context.Programmer
3536

36-
func Run(ctx *context.Context) {
37+
func Run(ctx *context.Context) error {
3738
programmer := bossac.NewBossac(ctx)
3839

3940
if ctx.FWUploaderBinary != "" {
4041
log.Println("Flashing firmware uploader sara")
4142
if err := programmer.Flash(ctx.FWUploaderBinary, nil); err != nil {
42-
log.Fatal(err)
43+
return err
4344
}
4445
}
4546

4647
log.Println("Connecting to programmer")
4748
if _f, err := OpenFlasher(ctx.PortName); err != nil {
48-
log.Fatal(err)
49+
return err
4950
} else {
5051
f = _f
5152
}
53+
defer f.Close()
5254

5355
time.Sleep(2 * time.Second)
5456

5557
// Synchronize with programmer
5658
log.Println("Sync with programmer")
5759
if err := f.Hello(); err != nil {
58-
log.Fatal(err)
60+
return err
5961
}
6062

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

6466
if fwVersion, err := f.GetFwVersion(); err != nil {
65-
log.Fatal(err)
67+
return err
6668
} else {
6769
log.Println("Initial firmware version: " + fwVersion)
6870
}
@@ -71,12 +73,12 @@ func Run(ctx *context.Context) {
7173

7274
if ctx.FirmwareFile != "" {
7375
if err := flashFirmware(ctx); err != nil {
74-
log.Fatal(err)
76+
return err
7577
}
7678
}
7779

7880
if fwVersion, err := f.GetFwVersion(); err != nil {
79-
log.Fatal(err)
81+
return err
8082
} else {
8183
log.Println("After applying update firmware version: " + fwVersion)
8284
}
@@ -87,9 +89,10 @@ func Run(ctx *context.Context) {
8789
log.Println("Restoring previous sketch")
8890

8991
if err := programmer.Flash(ctx.BinaryToRestore, nil); err != nil {
90-
log.Fatal(err)
92+
return err
9193
}
9294
}
95+
return nil
9396
}
9497

9598
func flashFirmware(ctx *context.Context) error {

Diff for: modules/winc/main.go

+14-12
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ package winc
2121

2222
import (
2323
"bytes"
24-
"errors"
2524
"fmt"
2625
"io/ioutil"
2726
"log"
@@ -30,63 +29,65 @@ import (
3029

3130
"github.com/arduino/FirmwareUploader/programmers/bossac"
3231
"github.com/arduino/FirmwareUploader/utils/context"
32+
"github.com/pkg/errors"
3333
)
3434

3535
var f *Flasher
3636
var payloadSize uint16
3737

38-
func Run(ctx *context.Context) {
38+
func Run(ctx *context.Context) error {
3939

4040
programmer := bossac.NewBossac(ctx)
4141

4242
if ctx.FWUploaderBinary != "" {
4343
log.Println("Flashing firmware uploader winc")
4444
if err := programmer.Flash(ctx.FWUploaderBinary, nil); err != nil {
45-
log.Fatal(err)
45+
return err
4646
}
4747
}
4848

4949
log.Println("Connecting to programmer")
5050
if _f, err := OpenFlasher(ctx.PortName); err != nil {
51-
log.Fatal(err)
51+
return err
5252
} else {
5353
f = _f
5454
}
55+
defer f.Close()
5556

5657
// Synchronize with programmer
5758
log.Println("Sync with programmer")
5859
if err := f.Hello(); err != nil {
59-
log.Fatal(err)
60+
return err
6061
}
6162

6263
// Check maximum supported payload size
6364
log.Println("Reading max payload size")
6465
_payloadSize, err := f.GetMaximumPayloadSize()
6566
if err != nil {
66-
log.Fatal(err)
67+
return err
6768
} else {
6869
payloadSize = _payloadSize
6970
}
7071
if payloadSize < 1024 {
71-
log.Fatalf("Programmer reports %d as maximum payload size (1024 is needed)", payloadSize)
72+
return errors.Errorf("Programmer reports %d as maximum payload size (1024 is needed)", payloadSize)
7273
}
7374

7475
if ctx.FirmwareFile != "" {
7576
if err := flashFirmware(ctx); err != nil {
76-
log.Fatal(err)
77+
return err
7778
}
7879
}
7980

8081
if ctx.RootCertDir != "" || len(ctx.Addresses) != 0 {
8182
if err := flashCerts(ctx); err != nil {
82-
log.Fatal(err)
83+
return err
8384
}
8485
}
8586

8687
if ctx.ReadAll {
8788
log.Println("Reading all flash")
8889
if err := readAllFlash(); err != nil {
89-
log.Fatal(err)
90+
return err
9091
}
9192
}
9293

@@ -96,15 +97,16 @@ func Run(ctx *context.Context) {
9697
log.Println("Restoring previous sketch")
9798

9899
if err := programmer.Flash(ctx.BinaryToRestore, nil); err != nil {
99-
log.Fatal(err)
100+
return err
100101
}
101102
}
103+
return nil
102104
}
103105

104106
func readAllFlash() error {
105107
for i := 0; i < 256; i++ {
106108
if data, err := f.Read(uint32(i*1024), 1024); err != nil {
107-
log.Fatal(err)
109+
return err
108110
} else {
109111
os.Stdout.Write(data)
110112
}

Diff for: utils/context/context.go

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type Context struct {
2828
ProgrammerPath string
2929
Model string
3030
Compatible string
31+
Retries int
3132
}
3233

3334
type Programmer interface {

0 commit comments

Comments
 (0)