Skip to content

Commit 0458d99

Browse files
committed
Implemented burn-bootloader
1 parent 7d90781 commit 0458d99

File tree

4 files changed

+125
-55
lines changed

4 files changed

+125
-55
lines changed

cli/upload/upload.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@ import (
3131
)
3232

3333
var (
34-
fqbn string
35-
port string
36-
verbose bool
37-
verify bool
38-
importDir string
39-
programmer string
34+
fqbn string
35+
port string
36+
verbose bool
37+
verify bool
38+
importDir string
39+
programmer string
40+
burnBootloader bool
4041
)
4142

4243
// NewCommand created a new `upload` command
@@ -56,6 +57,7 @@ func NewCommand() *cobra.Command {
5657
uploadCommand.Flags().BoolVarP(&verify, "verify", "t", false, "Verify uploaded binary after the upload.")
5758
uploadCommand.Flags().BoolVarP(&verbose, "verbose", "v", false, "Optional, turns on verbose mode.")
5859
uploadCommand.Flags().StringVarP(&programmer, "programmer", "P", "", "Optional, use the specified programmer to upload or 'list' to list supported programmers.")
60+
uploadCommand.Flags().BoolVar(&burnBootloader, "burn-bootloader", false, "Burn bootloader (some platforms performs chip-erase too).")
5961

6062
return uploadCommand
6163
}
@@ -88,6 +90,24 @@ func run(command *cobra.Command, args []string) {
8890
}
8991
sketchPath := initSketchPath(path)
9092

