Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 25d9100

Browse files
cmaglieper1234
andauthored
Extended Pluggable Monitor specification to allow board-specific settings to be applied (#1855)
* Added methods to obtain specific monitor settings for a board * Updated documentation * Implementaion of board-specific monitor settings * Allow submenu properties to override monitor settings * Apply code review changes to docs * Apply suggestions from code review Co-authored-by: per1234 <accounts@perglass.com> Co-authored-by: per1234 <accounts@perglass.com>
1 parent ae06539 commit 25d9100

File tree

6 files changed

+184
-17
lines changed

6 files changed

+184
-17
lines changed

‎arduino/cores/board.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,9 @@ func (b *Board) IsBoardMatchingIDProperties(query *properties.Map) bool {
173173
}
174174
return false
175175
}
176+
177+
// GetMonitorSettings returns the settings for the pluggable monitor of the given protocol
178+
// and set of board properties.
179+
func GetMonitorSettings(protocol string, boardProperties *properties.Map) *properties.Map {
180+
return boardProperties.SubTree("monitor_port." + protocol)
181+
}

‎arduino/cores/packagemanager/loader.go‎

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ func (pm *Builder) loadBoards(platform *cores.PlatformRelease) error {
504504
convertVidPidIdentificationPropertiesToPluggableDiscovery(boardProperties)
505505
convertUploadToolsToPluggableDiscovery(boardProperties)
506506
}
507+
convertLegacySerialPortRTSDTRSettingsToPluggableMonitor(boardProperties)
507508

508509
// The board's ID must be available in a board's properties since it can
509510
// be used in all configuration files for several reasons, like setting compilation
@@ -523,6 +524,42 @@ func (pm *Builder) loadBoards(platform *cores.PlatformRelease) error {
523524
return nil
524525
}
525526

527+
// Converts the old:
528+
//
529+
// - xxx.serial.disableRTS=true
530+
// - xxx.serial.disableDTR=true
531+
//
532+
// properties into pluggable monitor compatible:
533+
//
534+
// - xxx.monitor_port.serial.rts=off
535+
// - xxx.monitor_port.serial.dtr=off
536+
func convertLegacySerialPortRTSDTRSettingsToPluggableMonitor(boardProperties *properties.Map) {
537+
disabledToOnOff := func(k string) string {
538+
if boardProperties.GetBoolean(k) {
539+
return "off" // Disabled
540+
}
541+
return "on" // Not disabled
542+
}
543+
if boardProperties.ContainsKey("serial.disableDTR") {
544+
boardProperties.Set("monitor_port.serial.dtr", disabledToOnOff("serial.disableDTR"))
545+
}
546+
if boardProperties.ContainsKey("serial.disableRTS") {
547+
boardProperties.Set("monitor_port.serial.rts", disabledToOnOff("serial.disableRTS"))
548+
}
549+
for _, k := range boardProperties.Keys() {
550+
if strings.HasSuffix(k, ".serial.disableDTR") {
551+
boardProperties.Set(
552+
strings.TrimSuffix(k, ".serial.disableDTR")+".monitor_port.serial.dtr",
553+
disabledToOnOff(k))
554+
}
555+
if strings.HasSuffix(k, ".serial.disableRTS") {
556+
boardProperties.Set(
557+
strings.TrimSuffix(k, ".serial.disableRTS")+".monitor_port.serial.rts",
558+
disabledToOnOff(k))
559+
}
560+
}
561+
}
562+
526563
// Converts the old:
527564
//
528565
// - xxx.vid.N
@@ -532,7 +569,6 @@ func (pm *Builder) loadBoards(platform *cores.PlatformRelease) error {
532569
//
533570
// - xxx.upload_port.N.vid
534571
// - xxx.upload_port.N.pid
535-
//
536572
func convertVidPidIdentificationPropertiesToPluggableDiscovery(boardProperties *properties.Map) {
537573
n := 0
538574
outputVidPid := func(vid, pid string) {

‎arduino/cores/packagemanager/loader_test.go‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,67 @@ arduino_zero_native.pid.3=0x024d
106106
}`, zero4.Dump())
107107
}
108108

109+
func TestDisableDTRRTSConversionToPluggableMonitor(t *testing.T) {
110+
m, err := properties.LoadFromBytes([]byte(`
111+
menu.rts=RTS
112+
menu.dtr=DTR
113+
foo.menu.rts.on=On
114+
foo.menu.rts.on.serial.disableRTS=false
115+
foo.menu.rts.off=Off
116+
foo.menu.rts.off.serial.disableRTS=true
117+
foo.menu.dtr.on=On
118+
foo.menu.dtr.on.serial.disableDTR=false
119+
foo.menu.dtr.off=Off
120+
foo.menu.dtr.off.serial.disableDTR=true
121+
122+
arduino_zero.serial.disableDTR=true
123+
arduino_zero.serial.disableRTS=true
124+
125+
arduino_zero_edbg.serial.disableDTR=false
126+
arduino_zero_edbg.serial.disableRTS=true
127+
`))
128+
require.NoError(t, err)
129+
130+
{
131+
zero := m.SubTree("arduino_zero")
132+
convertLegacySerialPortRTSDTRSettingsToPluggableMonitor(zero)
133+
require.Equal(t, `properties.Map{
134+
"serial.disableDTR": "true",
135+
"serial.disableRTS": "true",
136+
"monitor_port.serial.dtr": "off",
137+
"monitor_port.serial.rts": "off",
138+
}`, zero.Dump())
139+
}
140+
{
141+
zeroEdbg := m.SubTree("arduino_zero_edbg")
142+
convertLegacySerialPortRTSDTRSettingsToPluggableMonitor(zeroEdbg)
143+
require.Equal(t, `properties.Map{
144+
"serial.disableDTR": "false",
145+
"serial.disableRTS": "true",
146+
"monitor_port.serial.dtr": "on",
147+
"monitor_port.serial.rts": "off",
148+
}`, zeroEdbg.Dump())
149+
}
150+
{
151+
foo := m.SubTree("foo")
152+
convertLegacySerialPortRTSDTRSettingsToPluggableMonitor(foo)
153+
require.Equal(t, `properties.Map{
154+
"menu.rts.on": "On",
155+
"menu.rts.on.serial.disableRTS": "false",
156+
"menu.rts.off": "Off",
157+
"menu.rts.off.serial.disableRTS": "true",
158+
"menu.dtr.on": "On",
159+
"menu.dtr.on.serial.disableDTR": "false",
160+
"menu.dtr.off": "Off",
161+
"menu.dtr.off.serial.disableDTR": "true",
162+
"menu.rts.on.monitor_port.serial.rts": "on",
163+
"menu.rts.off.monitor_port.serial.rts": "off",
164+
"menu.dtr.on.monitor_port.serial.dtr": "on",
165+
"menu.dtr.off.monitor_port.serial.dtr": "off",
166+
}`, foo.Dump())
167+
}
168+
}
169+
109170
func TestLoadDiscoveries(t *testing.T) {
110171
// Create all the necessary data to load discoveries
111172
fakePath := paths.New("fake-path")

‎commands/monitor/monitor.go‎

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func Monitor(ctx context.Context, req *rpc.MonitorRequest) (*PortProxy, *pluggab
6767
}
6868
defer release()
6969

70-
m, err := findMonitorForProtocolAndBoard(pme, req.GetPort().GetProtocol(), req.GetFqbn())
70+
m, boardSettings, err := findMonitorAndSettingsForProtocolAndBoard(pme, req.GetPort().GetProtocol(), req.GetFqbn())
7171
if err != nil {
7272
return nil, nil, err
7373
}
@@ -82,18 +82,25 @@ func Monitor(ctx context.Context, req *rpc.MonitorRequest) (*PortProxy, *pluggab
8282
return nil, nil, &arduino.FailedMonitorError{Cause: err}
8383
}
8484

85-
monIO, err := m.Open(req.GetPort().GetAddress(), req.GetPort().GetProtocol())
86-
if err != nil {
87-
m.Quit()
88-
return nil, nil, &arduino.FailedMonitorError{Cause: err}
89-
}
85+
// Apply user-requested settings
9086
if portConfig := req.GetPortConfiguration(); portConfig != nil {
9187
for _, setting := range portConfig.Settings {
88+
boardSettings.Remove(setting.SettingId) // Remove board settings overridden by the user
9289
if err := m.Configure(setting.SettingId, setting.Value); err != nil {
9390
logrus.Errorf("Could not set configuration %s=%s: %s", setting.SettingId, setting.Value, err)
9491
}
9592
}
9693
}
94+
// Apply specific board settings
95+
for setting, value := range boardSettings.AsMap() {
96+
m.Configure(setting, value)
97+
}
98+
99+
monIO, err := m.Open(req.GetPort().GetAddress(), req.GetPort().GetProtocol())
100+
if err != nil {
101+
m.Quit()
102+
return nil, nil, &arduino.FailedMonitorError{Cause: err}
103+
}
97104

98105
logrus.Infof("Port %s successfully opened", req.GetPort().GetAddress())
99106
return &PortProxy{
@@ -106,36 +113,39 @@ func Monitor(ctx context.Context, req *rpc.MonitorRequest) (*PortProxy, *pluggab
106113
}, descriptor, nil
107114
}
108115

109-
func findMonitorForProtocolAndBoard(pme *packagemanager.Explorer, protocol, fqbn string) (*pluggableMonitor.PluggableMonitor, error) {
116+
func findMonitorAndSettingsForProtocolAndBoard(pme *packagemanager.Explorer, protocol, fqbn string) (*pluggableMonitor.PluggableMonitor, *properties.Map, error) {
110117
if protocol == "" {
111-
return nil, &arduino.MissingPortProtocolError{}
118+
return nil, nil, &arduino.MissingPortProtocolError{}
112119
}
113120

114121
var monitorDepOrRecipe *cores.MonitorDependency
122+
boardSettings := properties.NewMap()
115123

116124
// If a board is specified search the monitor in the board package first
117125
if fqbn != "" {
118126
fqbn, err := cores.ParseFQBN(fqbn)
119127
if err != nil {
120-
return nil, &arduino.InvalidFQBNError{Cause: err}
128+
return nil, nil, &arduino.InvalidFQBNError{Cause: err}
121129
}
122130

123131
_, boardPlatform, _, boardProperties, _, err := pme.ResolveFQBN(fqbn)
124132
if err != nil {
125-
return nil, &arduino.UnknownFQBNError{Cause: err}
133+
return nil, nil, &arduino.UnknownFQBNError{Cause: err}
126134
}
127135

136+
boardSettings = cores.GetMonitorSettings(protocol, boardProperties)
137+
128138
if mon, ok := boardPlatform.Monitors[protocol]; ok {
129139
monitorDepOrRecipe = mon
130140
} else if recipe, ok := boardPlatform.MonitorsDevRecipes[protocol]; ok {
131141
// If we have a recipe we must resolve it
132142
cmdLine := boardProperties.ExpandPropsInString(recipe)
133143
cmdArgs, err := properties.SplitQuotedString(cmdLine, `"'`, false)
134144
if err != nil {
135-
return nil, &arduino.InvalidArgumentError{Message: tr("Invalid recipe in platform.txt"), Cause: err}
145+
return nil, nil, &arduino.InvalidArgumentError{Message: tr("Invalid recipe in platform.txt"), Cause: err}
136146
}
137147
id := fmt.Sprintf("%s-%s", boardPlatform, protocol)
138-
return pluggableMonitor.New(id, cmdArgs...), nil
148+
return pluggableMonitor.New(id, cmdArgs...), boardSettings, nil
139149
}
140150
}
141151

@@ -150,17 +160,17 @@ func findMonitorForProtocolAndBoard(pme *packagemanager.Explorer, protocol, fqbn
150160
}
151161

152162
if monitorDepOrRecipe == nil {
153-
return nil, &arduino.NoMonitorAvailableForProtocolError{Protocol: protocol}
163+
return nil, nil, &arduino.NoMonitorAvailableForProtocolError{Protocol: protocol}
154164
}
155165

156166
// If it is a monitor dependency, resolve tool and create a monitor client
157167
tool := pme.FindMonitorDependency(monitorDepOrRecipe)
158168
if tool == nil {
159-
return nil, &arduino.MonitorNotFoundError{Monitor: monitorDepOrRecipe.String()}
169+
return nil, nil, &arduino.MonitorNotFoundError{Monitor: monitorDepOrRecipe.String()}
160170
}
161171

162172
return pluggableMonitor.New(
163173
monitorDepOrRecipe.Name,
164174
tool.InstallDir.Join(monitorDepOrRecipe.Name).String(),
165-
), nil
175+
), boardSettings, nil
166176
}

‎commands/monitor/settings.go‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitor
3232
}
3333
defer release()
3434

35-
m, err := findMonitorForProtocolAndBoard(pme, req.GetPortProtocol(), req.GetFqbn())
35+
m, boardSettings, err := findMonitorAndSettingsForProtocolAndBoard(pme, req.GetPortProtocol(), req.GetFqbn())
3636
if err != nil {
3737
return nil, err
3838
}
@@ -46,6 +46,19 @@ func EnumerateMonitorPortSettings(ctx context.Context, req *rpc.EnumerateMonitor
4646
if err != nil {
4747
return nil, &arduino.FailedMonitorError{Cause: err}
4848
}
49+
50+
// Apply default settings for this board and protocol
51+
for setting, value := range boardSettings.AsMap() {
52+
if param, ok := desc.ConfigurationParameters[setting]; ok {
53+
for _, v := range param.Values {
54+
if v == value {
55+
param.Selected = value
56+
break
57+
}
58+
}
59+
}
60+
}
61+
4962
return &rpc.EnumerateMonitorPortSettingsResponse{Settings: convert(desc)}, nil
5063
}
5164

‎docs/platform-specification.md‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,47 @@ will allow all legacy non-pluggable platforms to migrate to pluggable monitor wi
903903

904904
For detailed information, see the [Pluggable Monitor specification](pluggable-monitor-specification.md).
905905

906+
#### Port configuration
907+
908+
Each pluggable monitor has its own default settings that can be overridden using the following board properties:
909+
910+
```
911+
BOARD_ID.monitor_port.PROTOCOL.SETTING_NAME=SETTING_VALUE
912+
```
913+
914+
where:
915+
916+
- `BOARD_ID` is the board identifier
917+
- `PROTOCOL` is the port protocol
918+
- `SETTING_NAME` and `SETTING_VALUE` are the port setting and the desired value
919+
920+
For example, let's suppose that a board needs the `baudrate` setting of the `serial` port to be `9600`, then the
921+
corresponding properties in the `boards.txt` file will be:
922+
923+
```
924+
myboard.monitor_port.serial.baudrate=9600
925+
```
926+
927+
The settings available in a specific pluggable monitor can be
928+
[queried directly from it](pluggable-monitor-specification.md#describe-command).
929+
930+
#### Legacy `serial.disableRTS` and `serial.disableDTR` properties
931+
932+
In the old Arduino IDE (<=1.8.x) we used the properties:
933+
934+
```
935+
BOARD_ID.serial.disableRTS=true
936+
BOARD_ID.serial.disableDTR=true
937+
```
938+
939+
to disable RTS and DTR when opening the serial monitor. To keep backward compatibilty the properties above are
940+
automatically converted to the corresponding pluggable monitor properties:
941+
942+
```
943+
BOARD_ID.monitor_port.serial.rts=off
944+
BOARD_ID.monitor_port.serial.dtr=off
945+
```
946+
906947
### Verbose parameter
907948

908949
It is possible for the user to enable verbosity from the Preferences panel of the IDEs or Arduino CLI's `--verbose`

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /