Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit fdae9b9

Browse files
committedJul 22, 2021
Add documentation
1 parent feed887 commit fdae9b9

File tree

4 files changed

+604
-13
lines changed

4 files changed

+604
-13
lines changed
 

‎docs/package_index_json-specification.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ Each tool describes a binary distribution of a command line tool. A tool can be:
8080
- a file preprocessor
8181
- a debugger
8282
- a program that performs a firmware upgrade
83+
- a [Pluggable Discovery](pluggable-discovery-specification.md)
8384

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

@@ -215,7 +216,11 @@ Finally, let's see how `PLATFORMS` are made.
215216
"toolsDependencies": [
216217
{ "packager": "arduino", "name": "avr-gcc", "version": "4.8.1-arduino5" },
217218
{ "packager": "arduino", "name": "avrdude", "version": "6.0.1-arduino5" }
218-
]
219+
],
220+
"discoveryDependencies": [
221+
{ "packager": "arduino", "name": "serial-discovery" },
222+
{ "packager": "arduino", "name": "mdns-discovery" }
223+
]
219224
},
220225
```
221226

@@ -234,6 +239,10 @@ Each PLATFORM describes a core for a specific architecture. The fields needed ar
234239
- `toolsDependencies`: the tools needed by this core. They will be installed by Boards Manager along with the platform.
235240
Each tool is referenced by the triple (`packager`, `name`, `version`) as previously said. Note that you can reference
236241
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.
237246

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

‎docs/platform-specification.md

Lines changed: 224 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ A tool may have some actions not defined (it's not mandatory to define all four
615615
tools.avrdude.cmd.path={path}/bin/avrdude
616616
tools.avrdude.config.path={path}/etc/avrdude.conf
617617

618-
tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
618+
tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" -p{build.mcu} -c{upload.port.protocol} -P{upload.port.address} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
619619

620620
A **{runtime.tools.TOOL_NAME.path}** and **{runtime.tools.TOOL_NAME-TOOL_VERSION.path}** property is generated for the
621621
tools of Arduino AVR Boards and any other platform installed via Boards Manager. **{runtime.tools.TOOL_NAME.path}**
@@ -625,6 +625,64 @@ The tool configuration properties are available globally without the prefix. For
625625
property can be used as **{cmd.path}** inside the recipe, and the same happens for all the other avrdude configuration
626626
variables.
627627

628+
#### Pluggable Discovery
629+
630+
Discovery tools are a special kind of tools that are used to find supported boards, a platform must declare one or more
631+
Pluggable Discoveries in its `platform.txt`. It's ok to use another platform discovery or the builtin ones if necessary.
632+
633+
There are two different syntaxes to declare discoveries, if the platform uses just one discovery:
634+
635+
```
636+
discovery.required=PLATFORM:DISCOVERY_NAME
637+
```
638+
639+
instead if it needs multiple discoveries:
640+
641+
```
642+
discovery.required.0=PLATFORM:DISCOVERY_ID_1
643+
discovery.required.1=PLATFORM:DISCOVERY_ID_2
644+
```
645+
646+
A platform that supports only boards connected to the serial can easily use the builtin `serial-discovery` without
647+
creating a custom Pluggable Discovery:
648+
649+
```
650+
discovery.required=builtin:serial-discovery
651+
```
652+
653+
if it supports also boards connected to the network it can use the builtin `mdns-discovery`:
654+
655+
```
656+
discovery.required.0=builtin:serial-discovery
657+
discovery.required.1=builtin:mdns-discovery
658+
```
659+
660+
Since the above syntax requires adding a discovery in the `discoveryDependencies` field in the platform
661+
`package_index.json` it might be cumbersome to do it before releasing it so we also provide another syntax to ease
662+
development:
663+
664+
```
665+
discovery.DISCOVERY_ID.pattern=DISCOVERY_RECIPE
666+
```
667+
668+
`DISCOVERY_ID` must be replaced by a unique identifier for the particular discovery and `DISCOVERY_RECIPE` must be
669+
replaced by the command line to launch the discovery. An example could be:
670+
671+
```
672+
## Teensy Ports Discovery
673+
discovery.teensy.pattern="{runtime.tools.teensy_ports.path}/hardware/tools/teensy_ports" -J2
674+
```
675+
676+
We strongly recommend not using this syntax on released platforms but only for development purposes.
677+
678+
For backward compatibility, if a platform does not declare any discovery (using the `discovery.*` properties in
679+
`platform.txt`) it will automatically inherits `builtin:serial-discovery` and `builtin:mdns-discovery` (but not other
680+
builtin discoveries that may be possibly added in the future). This will allow all legacy non-pluggable platforms to
681+
migrate to pluggable discovery without disruption.
682+
683+
For detailed information see the [Pluggable Discovery specification](pluggable-discovery-specification.md)
684+
documentation.
685+
628686
#### Verbose parameter
629687

630688
It is possible for the user to enable verbosity from the Preferences panel of the IDEs or Arduino CLI's `--verbose`
@@ -651,26 +709,48 @@ The Upload action is triggered when the user clicks on the "Upload" button on th
651709
[`arduino-cli upload`](commands/arduino-cli_upload.md). Arduino uses the term "upload" for the process of transferring a
652710
program to the Arduino board.
653711

654-
The **upload.tool** property determines the tool to be used for upload. A specific **upload.tool** property should be
655-
defined for every board in boards.txt:
712+
The **upload.tool.<protocol_name\>** property determines the tool to be used for upload. A specific
713+
**upload.tool.<protocol_name\>** property should be defined for every board in boards.txt:
656714

657715
[......]
658-
uno.upload.tool=avrdude
716+
uno.upload.tool.serial=avrdude
659717
[......]
660-
leonardo.upload.tool=avrdude
718+
leonardo.upload.tool.serial=avrdude
719+
leonardo.upload.tool.network=arduino_ota
661720
[......]
662721

722+
When the user tries to upload using a certain protocol but the board doesn't support it it will fallback to `default` if
723+
specified. A board can always specify a `default` protocol even if others are defined:
724+
725+
[......]
726+
uno.upload.tool.default=avrdude
727+
[......]
728+
leonardo.upload.tool.default=avrdude
729+
leonardo.upload.tool.network=arduino_ota
730+
[......]
731+
732+
`default` is also used when no upload address is provided by the user, this can be done only for boards that use upload
733+
tools with builtin port detection like `openocd`.
734+
735+
For backward compatibility with IDE 1.8.15 and older the previous syntax is still supported:
736+
737+
uno.upload.tool=avrdude
738+
739+
The previous syntax is equivalent to:
740+
741+
uno.upload.tool.default=avrdude
742+
663743
Other upload parameters can also be defined for the board. For example, in the Arduino AVR Boards boards.txt we have:
664744

665745
[.....]
666746
uno.name=Arduino Uno
667-
uno.upload.tool=avrdude
747+
uno.upload.tool.serial=avrdude
668748
uno.upload.protocol=arduino
669749
uno.upload.maximum_size=32256
670750
uno.upload.speed=115200
671751
[.....]
672752
leonardo.name=Arduino Leonardo
673-
leonardo.upload.tool=avrdude
753+
leonardo.upload.tool.serial=avrdude
674754
leonardo.upload.protocol=avr109
675755
leonardo.upload.maximum_size=28672
676756
leonardo.upload.speed=57600
@@ -681,9 +761,112 @@ Other upload parameters can also be defined for the board. For example, in the A
681761
Most **{upload.XXXX}** variables are used later in the avrdude upload recipe in platform.txt:
682762

683763
[.....]
684-
tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
764+
tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} -p{build.mcu} -c{upload.port.protocol} -P{upload.port.address} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"
685765
[.....]
686766

767+
If necessary the same property can be defined multiple times for different protocols:
768+
769+
leonardo.upload.serial.maximum_size=28672
770+
leonardo.upload.network.maximum_size=256
771+
772+
The two above properties will be available as **{upload.serial.maximum_size}** and **{upload.network.maximum_size}**.
773+
774+
#### Properties from Pluggable Discovery
775+
776+
If a platform supports Pluggable Discovery it can also use the port's properties returned by a discovery. For example,
777+
the following port metadata coming from a pluggable discovery:
778+
779+
{
780+
"eventType": "add",
781+
"port": {
782+
"address": "/dev/ttyACM0",
783+
"label": "ttyACM0",
784+
"protocol": "serial",
785+
"protocolLabel": "Serial Port (USB)",
786+
"properties": {
787+
"pid": "0x804e",
788+
"vid": "0x2341",
789+
"serialNumber": "EBEABFD6514D32364E202020FF10181E",
790+
"name": "ttyACM0"
791+
}
792+
}
793+
}
794+
795+
will be available on the recipe as the variables:
796+
797+
{upload.port.address} = /dev/ttyACM0
798+
{upload.port.label} = ttyACM0
799+
{upload.port.protocol} = serial
800+
{upload.port.protocolLabel} = Serial Port (USB)
801+
{upload.port.properties.pid} = 0x8043
802+
{upload.port.properties.vid} = 0x2341
803+
{upload.port.properties.serialNumber} = EBEABFD6514D32364E202020FF10181E
804+
{upload.port.properties.name} = ttyACM0
805+
{serial.port} = /dev/ttyACM0 # for backward compatibility
806+
{serial.port.file} = ttyACM0 # only because protocol=serial
807+
808+
Here another example:
809+
810+
{
811+
"eventType": "add",
812+
"port": {
813+
"address": "192.168.1.232",
814+
"label": "SSH on my-board (192.168.1.232)",
815+
"protocol": "ssh",
816+
"protocolLabel": "SSH Network port",
817+
"properties": {
818+
"macprefix": "AA:BB:CC",
819+
"macaddress": "AA:BB:CC:DD:EE:FF"
820+
}
821+
}
822+
}
823+
824+
that is translated to:
825+
826+
{upload.port.address} = 192.168.1.232
827+
{upload.port.label} = SSH on my-board (192.168.1.232)
828+
{upload.port.protocol} = ssh
829+
{upload.port.protocolLabel} = SSH Network port
830+
{upload.port.properties.macprefix} = AA:BB:CC
831+
{upload.port.properties.macaddress} = AA:BB:CC:DD:EE:FF
832+
{serial.port} = 192.168.1.232 # for backward compatibility
833+
834+
This configuration, together with protocol selection, allows to remove the hardcoded `network_pattern`, now we can
835+
replace the legacy recipe (split into multiple lines for clarity):
836+
837+
tools.bossac.upload.network_pattern="{runtime.tools.arduinoOTA.path}/bin/arduinoOTA"
838+
-address {serial.port} -port 65280
839+
-sketch "{build.path}/{build.project_name}.bin"
840+
841+
with:
842+
843+
tools.arduino_ota.upload.pattern="{runtime.tools.arduinoOTA.path}/bin/arduinoOTA"
844+
-address {upload.port.address} -port 65280
845+
-sketch "{build.path}/{build.project_name}.bin"
846+
847+
#### User provided fields
848+
849+
Some upload recipes might require custom fields that must be provided by the user, like username and password to upload
850+
over the network. In this case the recipe must use the special placeholder {upload.field.FIELD_NAME} where FIELD_NAME
851+
must be declared separately in the recipe using the following format:
852+
853+
tools.UPLOAD_RECIPE_ID.upload.field.FIELD_NAME=FIELD_LABEL
854+
tools.UPLOAD_RECIPE_ID.upload.field.FIELD_NAME.secret=true
855+
856+
FIELD_LABEL is the label shown in the graphical prompt to ask the user to enter the value of the field. The secret
857+
property is optional and it should be set to true if the field is a secret (like passwords or token).
858+
859+
Let’s see how a complete example will look like:
860+
861+
tools.arduino_ota.upload.field.username=Username
862+
tools.arduino_ota.upload.field.password=Password
863+
tools.arduino_ota.upload.field.password.secret=true
864+
tools.arduino_ota.upload.pattern="{runtime.tools.arduinoOTA.path}/bin/arduinoOTA"
865+
-address {upload.port.address} -port 65280
866+
-username "{upload.field.username}
867+
-password "{upload.field.password}"
868+
-sketch "{build.path}/{build.project_name}.bin"
869+
687870
#### Upload verification
688871

689872
Upload verification can be enabled via the Arduino IDE's **File > Preferences > Verify code after upload** or
@@ -744,10 +927,14 @@ support uploading via programmer.
744927

745928
The full path (e.g., `/dev/ttyACM0`) of the port selected via the IDE or
746929
[`arduino-cli upload`](commands/arduino-cli_upload.md)'s `--port` option is available as a configuration property
747-
**{serial.port}**.
930+
**{upload.port.address}**.
748931

749932
The file component of the port's path (e.g., `ttyACM0`) is available as the configuration property
750-
**{serial.port.file}**.
933+
**{upload.port.label}**.
934+
935+
For backward compatibility with IDE 1.8.15 and older the old property **serial.port** is still available and is
936+
identical to **{upload.port.address}**. Instead **serial.port.file** is identical to **{upload.port.label}** and
937+
available only if protocol in use is **serial**.
751938

752939
### Upload using an external programmer
753940

@@ -756,7 +943,17 @@ The `program` action is triggered via the **Sketch > Upload Using Programmer** f
756943
compiled sketch to a board using an external programmer.
757944

758945
The **program.tool** property determines the tool to be used for this action. This property is typically defined for
759-
each programmer in [programmers.txt](#programmerstxt):
946+
each programmer in [programmers.txt](#programmerstxt) and uses the same syntax as `upload` action:
947+
948+
[......]
949+
usbasp.program.tool.serial=avrdude
950+
[......]
951+
arduinoasisp.program.tool.serial=avrdude
952+
[......]
953+
arduinoisp.program.tool.default=avrdude
954+
[......]
955+
956+
For backward compatibility with IDE 1.8.15 and older the previous syntax is still supported:
760957

761958
[......]
762959
usbasp.program.tool=avrdude
@@ -786,7 +983,18 @@ the board.
786983
1. `bootloader` is used to flash the bootloader to the board
787984

788985
The **bootloader.tool** property determines the tool to be used for the `erase` and `bootloader` actions both. This
789-
property is typically defined for each board in boards.txt:
986+
property is typically defined for each board in boards.txt and uses the same syntax as `upload` action:
987+
988+
[......]
989+
uno.bootloader.tool.serial=avrdude
990+
[......]
991+
leonardo.upload.tool.serial=avrdude
992+
leonardo.upload.tool.network=arduino_ota
993+
[......]
994+
duemilanove.upload.tool.default=avrdude
995+
[......]
996+
997+
For backward compatibility with IDE 1.8.15 and older the previous syntax is still supported:
790998

791999
[......]
7921000
uno.bootloader.tool=avrdude
@@ -1009,3 +1217,7 @@ software is in use:
10091217
This behavior
10101218
[can be configured](https://arduino.github.io/arduino-cli/latest/commands/arduino-cli_core_install/#options)
10111219
- **Arduino Pro IDE**: (since 0.1.0) runs the script for any installed platform.
1220+
1221+
```
1222+
1223+
```
Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
These tools must be in the form of executables that can be launched as a subprocess using a `platform.txt` command line
2+
recipe. They will communicate to the parent process via stdin/stdout, in particular a discovery will accept commands as
3+
plain text strings from stdin and will send answers back in JSON format on stdout. Each tool will implement the commands
4+
to list and enumerate ports for a specific protocol as specified in this document.
5+
6+
### Pluggable discovery API via stdin/stdout
7+
8+
All the commands listed in this specification must be implemented in the discovery.
9+
10+
After startup, the tool will just stay idle waiting for commands. The available commands are: `HELLO`, `START`, `STOP`,
11+
`QUIT`, `LIST` and `START_SYNC`.
12+
13+
After each command the client always expect a response from the discovery. The discovery must not introduce any delay
14+
and must respond to all commands as fast as possible.
15+
16+
#### HELLO command
17+
18+
`HELLO` **must be the first command sent** to the discovery to tell the name of the client/IDE and the version of the
19+
pluggable discovery protocol that the client/IDE supports. The syntax of the command is:
20+
21+
`HELLO <PROTOCOL_VERSION> "<USER_AGENT>"`
22+
23+
- `<PROTOCOL_VERSION>` is the maximum protocol version supported by the client/IDE (currently `1`)
24+
25+
- `<USER_AGENT>` is the name and version of the client (double-quotes `"` are not allowed)
26+
27+
some examples:
28+
29+
- `HELLO 1 "Arduino IDE 1.8.13"`
30+
31+
- `HELLO 1 "arduino-cli 1.2.3"`
32+
33+
the response to the command is:
34+
35+
```JSON
36+
{
37+
"eventType": "hello",
38+
"protocolVersion": 1,
39+
"message": "OK"
40+
}
41+
```
42+
43+
The `protocolVersion` field represents the protocol version that will be used in the rest of the communication. There
44+
are three possible cases:
45+
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.
48+
- if the discovery supports a more recent version of the protocol than the client/IDE: the discovery should downgrade
49+
itself into compatibility mode and report a `protocolVersion` that is less than or equal to the one supported by the
50+
client/IDE.
51+
- if the discovery cannot go into compatibility mode, it will report the protocol version supported (even if greater
52+
than the version supported by the client/IDE) and the client/IDE may decide to terminate the discovery or produce an
53+
error/warning.
54+
55+
#### START command
56+
57+
The `START` command initializes and start the discovery internal subroutines. This command must be called before `LIST`
58+
or `START_SYNC`. The response to the start command is:
59+
60+
```JSON
61+
{
62+
"eventType": "start",
63+
"message": "OK"
64+
}
65+
```
66+
67+
If the discovery could not start, for any reason, it must report the error with:
68+
69+
```JSON
70+
{
71+
"eventType": "start",
72+
"error": true,
73+
"message": "Permission error"
74+
}
75+
```
76+
77+
The `error` field must be set to `true` and the `message` field should contain a description of the error.
78+
79+
#### STOP command
80+
81+
The `STOP` command stops the discovery internal subroutines and possibly free the internally used resources. This
82+
command should be called if the client wants to pause the discovery for a while. The response to the command is:
83+
84+
```JSON
85+
{
86+
"eventType": "stop",
87+
"message": "OK"
88+
}
89+
```
90+
91+
If an error occurs:
92+
93+
```JSON
94+
{
95+
"eventType": "stop",
96+
"error": true,
97+
"message": "Resource busy"
98+
}
99+
```
100+
101+
The `error` field must be set to `true` and the `message` field should contain a description of the error.
102+
103+
#### QUIT command
104+
105+
The `QUIT` command terminates the discovery. The response to `QUIT` is:
106+
107+
```JSON
108+
{
109+
"eventType": "quit",
110+
"message": "OK"
111+
}
112+
```
113+
114+
after this output the discovery exits. This command is supposed to always succeed.
115+
116+
#### LIST command
117+
118+
The `LIST` command executes an enumeration of the ports and returns a list of the available ports at the moment of the
119+
call. The format of the response is the following:
120+
121+
```
122+
{
123+
"eventType": "list",
124+
"ports": [
125+
{
126+
"address": <-- THE ADDRESS OF THE PORT
127+
"label": <-- HOW THE PORT IS DISPLAYED ON THE GUI
128+
"protocol": <-- THE PROTOCOL USED BY THE BOARD
129+
"protocolLabel": <-- HOW THE PROTOCOL IS DISPLAYED ON THE GUI
130+
"properties": {
131+
<-- A LIST OF PROPERTIES OF THE PORT
132+
}
133+
}, {
134+
... <-- OTHER PORTS...
135+
}
136+
]
137+
}
138+
```
139+
140+
The `ports` field contains a list of the available ports.
141+
142+
Each port has:
143+
144+
- an `address` (for example `/dev/ttyACM0` for serial ports or `192.168.10.100` for network ports)
145+
146+
- a `label` that is the human readable form of the `address` (it may be for example `ttyACM0` or
147+
`SSH on 192.168.10.100`)
148+
149+
- `protocol` is the protocol identifier (such as `serial` or `dfu` or `ssh`)
150+
151+
- `protocolLabel` is the `protocol` in human readable form (for example `Serial port` or `DFU USB` or `Network (ssh)`)
152+
153+
- `properties` is a list of key/value pairs that represent information relative to the specific port
154+
155+
To make the above more clear let’s show an example with the `serial_discovery`:
156+
157+
```JSON
158+
{
159+
"eventType": "list",
160+
"ports": [
161+
{
162+
"address": "/dev/ttyACM0",
163+
"label": "ttyACM0",
164+
"protocol": "serial",
165+
"protocolLabel": "Serial Port (USB)",
166+
"properties": {
167+
"pid": "0x804e",
168+
"vid": "0x2341",
169+
"serialNumber": "EBEABFD6514D32364E202020FF10181E",
170+
"name": "ttyACM0"
171+
}
172+
}
173+
]
174+
}
175+
```
176+
177+
In this case the serial port metadata comes from an USB serial converter. Inside the `properties` we have all the
178+
properties of the port, and some of them may be useful for product identification (in this case only USB VID/PID is
179+
useful to identify the board model).
180+
181+
The `LIST` command performs a one-shot polling of the ports. The discovery should answer as soon as reasonably possible,
182+
without any additional delay.
183+
184+
Some discoveries may require some time to discover a new port (for example network protocols like MDNS, Bluetooth, etc.
185+
requires some seconds to receive the broadcasts from all available clients) in that case is fine to answer with an empty
186+
or incomplete list.
187+
188+
If an error occurs and the discovery can't complete the enumeration is must report the error with:
189+
190+
```JSON
191+
{
192+
"eventType": "list",
193+
"error": true,
194+
"message": "Resource busy"
195+
}
196+
```
197+
198+
The `error` field must be set to `true` and the `message` field should contain a description of the error.
199+
200+
#### START_SYNC command
201+
202+
The `START_SYNC` command puts the tool in "events" mode: the discovery will send `add` and `remove` events each time a
203+
new port is detected or removed respectively. If the discovery goes into "events" mode successfully the response to this
204+
command is:
205+
206+
```JSON
207+
{
208+
"eventType": "start_sync",
209+
"message": "OK"
210+
}
211+
```
212+
213+
After this message the discoery will send `add` and `remove` event asyncronoushly (more on that later). If an error
214+
occurs and the discovery can't go in "events" mode the error must be reported as:
215+
216+
```JSON
217+
{
218+
"eventType": "start_sync",
219+
"error": true,
220+
"message": "Resource busy"
221+
}
222+
```
223+
224+
The `error` field must be set to `true` and the `message` field should contain a description of the error.
225+
226+
Once in "event" mode, the discovery is allowed to send `add` and `remove` messages asynchronously in realtime, this
227+
means that the client must be able to handle these incoming messages at any moment.
228+
229+
The `add` event looks like the following:
230+
231+
```JSON
232+
{
233+
"eventType": "add",
234+
"port": {
235+
"address": "/dev/ttyACM0",
236+
"label": "ttyACM0",
237+
"properties": {
238+
"pid": "0x804e",
239+
"vid": "0x2341",
240+
"serialNumber": "EBEABFD6514D32364E202020FF10181E",
241+
"name": "ttyACM0"
242+
},
243+
"protocol": "serial",
244+
"protocolLabel": "Serial Port (USB)"
245+
}
246+
}
247+
```
248+
249+
It basically provides the same information as the `list` event but for a single port. After calling `START_SYNC` an
250+
initial burst of add events must be generated in sequence to report all the ports available at the moment of the start.
251+
252+
The `remove` event looks like the following:
253+
254+
```JSON
255+
{
256+
"eventType": "remove",
257+
"port": {
258+
"address": "/dev/ttyACM0",
259+
"protocol": "serial"
260+
}
261+
}
262+
```
263+
264+
The content is straightforward, in this case only the `address` and `protocol` fields are reported.
265+
266+
If the information about a port needs to be updated the discovery may send a new `add` message for the same port address
267+
and protocol without sending a `remove` first: this means that all the previous information about the port must be
268+
discarded and replaced with the new one.
269+
270+
#### Invalid commands
271+
272+
If the client sends an invalid or malformed command, the discovery should answer with:
273+
274+
```JSON
275+
{
276+
"eventType": "command_error",
277+
"error": true,
278+
"message": "Unknown command XXXX"
279+
}
280+
```
281+
282+
### Board identification
283+
284+
The `properties` associated to a port can be used to identify the board attached to that port. The algorithm is simple:
285+
286+
- each board listed in the platform file `boards.txt` may declare a set of `upload_port.*` properties
287+
- if each `upload_port.*` property has a match in the `properties` set coming from the discovery then the board is a
288+
“candidate” board attached to that port.
289+
290+
Some port `properties` may not be precise enough to uniquely identify a board, in that case more boards may match the
291+
same set of `properties`, that’s why we called it “candidate”.
292+
293+
Let’s see an example to clarify things a bit, let's suppose that we have the following `properties` coming from the
294+
serial discovery:
295+
296+
```JSON
297+
"port": {
298+
"address": "/dev/ttyACM0",
299+
"properties": {
300+
"pid": "0x804e",
301+
"vid": "0x2341",
302+
"serialNumber": "EBEABFD6514D32364E202020FF10181E",
303+
"name": "ttyACM0"
304+
}
305+
```
306+
307+
in this case we can use `vid` and `pid` to identify the board. The `serialNumber`, instead, is unique for that specific
308+
instance of the board so it can't be used to identify the board model. Let’s suppose we have the following `boards.txt`:
309+
310+
```
311+
# Arduino Zero (Programming Port)
312+
# ---------------------------------------
313+
arduino_zero_edbg.name=Arduino Zero (Programming Port)
314+
arduino_zero_edbg.upload_port.vid=0x03eb
315+
arduino_zero_edbg.upload_port.pid=0x2157
316+
[...CUT...]
317+
# Arduino Zero (Native USB Port)
318+
# --------------------------------------
319+
arduino_zero_native.name=Arduino Zero (Native USB Port)
320+
arduino_zero_native.upload_port.0.vid=0x2341
321+
arduino_zero_native.upload_port.0.pid=0x804d
322+
arduino_zero_native.upload_port.1.vid=0x2341
323+
arduino_zero_native.upload_port.1.pid=0x004d
324+
arduino_zero_native.upload_port.2.vid=0x2341
325+
arduino_zero_native.upload_port.2.pid=0x824d
326+
arduino_zero_native.upload_port.3.vid=0x2341
327+
arduino_zero_native.upload_port.3.pid=0x024d
328+
[...CUT...]
329+
# Arduino MKR1000
330+
# -----------------------
331+
mkr1000.name=Arduino MKR1000
332+
mkr1000.upload_port.0.vid=0x2341 <------- MATCHING IDs
333+
mkr1000.upload_port.0.pid=0x804e <------- MATCHING IDs
334+
mkr1000.upload_port.1.vid=0x2341
335+
mkr1000.upload_port.1.pid=0x004e
336+
mkr1000.upload_port.2.vid=0x2341
337+
mkr1000.upload_port.2.pid=0x824e
338+
mkr1000.upload_port.3.vid=0x2341
339+
mkr1000.upload_port.3.pid=0x024e
340+
[...CUT...]
341+
```
342+
343+
As we can see the only board that has the two properties matching is the `mkr1000`, in this case the CLI knows that the
344+
board is surely an MKR1000.
345+
346+
Note that `vid` and `pid` properties are just free text key/value pairs: the discovery may return basically anything,
347+
the board just needs to have the same properties defined in `boards.txt` as `upload_port.*` to be identified.
348+
349+
We can also specify multiple identification properties for the same board using the `.N` suffix, for example:
350+
351+
```
352+
myboard.name=My Wonderful Arduino Compatible Board
353+
myboard.upload_port.pears=20
354+
myboard.upload_port.apples=30
355+
```
356+
357+
will match on `pears=20, apples=30` but:
358+
359+
```
360+
myboard.name=My Wonderful Arduino Compatible Board
361+
myboard.upload_port.0.pears=20
362+
myboard.upload_port.0.apples=30
363+
myboard.upload_port.1.pears=30
364+
myboard.upload_port.1.apples=40
365+
```
366+
367+
will match on both `pears=20, apples=30` and `pears=30, apples=40` but not `pears=20, apples=40`, in that sense each
368+
"set" of identification properties is indepentent from each other and cannot be mixed for port matching.

‎mkdocs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ nav:
7070
- board details: commands/arduino-cli_board_details.md
7171
- board list: commands/arduino-cli_board_list.md
7272
- board listall: commands/arduino-cli_board_listall.md
73+
- board search: commands/arduino-cli_board_search.md
7374
- burn-bootloader: commands/arduino-cli_burn-bootloader.md
7475
- cache: commands/arduino-cli_cache.md
7576
- cache clean: commands/arduino-cli_cache_clean.md
@@ -121,6 +122,7 @@ nav:
121122
- sketch-specification.md
122123
- library-specification.md
123124
- platform-specification.md
125+
- Pluggable Discovery specification: pluggable-discovery-specification.md
124126
- Package index specification: package_index_json-specification.md
125127

126128
extra_css:

0 commit comments

Comments
 (0)
Please sign in to comment.