93+
if burnBootloader {
94+
if _, err := upload.Upload(context.Background(), &rpc.UploadReq{
95+
Instance: instance,
96+
Fqbn: fqbn,
97+
SketchPath: sketchPath.String(),
98+
Port: port,
99+
Verbose: verbose,
100+
Verify: verify,
101+
ImportDir: importDir,
102+
Programmer: programmer,
103+
BurnBootloader: true,
104+
}, os.Stdout, os.Stderr); err != nil {
105+
feedback.Errorf("Error during Upload: %v", err)
106+
os.Exit(errorcodes.ErrGeneric)
107+
}
108+
os.Exit(0)
109+
}
110+
91111
if _, err := upload.Upload(context.Background(), &rpc.UploadReq{
92112
Instance: instance,
93113
Fqbn: fqbn,

commands/upload/upload.go

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
5151
return nil, fmt.Errorf("opening sketch: %s", err)
5252
}
5353

54+
if req.GetBurnBootloader() && req.GetProgrammer() == "" {
55+
return nil, fmt.Errorf("no programmer specified for burning bootloader")
56+
}
57+
5458
// FIXME: make a specification on how a port is specified via command line
5559
port := req.GetPort()
5660
if port == "" && sketch != nil && sketch.Metadata != nil {
@@ -90,6 +94,16 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
9094
var uploadToolName string
9195
var uploadToolPlatform *cores.PlatformRelease
9296
var programmer *cores.Programmer
97+
98+
burnBootloader := req.GetBurnBootloader()
99+
if burnBootloader {
100+
uploadToolName = boardProperties.Get("bootloader.tool")
101+
uploadToolPlatform = boardPlatform
102+
if uploadToolName == "" {
103+
return nil, fmt.Errorf("cannot get programmer tool: undefined 'bootloader.tool' in boards.txt")
104+
}
105+
}
106+
93107
if programmerID := req.GetProgrammer(); programmerID != "" {
94108
programmer = boardPlatform.Programmers[programmerID]
95109
if programmer == nil {
@@ -153,13 +167,25 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
153167
if v, ok := uploadProperties.GetOk("program.params.verbose"); ok {
154168
uploadProperties.Set("program.verbose", v)
155169
}
170+
if v, ok := uploadProperties.GetOk("erase.params.verbose"); ok {
171+
uploadProperties.Set("erase.verbose", v)
172+
}
173+
if v, ok := uploadProperties.GetOk("bootloader.params.verbose"); ok {
174+
uploadProperties.Set("bootloader.verbose", v)
175+
}
156176
} else {
157177
if v, ok := uploadProperties.GetOk("upload.params.quiet"); ok {
158178
uploadProperties.Set("upload.verbose", v)
159179
}
160180
if v, ok := uploadProperties.GetOk("program.params.quiet"); ok {
161181
uploadProperties.Set("program.verbose", v)
162182
}
183+
if v, ok := uploadProperties.GetOk("erase.params.quiet"); ok {
184+
uploadProperties.Set("erase.verbose", v)
185+
}
186+
if v, ok := uploadProperties.GetOk("bootloader.params.quiet"); ok {
187+
uploadProperties.Set("bootloader.verbose", v)
188+
}
163189
}
164190

165191
// Set properties for verify
@@ -172,29 +198,31 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
172198
}
173199

174200
var importPath *paths.Path
175-
if importDir := req.GetImportDir(); importDir != "" {
176-
importPath = paths.New(importDir)
177-
} else {
178-
// TODO: Create a function to obtain importPath from sketch
179-
importPath = sketch.FullPath
180-
// Add FQBN (without configs part) to export path
181-
fqbnSuffix := strings.Replace(fqbn.StringWithoutConfig(), ":", ".", -1)
182-
importPath = importPath.Join("build").Join(fqbnSuffix)
183-
}
201+
if !burnBootloader {
202+
if importDir := req.GetImportDir(); importDir != "" {
203+
importPath = paths.New(importDir)
204+
} else {
205+
// TODO: Create a function to obtain importPath from sketch
206+
importPath = sketch.FullPath
207+
// Add FQBN (without configs part) to export path
208+
fqbnSuffix := strings.Replace(fqbn.StringWithoutConfig(), ":", ".", -1)
209+
importPath = importPath.Join("build").Join(fqbnSuffix)
210+
}
184211

185-
if !importPath.Exist() {
186-
return nil, fmt.Errorf("compiled sketch not found in %s", importPath)
187-
}
188-
if !importPath.IsDir() {
189-
return nil, fmt.Errorf("expected compiled sketch in directory %s, but is a file instead", importPath)
212+
if !importPath.Exist() {
213+
return nil, fmt.Errorf("compiled sketch not found in %s", importPath)
214+
}
215+
if !importPath.IsDir() {
216+
return nil, fmt.Errorf("expected compiled sketch in directory %s, but is a file instead", importPath)
217+
}
218+
uploadProperties.SetPath("build.path", importPath)
219+
uploadProperties.Set("build.project_name", sketch.Name+".ino")
190220
}
191-
uploadProperties.SetPath("build.path", importPath)
192-
uploadProperties.Set("build.project_name", sketch.Name+".ino")
193221

194222
// If not using programmer perform some action required
195223
// to set the board in bootloader mode
196224
actualPort := port
197-
if programmer == nil {
225+
if programmer == nil && !burnBootloader {
198226
// Perform reset via 1200bps touch if requested
199227
if uploadProperties.GetBoolean("upload.use_1200bps_touch") {
200228
ports, err := serial.GetPortsList()
@@ -250,8 +278,14 @@ func Upload(ctx context.Context, req *rpc.UploadReq, outStream io.Writer, errStr
250278
}
251279

252280
// Build recipe for upload
253-
var recipe string
254-
if programmer != nil {
281+
if burnBootloader {
282+
if err := runTool("erase.pattern", uploadProperties, outStream, errStream, req.GetVerbose()); err != nil {
283+
return nil, fmt.Errorf("chip erase error: %s", err)
284+
}
285+
if err := runTool("bootloader.pattern", uploadProperties, outStream, errStream, req.GetVerbose()); err != nil {
286+
return nil, fmt.Errorf("burn bootloader error: %s", err)
287+
}
288+
} else if programmer != nil {
255289
if err := runTool("program.pattern", uploadProperties, outStream, errStream, req.GetVerbose()); err != nil {
256290
return nil, fmt.Errorf("programming error: %s", err)
257291
}

rpc/commands/upload.pb.go

Lines changed: 42 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rpc/commands/upload.proto

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ message UploadReq {
4444
// not specified, the standard build directory under `sketch_path` is used.
4545
string import_dir = 8;
4646
string programmer = 9;
47+
// Set to true if you want to program the bootloader. This option requires a
48+
// programmer. If sketch_path and import_path are empty only the bootloader is
49+
// uploaded.
50+
bool burn_bootloader = 10;
4751
}
4852

4953
message UploadResp {

0 commit comments

Comments
 (0)