Skip to content

Commit 24bd145

Browse files
authored
Allow port, protocol and port settings to be specified in profiles. (#2717)
* Allow port/protocol keys in sketch profile * Allow port/protocol in profiles * Added port settings in sketch profile * Allow port configuration from sketch profile * Added docs * fix: Moved port-from-profile logic in args.Port.GetPort(...) This allows to implement the selection logic on more commands. * Fixed FQBN selection logic in monitor/arg command * Fixed incorrect tests The previous fixes now let the CLI to produce the correct output.
1 parent 863c1ec commit 24bd145

File tree

22 files changed

+653
-339
lines changed

22 files changed

+653
-339
lines changed

docs/sketch-project-file.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Each profile will define:
1515
- A possible core platform name and version, that is a dependency of the target core platform (with the 3rd party
1616
platform index URL if needed)
1717
- The libraries used in the sketch (including their version)
18+
- The port and protocol to upload the sketch and monitor the board
1819

1920
The format of the file is the following:
2021

@@ -33,7 +34,11 @@ profiles:
3334
- <LIB_NAME> (<LIB_VERSION>)
3435
- <LIB_NAME> (<LIB_VERSION>)
3536
- <LIB_NAME> (<LIB_VERSION>)
36-
37+
port: <PORT_NAME>
38+
port_config:
39+
<PORT_SETTING_NAME>: <PORT_SETTING_VALUE>
40+
...
41+
protocol: <PORT_PROTOCOL>
3742
...more profiles here...
3843
```
3944

@@ -54,6 +59,15 @@ otherwise below). The available fields are:
5459
- `<USER_NOTES>` is a free text string available to the developer to add comments. This field is optional.
5560
- `<PROGRAMMER>` is the programmer that will be used. This field is optional.
5661

62+
The following fields are available since Arduino CLI 1.1.0:
63+
64+
- `<PORT_NAME>` is the port that will be used to upload and monitor the board (unless explicitly set otherwise). This
65+
field is optional.
66+
- `port_config` section with `<PORT_SETTING_NAME>` and `<PORT_SETTING_VALUE>` defines the port settings that will be
67+
used in the `monitor` command. Typically is used to set the baudrate for the serial port (for example
68+
`baudrate: 115200`) but any setting/value can be specified. Multiple settings can be set. These fields are optional.
69+
- `<PORT_PROTOCOL>` is the protocol for the port used to upload and monitor the board. This field is optional.
70+
5771
A complete example of a sketch project file may be the following:
5872

5973
```
@@ -76,6 +90,9 @@ profiles:
7690
- VitconMQTT (1.0.1)
7791
- Arduino_ConnectionHandler (0.6.4)
7892
- TinyDHT sensor library (1.1.0)
93+
port: /dev/ttyACM0
94+
port_config:
95+
baudrate: 115200
7996
8097
tiny:
8198
notes: testing the very limit of the AVR platform, it will be very unstable
@@ -139,6 +156,8 @@ particular:
139156
- The `default_fqbn` key sets the default value for the `--fqbn` flag
140157
- The `default_programmer` key sets the default value for the `--programmer` flag
141158
- The `default_port` key sets the default value for the `--port` flag
159+
- The `default_port_config` key sets the default values for the `--config` flag in the `monitor` command (available
160+
since Arduino CLI 1.1.0)
142161
- The `default_protocol` key sets the default value for the `--protocol` flag
143162
- The `default_profile` key sets the default value for the `--profile` flag
144163

@@ -148,11 +167,14 @@ For example:
148167
default_fqbn: arduino:samd:mkr1000
149168
default_programmer: atmel_ice
150169
default_port: /dev/ttyACM0
170+
default_port_config:
171+
baudrate: 115200
151172
default_protocol: serial
152173
default_profile: myprofile
153174
```
154175

155176
With this configuration set, it is not necessary to specify the `--fqbn`, `--programmer`, `--port`, `--protocol` or
156177
`--profile` flags to the [`arduino-cli compile`](commands/arduino-cli_compile.md),
157178
[`arduino-cli upload`](commands/arduino-cli_upload.md) or [`arduino-cli debug`](commands/arduino-cli_debug.md) commands
158-
when compiling, uploading or debugging the sketch.
179+
when compiling, uploading or debugging the sketch. Moreover in the `monitor` command it is not necessary to specify the
180+
`--config baudrate=115200` to communicate with the monitor port of the board.

internal/arduino/sketch/profiles.go

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,13 @@ import (
3434

3535
// projectRaw is a support struct used only to unmarshal the yaml
3636
type projectRaw struct {
37-
ProfilesRaw yaml.Node `yaml:"profiles"`
38-
DefaultProfile string `yaml:"default_profile"`
39-
DefaultFqbn string `yaml:"default_fqbn"`
40-
DefaultPort string `yaml:"default_port,omitempty"`
41-
DefaultProtocol string `yaml:"default_protocol,omitempty"`
42-
DefaultProgrammer string `yaml:"default_programmer,omitempty"`
37+
ProfilesRaw yaml.Node `yaml:"profiles"`
38+
DefaultProfile string `yaml:"default_profile"`
39+
DefaultFqbn string `yaml:"default_fqbn"`
40+
DefaultPort string `yaml:"default_port,omitempty"`
41+
DefaultPortConfig map[string]string `yaml:"default_port_config,omitempty"`
42+
DefaultProtocol string `yaml:"default_protocol,omitempty"`
43+
DefaultProgrammer string `yaml:"default_programmer,omitempty"`
4344
}
4445

4546
// Project represents the sketch project file
@@ -48,6 +49,7 @@ type Project struct {
4849
DefaultProfile string
4950
DefaultFqbn string
5051
DefaultPort string
52+
DefaultPortConfig map[string]string
5153
DefaultProtocol string
5254
DefaultProgrammer string
5355
}
@@ -70,6 +72,12 @@ func (p *Project) AsYaml() string {
7072
if p.DefaultPort != "" {
7173
res += fmt.Sprintf("default_port: %s\n", p.DefaultPort)
7274
}
75+
if len(p.DefaultPortConfig) > 0 {
76+
res += "default_port_config:\n"
77+
for k, v := range p.DefaultPortConfig {
78+
res += fmt.Sprintf(" %s: %s\n", k, v)
79+
}
80+
}
7381
if p.DefaultProtocol != "" {
7482
res += fmt.Sprintf("default_protocol: %s\n", p.DefaultProtocol)
7583
}
@@ -103,17 +111,33 @@ type Profile struct {
103111
Name string
104112
Notes string `yaml:"notes"`
105113
FQBN string `yaml:"fqbn"`
114+
Port string `yaml:"port"`
115+
PortConfig map[string]string `yaml:"port_config"`
116+
Protocol string `yaml:"protocol"`
106117
Programmer string `yaml:"programmer"`
107118
Platforms ProfileRequiredPlatforms `yaml:"platforms"`
108119
Libraries ProfileRequiredLibraries `yaml:"libraries"`
109120
}
110121

111122
// ToRpc converts this Profile to an rpc.SketchProfile
112123
func (p *Profile) ToRpc() *rpc.SketchProfile {
124+
var portConfig *rpc.MonitorPortConfiguration
125+
if len(p.PortConfig) > 0 {
126+
portConfig = &rpc.MonitorPortConfiguration{}
127+
for k, v := range p.PortConfig {
128+
portConfig.Settings = append(portConfig.Settings, &rpc.MonitorPortSetting{
129+
SettingId: k,
130+
Value: v,
131+
})
132+
}
133+
}
113134
return &rpc.SketchProfile{
114135
Name: p.Name,
115136
Fqbn: p.FQBN,
116137
Programmer: p.Programmer,
138+
Port: p.Port,
139+
PortConfig: portConfig,
140+
Protocol: p.Protocol,
117141
}
118142
}
119143

@@ -127,6 +151,18 @@ func (p *Profile) AsYaml() string {
127151
if p.Programmer != "" {
128152
res += fmt.Sprintf(" programmer: %s\n", p.Programmer)
129153
}
154+
if p.Port != "" {
155+
res += fmt.Sprintf(" port: %s\n", p.Port)
156+
}
157+
if p.Protocol != "" {
158+
res += fmt.Sprintf(" protocol: %s\n", p.Protocol)
159+
}
160+
if len(p.PortConfig) > 0 {
161+
res += " port_config:\n"
162+
for k, v := range p.PortConfig {
163+
res += fmt.Sprintf(" %s: %s\n", k, v)
164+
}
165+
}
130166
res += p.Platforms.AsYaml()
131167
res += p.Libraries.AsYaml()
132168
return res
@@ -291,6 +327,7 @@ func LoadProjectFile(file *paths.Path) (*Project, error) {
291327
DefaultProfile: raw.DefaultProfile,
292328
DefaultFqbn: raw.DefaultFqbn,
293329
DefaultPort: raw.DefaultPort,
330+
DefaultPortConfig: raw.DefaultPortConfig,
294331
DefaultProtocol: raw.DefaultProtocol,
295332
DefaultProgrammer: raw.DefaultProgrammer,
296333
}, nil

internal/arduino/sketch/sketch.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,16 @@ func (s *Sketch) Hash() string {
289289
// ToRpc converts this Sketch into a rpc.LoadSketchResponse
290290
func (s *Sketch) ToRpc() *rpc.Sketch {
291291
defaultPort, defaultProtocol := s.GetDefaultPortAddressAndProtocol()
292+
var defaultPortConfig *rpc.MonitorPortConfiguration
293+
if len(s.Project.DefaultPortConfig) > 0 {
294+
defaultPortConfig = &rpc.MonitorPortConfiguration{}
295+
for k, v := range s.Project.DefaultPortConfig {
296+
defaultPortConfig.Settings = append(defaultPortConfig.Settings, &rpc.MonitorPortSetting{
297+
SettingId: k,
298+
Value: v,
299+
})
300+
}
301+
}
292302
res := &rpc.Sketch{
293303
MainFile: s.MainFile.String(),
294304
LocationPath: s.FullPath.String(),
@@ -297,6 +307,7 @@ func (s *Sketch) ToRpc() *rpc.Sketch {
297307
RootFolderFiles: s.RootFolderFiles.AsStrings(),
298308
DefaultFqbn: s.GetDefaultFQBN(),
299309
DefaultPort: defaultPort,
310+
DefaultPortConfig: defaultPortConfig,
300311
DefaultProtocol: defaultProtocol,
301312
DefaultProgrammer: s.GetDefaultProgrammer(),
302313
Profiles: f.Map(s.Project.Profiles, (*Profile).ToRpc),

internal/cli/arguments/fqbn.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,19 @@ func (f *Fqbn) Set(fqbn string) {
6464
// parameters provided by the user.
6565
// This determine the FQBN based on:
6666
// - the value of the FQBN flag if explicitly specified, otherwise
67+
// - the FQBN of the selected profile if available, otherwise
6768
// - the default FQBN value in sketch.yaml (`default_fqbn` key) if available, otherwise
6869
// - it tries to autodetect the board connected to the given port flags
6970
// If all above methods fails, it returns the empty string.
7071
// The Port metadata are always returned except if:
7172
// - the port is not found, in this case nil is returned
7273
// - the FQBN autodetection fail, in this case the function prints an error and
7374
// terminates the execution
74-
func CalculateFQBNAndPort(ctx context.Context, portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultFQBN, defaultAddress, defaultProtocol string) (string, *rpc.Port) {
75+
func CalculateFQBNAndPort(ctx context.Context, portArgs *Port, fqbnArg *Fqbn, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultFQBN, defaultAddress, defaultProtocol string, profile *rpc.SketchProfile) (string, *rpc.Port) {
7576
fqbn := fqbnArg.String()
77+
if fqbn == "" {
78+
fqbn = profile.GetFqbn()
79+
}
7680
if fqbn == "" {
7781
fqbn = defaultFQBN
7882
}
@@ -87,7 +91,7 @@ func CalculateFQBNAndPort(ctx context.Context, portArgs *Port, fqbnArg *Fqbn, in
8791
return fqbn, port
8892
}
8993

90-
port, err := portArgs.GetPort(ctx, instance, srv, defaultAddress, defaultProtocol)
94+
port, err := portArgs.GetPort(ctx, instance, srv, defaultAddress, defaultProtocol, profile)
9195
if err != nil {
9296
feedback.Fatal(i18n.Tr("Error getting port metadata: %v", err), feedback.ErrGeneric)
9397
}

internal/cli/arguments/port.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ func (p *Port) AddToCommand(cmd *cobra.Command, srv rpc.ArduinoCoreServiceServer
5757
// This method allows will bypass the discoveries if:
5858
// - a nil instance is passed: in this case the plain port and protocol arguments are returned (even if empty)
5959
// - a protocol is specified: in this case the discoveries are not needed to autodetect the protocol.
60-
func (p *Port) GetPortAddressAndProtocol(ctx context.Context, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string) (string, string, error) {
60+
func (p *Port) GetPortAddressAndProtocol(ctx context.Context, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string, profile *rpc.SketchProfile) (string, string, error) {
6161
if p.protocol != "" || instance == nil {
6262
return p.address, p.protocol, nil
6363
}
6464

65-
port, err := p.GetPort(ctx, instance, srv, defaultAddress, defaultProtocol)
65+
port, err := p.GetPort(ctx, instance, srv, defaultAddress, defaultProtocol, profile)
6666
if err != nil {
6767
return "", "", err
6868
}
@@ -71,7 +71,13 @@ func (p *Port) GetPortAddressAndProtocol(ctx context.Context, instance *rpc.Inst
7171

7272
// GetPort returns the Port obtained by parsing command line arguments.
7373
// The extra metadata for the ports is obtained using the pluggable discoveries.
74-
func (p *Port) GetPort(ctx context.Context, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string) (*rpc.Port, error) {
74+
func (p *Port) GetPort(ctx context.Context, instance *rpc.Instance, srv rpc.ArduinoCoreServiceServer, defaultAddress, defaultProtocol string, profile *rpc.SketchProfile) (*rpc.Port, error) {
75+
if profile.GetPort() != "" {
76+
defaultAddress = profile.GetPort()
77+
}
78+
if profile.GetProtocol() != "" {
79+
defaultProtocol = profile.GetProtocol()
80+
}
7581
address := p.address
7682
protocol := p.protocol
7783
if address == "" && (defaultAddress != "" || defaultProtocol != "") {

internal/cli/board/attach.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func initAttachCommand(srv rpc.ArduinoCoreServiceServer) *cobra.Command {
5959
func runAttachCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, path string, port *arguments.Port, fqbn string, programmer *arguments.Programmer) {
6060
sketchPath := arguments.InitSketchPath(path)
6161

62-
portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(ctx, nil, srv, "", "")
62+
portAddress, portProtocol, _ := port.GetPortAddressAndProtocol(ctx, nil, srv, "", "", nil)
6363
newDefaults, err := srv.SetSketchDefaults(ctx, &rpc.SetSketchDefaultsRequest{
6464
SketchPath: sketchPath.String(),
6565
DefaultFqbn: fqbn,

internal/cli/burnbootloader/burnbootloader.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func runBootloaderCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer)
7373
logrus.Info("Executing `arduino-cli burn-bootloader`")
7474

7575
// We don't need a Sketch to upload a board's bootloader
76-
discoveryPort, err := port.GetPort(ctx, instance, srv, "", "")
76+
discoveryPort, err := port.GetPort(ctx, instance, srv, "", "", nil)
7777
if err != nil {
7878
feedback.Fatal(i18n.Tr("Error during Upload: %v", err), feedback.ErrGeneric)
7979
}

internal/cli/compile/compile.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func runCompileCommand(cmd *cobra.Command, args []string, srv rpc.ArduinoCoreSer
180180
fqbnArg.Set(profile.GetFqbn())
181181
}
182182

183-
fqbn, port := arguments.CalculateFQBNAndPort(ctx, &portArgs, &fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol())
183+
fqbn, port := arguments.CalculateFQBNAndPort(ctx, &portArgs, &fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol(), profile)
184184

185185
if keysKeychain != "" || signKey != "" || encryptKey != "" {
186186
arguments.CheckFlagsMandatory(cmd, "keys-keychain", "sign-key", "encrypt-key")

internal/cli/debug/debug.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ func runDebugCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer, args
108108
fqbnArg.Set(profile.GetFqbn())
109109
}
110110

111-
fqbn, port := arguments.CalculateFQBNAndPort(ctx, portArgs, fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol())
111+
fqbn, port := arguments.CalculateFQBNAndPort(ctx, portArgs, fqbnArg, inst, srv, sk.GetDefaultFqbn(), sk.GetDefaultPort(), sk.GetDefaultProtocol(), profile)
112112

113113
prog := profile.GetProgrammer()
114114
if prog == "" || programmer.GetProgrammer() != "" {

internal/cli/debug/debug_check.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func runDebugCheckCommand(ctx context.Context, srv rpc.ArduinoCoreServiceServer,
6060
instance := instance.CreateAndInit(ctx, srv)
6161
logrus.Info("Executing `arduino-cli debug`")
6262

63-
port, err := portArgs.GetPort(ctx, instance, srv, "", "")
63+
port, err := portArgs.GetPort(ctx, instance, srv, "", "", nil)
6464
if err != nil {
6565
feedback.FatalError(err, feedback.ErrBadArgument)
6666
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy