Skip to content

Commit a5cef06

Browse files
committed
Added documentation for pluggable monitor
1 parent fd14435 commit a5cef06

4 files changed

+336
-11
lines changed

Diff for: docs/package_index_json-specification.md

+15-7
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ Each tool describes a binary distribution of a command line tool. A tool can be:
8181
- a debugger
8282
- a program that performs a firmware upgrade
8383
- a [pluggable discovery](pluggable-discovery-specification.md)
84+
- a [pluggable monitor][pluggable-monitor-specification.md]
8485

8586
basically anything that can run on the user's host PC and do something useful.
8687

@@ -220,6 +221,9 @@ Finally, let's see how `PLATFORMS` are made.
220221
"discoveryDependencies": [
221222
{ "packager": "arduino", "name": "serial-discovery" },
222223
{ "packager": "arduino", "name": "mdns-discovery" }
224+
],
225+
"monitorDependencies": [
226+
{ "packager": "arduino", "name": "serial-monitor" }
223227
]
224228
},
225229
```
@@ -236,13 +240,17 @@ Each PLATFORM describes a core for a specific architecture. The fields needed ar
236240
TOOLS
237241
- `boards`: the list of boards supported (note: just the names to display on the Arduino IDE and Arduino Pro IDE's
238242
Boards Manager GUI! the real boards definitions are inside `boards.txt` inside the core archive file)
239-
- `toolsDependencies`: the tools needed by this core. They will be installed by Boards Manager along with the platform.
240-
Each tool is referenced by the triple (`packager`, `name`, `version`) as previously said. Note that you can reference
241-
tools available in other packages as well, even if no platform of that package is installed.
242-
- `discoveryDependencies`: the Pluggable Discoveries needed by this core. Each discovery is referenced by `packager` and
243-
`name`, the `version` is not specified because the latest installed discovery tool will always be used. Like
244-
`toolsDependencies` they will be installed by Boards Manager along with the platform and can reference tools available
245-
in other packages as well, even if no platform of that package is installed.
243+
- `toolsDependencies`: the tools needed by this platform. They will be installed by Boards Manager along with the
244+
platform. Each tool is referenced by the triple (`packager`, `name`, `version`) as previously said. Note that you can
245+
reference tools available in other packages as well, even if no platform of that package is installed.
246+
- `discoveryDependencies`: the Pluggable Discoveries needed by this platform. Each discovery is referenced by the pair
247+
(`packager`, `name`), the `version` is not specified because the latest installed discovery tool will always be used.
248+
Like `toolsDependencies` they will be installed by Boards Manager along with the platform and can reference tools
249+
available in other packages as well, even if no platform of that package is installed.
250+
- `monitorDependencies`: the Pluggable Monitors needed by this platform. Each monitor is referenced by the pair
251+
(`packager`, `name`), the `version` is not specified because the latest installed monitor tool will always be used.
252+
Like `toolsDependencies` they will be installed by Boards Manager along with the platform and can reference tools
253+
available in other packages as well, even if no platform of that package is installed.
246254

247255
The `version` field is validated by both Arduino IDE and [JSemVer](https://github.com/zafarkhaja/jsemver). Here are the
248256
rules Arduino IDE follows for parsing versions

Diff for: docs/platform-specification.md

+66-2
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ The tool configuration properties are available globally without the prefix. For
698698
property can be used as **{cmd.path}** inside the recipe, and the same happens for all the other avrdude configuration
699699
variables.
700700

701-
#### Pluggable discovery
701+
### Pluggable discovery
702702

703703
Discovery tools are a special kind of tool used to find supported boards. A platform must declare one or more Pluggable
704704
Discoveries in its [`platform.txt`](#platformtxt). Discoveries can be referenced from other packages, including the
@@ -755,7 +755,71 @@ builtin discoveries that may be possibly added in the future).
755755

756756
For detailed information, see the [Pluggable Discovery specification](pluggable-discovery-specification.md).
757757

758-
#### Verbose parameter
758+
### Pluggable monitor
759+
760+
Monitor tools are a special kind of tool used to let the user communicate with the supported boards.
761+
762+
A platform must declare one or more Pluggable Monitor in its [`platform.txt`](#platformtxt) and bind them to a specific
763+
port protocol. Monitors can be referenced from other packages.
764+
765+
The following direcive is used to bind a specific monitor tool to a specific port protocol:
766+
767+
```
768+
pluggable_monitor.required.PROTOCOL=PLATFORM:MONITOR_NAME
769+
```
770+
771+
where `PROTOCOL` must be replaced with the port protocol identifier and `PLATFORM:MONITOR_NAME` must be replaced with
772+
the monitor tool identifier.
773+
774+
The platform can support as many protocols as needed:
775+
776+
```
777+
pluggable_monitor.required.PROTOCOL1=PLATFORM:MONITOR_NAME1
778+
pluggable_monitor.required.PROTOCOL2=PLATFORM:MONITOR_NAME2
779+
...
780+
```
781+
782+
The above syntax requires specifying a monitor tool via the `monitorDependencies` field of the platform's
783+
[package index](package_index_json-specification.md). Since it might be cumbersome to use with manual installations, we
784+
provide another syntax to ease development and beta testing:
785+
786+
```
787+
pluggable_monitor.pattern.PROTOCOL=MONITOR_RECIPE
788+
```
789+
790+
where `MONITOR_RECIPE` must be replaced by the command line to launch the monitor tool for the specific `PROTOCOL`. An
791+
example could be:
792+
793+
```
794+
pluggable_monitor.pattern.custom-ble="{runtime.tools.my-ble-monitor.path}/my-ble-monitor" -H
795+
```
796+
797+
in this case the platform provides a new hypotetical `custom-ble` protocol monitor tool and the command line tool named
798+
`my-ble-monitor` is launched with the `-H` parameter to start the monitor tool. In this case the command line pattern
799+
may contain any extra parameter in the formula: this is different from the monitor tools installed through the
800+
`discoveryDependencies` field that must run without any command line parameter.
801+
802+
We strongly recommend using this syntax only for development purposes and not on released platforms.
803+
804+
#### Built-in monitors
805+
806+
If a platform supports only boards connected via serial ports it can easily use the `builtin:serial-monitor` tool
807+
without creating a custom pluggable monitor:
808+
809+
```
810+
pluggable_monitor.required.serial=builtin:serial-monitor
811+
```
812+
813+
#### Backward compatibility
814+
815+
For backward compatibility, if a platform does not declare any discovery or monitor tool (using the
816+
`pluggable_discovery.*` or `pluggable_monitor.*` properties in `platform.txt` respectively) it will automatically
817+
inherit `builtin:serial-monitor` (but not other `builtin` monitor tools that may be possibly added in the future). This
818+
will allow all legacy non-pluggable platforms to migrate to pluggable monitor without disruption.
819+
820+
For detailed information, see the [Pluggable Monitor specification](pluggable-monitor-specification.md).
821+
822+
### Verbose parameter
759823

760824
It is possible for the user to enable verbosity from the Preferences panel of the IDEs or Arduino CLI's `--verbose`
761825
flag. This preference is transferred to the command line using the **ACTION.verbose** property (where ACTION is the

Diff for: docs/pluggable-discovery-specification.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ the response to the command is:
4343
The `protocolVersion` field represents the protocol version that will be used in the rest of the communication. There
4444
are three possible cases:
4545

46-
- if the client/IDE supports the same or a more recent version of the protocol than the discovery, then the IDE should
47-
go into a compatibility mode and use the protocol level supported by the discovery.
46+
- if the client/IDE supports the same or a more recent version of the protocol than the discovery, then the clietn/IDE
47+
should go into a compatibility mode and use the protocol level supported by the discovery.
4848
- if the discovery supports a more recent version of the protocol than the client/IDE: the discovery should downgrade
4949
itself into compatibility mode and report a `protocolVersion` that is less than or equal to the one supported by the
5050
client/IDE.

Diff for: docs/pluggable-monitor-specification.md

+253
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
Monitor tools are a special kind of tool used to let the user communicate with the supported boards. A platform
2+
developer can create their own tools following the specification below. These tools must be in the form of command line
3+
executables that can be launched as a subprocess.
4+
5+
They will communicate to the parent process via stdin/stdout, in particular a monitor tool will accept commands as plain
6+
text strings from stdin and will send answers back in JSON format on stdout. Each tool will implement the commands to
7+
open and control communication ports for a specific protocol as specified in this document. The actual I/O data stream
8+
from the communication port will be transferred to the parent process through a separate channel via TCP/IP.
9+
10+
### Pluggable monitor API via stdin/stdout
11+
12+
All the commands listed in this specification must be implemented in the monitor tool.
13+
14+
After startup, the tool will just stay idle waiting for commands. The available commands are: `HELLO`, `DESCRIBE`,
15+
`CONFIGURE`, `OPEN`, `CLOSE` and `QUIT`.
16+
17+
After each command the client always expects a response from the monitor. The monitor must not introduce any delay and
18+
must respond to all commands as fast as possible.
19+
20+
#### HELLO command
21+
22+
`HELLO` **must be the first command sent** to the monitor to tell the name of the client/IDE and the version of the
23+
pluggable monitor protocol that the client/IDE supports. The syntax of the command is:
24+
25+
`HELLO <PROTOCOL_VERSION> "<USER_AGENT>"`
26+
27+
- `<PROTOCOL_VERSION>` is the maximum protocol version supported by the client/IDE (currently `1`)
28+
- `<USER_AGENT>` is the name and version of the client. It must not contain double-quotes (`"`).
29+
30+
some examples:
31+
32+
- `HELLO 1 "Arduino IDE 1.8.13"`
33+
34+
- `HELLO 1 "arduino-cli 1.2.3"`
35+
36+
the response to the command is:
37+
38+
```JSON
39+
{
40+
"eventType": "hello",
41+
"protocolVersion": 1,
42+
"message": "OK"
43+
}
44+
```
45+
46+
The `protocolVersion` field represents the protocol version that will be used in the rest of the communication. There
47+
are three possible cases:
48+
49+
- if the client/IDE supports the same or a more recent version of the protocol than the monitor tool, then the
50+
client/IDE should go into a compatibility mode and use the protocol level supported by the monitor tool.
51+
- if the monitor tool supports a more recent version of the protocol than the client/IDE, then the monitor tool should
52+
downgrade itself into compatibility mode and report a `protocolVersion` that is less than or equal to the one
53+
supported by the client/IDE.
54+
- if the monitor tool cannot go into compatibility mode, it must report the protocol version supported (even if greater
55+
than the version supported by the client/IDE) and the client/IDE may decide to terminate the monitor tool or produce
56+
an error/warning.
57+
58+
#### DESCRIBE command
59+
60+
The `DESCRIBE` command returns a description of the communication port. The description will have metadata about the
61+
port configuration, and which parameters are available to the user.
62+
63+
```JSON
64+
{
65+
"event": "describe",
66+
"message": "ok",
67+
"port_description": {
68+
"protocol": "serial",
69+
"configuration_parameters": {
70+
"baudrate": {
71+
"label": "Baudrate",
72+
"type": "enum",
73+
"values": [
74+
"300", "600", "750", "1200", "2400", "4800", "9600",
75+
"19200", "38400", "57600", "115200", "230400", "460800",
76+
"500000", "921600", "1000000", "2000000"
77+
],
78+
"selected": "9600"
79+
},
80+
"parity": {
81+
"label": "Parity",
82+
"type": "enum",
83+
"values": [ "N", "E", "O", "M", "S" ],
84+
"selected": "N"
85+
},
86+
"bits": {
87+
"label": "Data bits",
88+
"type": "enum",
89+
"values": [ "5", "6", "7", "8", "9" ],
90+
"selected": "8"
91+
},
92+
"stop_bits": {
93+
"label": "Stop bits",
94+
"type": "enum",
95+
"values": [ "1", "1.5", "2" ],
96+
"selected": "1"
97+
}
98+
}
99+
}
100+
}
101+
```
102+
103+
The field `protocol` is the board port protocol identifier, it must match with the corresponding protocol identifier for
104+
a pluggable discovery tool.
105+
106+
`configuration_parameters` is a key/value map that enumerates the available port parameters.
107+
108+
Each parameter has a unique name (`baudrate`, `parity`, etc...), a `type` (in this case only `enum` is allowed but more
109+
types may be added in the future if needed), and the `selected` value for each parameter.
110+
111+
The parameter name can not contain spaces, the allowed characters are alphanumerics, underscore `_`, dot `.`, and dash
112+
`-`.
113+
114+
The `enum` types must have a list of possible `values`.
115+
116+
The client/IDE may expose these configuration values to the user via a config file or a GUI, in this case the `label`
117+
field may be used for a user readable description of the parameter.
118+
119+
#### CONFIGURE command
120+
121+
The `CONFIGURE` command sets configuration parameters for the communication port. The parameters can be changed one at a
122+
time and the syntax is:
123+
124+
`CONFIGURE <PARAMETER_NAME> <VALUE>`
125+
126+
The response to the command is:
127+
128+
```JSON
129+
{
130+
"event": "configure",
131+
"message": "ok",
132+
}
133+
```
134+
135+
or if there is an error:
136+
137+
```JSON
138+
{
139+
"event": "configure",
140+
"error": true,
141+
"message": "invalid value for parameter baudrate: 123456"
142+
}
143+
```
144+
145+
The currently selected parameters or their default value may be obtained using the `DESCRIBE` command.
146+
147+
#### OPEN command
148+
149+
The `OPEN` command opens a communication port with the board, the data exchanged with the board will be transferred to
150+
the Client/IDE via TCP/IP.
151+
152+
The Client/IDE must first TCP-Listen to a randomly selected TCP port and send the address to connect it to the monitor
153+
tool as part of the `OPEN` command. The syntax of the `OPEN` command is:
154+
155+
`OPEN <CLIENT_TCPIP_ADDRESS> <BOARD_PORT>`
156+
157+
For example, let's suppose that the Client/IDE wants to communicate with the serial port `/dev/ttyACM0` using an
158+
hypotetical `serial-monitor` tool, then the sequence of actions to perform will be the following:
159+
160+
1. the Client/IDE must first listen to a random TCP port (let's suppose it chose `32123`)
161+
1. the Client/IDE runs the `serial-monitor` tool and initialize it with the `HELLO` command
162+
1. the Client/IDE sends the command `OPEN 127.0.0.1:32123 /dev/ttyACM0` to the monitor tool
163+
1. the monitor tool opens `/dev/ttyACM0`
164+
1. the monitor tool connects via TCP/IP to `127.0.0.1:32123` and start streaming data back and forth
165+
166+
The answer to the `OPEN` command is:
167+
168+
```JSON
169+
{
170+
"event": "open",
171+
"message": "ok"
172+
}
173+
```
174+
175+
If the monitor tool cannot communicate with the board, or if the tool can not connect back to the TCP port, or if any
176+
other error condition happens:
177+
178+
```JSON
179+
{
180+
"event": "open",
181+
"error": true,
182+
"message": "unknown port /dev/ttyACM23"
183+
}
184+
```
185+
186+
The board port will be opened using the parameters previously set through the `CONFIGURE` command.
187+
188+
Once the port is opened, it may be unexpectedly closed at any time due to hardware failure, or because the Client/IDE
189+
closes the TCP/IP connection, etc. In this case an asynchronous `port_closed` message must be generated from the monitor
190+
tool:
191+
192+
```JSON
193+
{
194+
"event": "port_closed",
195+
"message": "serial port disappeared!"
196+
}
197+
```
198+
199+
or
200+
201+
```JSON
202+
{
203+
"event": "port_closed",
204+
"message": "lost TCP/IP connection with the client!"
205+
}
206+
```
207+
208+
#### CLOSE command
209+
210+
The `CLOSE` command will close the currently opened port and close the TCP/IP connection used to communicate with the
211+
Client/IDE. The answer to the command is:
212+
213+
```JSON
214+
{
215+
"event": "close",
216+
"message": "ok"
217+
}
218+
```
219+
220+
or in case of error
221+
222+
```JSON
223+
{
224+
"event": "close",
225+
"error": true,
226+
"message": "port already closed"
227+
}
228+
```
229+
230+
#### QUIT command
231+
232+
The `QUIT` command terminates the monitor. The response to `QUIT` is:
233+
234+
```JSON
235+
{
236+
"eventType": "quit",
237+
"message": "OK"
238+
}
239+
```
240+
241+
after this output the monitor exits. This command is supposed to always succeed.
242+
243+
#### Invalid commands
244+
245+
If the client sends an invalid or malformed command, the monitor should answer with:
246+
247+
```JSON
248+
{
249+
"eventType": "command_error",
250+
"error": true,
251+
"message": "Unknown command XXXX"
252+
}
253+
```

0 commit comments

Comments
 (0)