mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #18455 from maribu/doc/doxygen/src/flashing.md
doc: Add high-level documentation on flashing boards
This commit is contained in:
commit
ecbe686b03
@ -764,6 +764,7 @@ INPUT = ../../doc.txt \
|
||||
src/porting-boards.md \
|
||||
src/driver-guide.md \
|
||||
src/getting-started.md \
|
||||
src/flashing.md \
|
||||
src/build-in-docker.md \
|
||||
../../tests/README.md \
|
||||
src/build-system-basics.md \
|
||||
|
@ -39,215 +39,6 @@ You can configure your own files that will be parsed by the build system main
|
||||
* Define your custom targets
|
||||
* Override default targets
|
||||
|
||||
|
||||
Handling multiple boards with udev-rules {#multiple-boards-udev}
|
||||
========================================
|
||||
|
||||
When developing and working with multiple boards the default `PORT` configuration
|
||||
for a particular board might not apply anymore so `PORT` will need to be specified
|
||||
whenever calling `make term/test`. This can also happen if multiple `DEBUGGERS/PROGRAMMERS`
|
||||
are present so `DEBUG_ADAPTER_ID` will also need to be passed. Keeping track of
|
||||
this will become annoying.
|
||||
|
||||
One way of handling this is to use `udev` rules to define `SYMLINKS` between the
|
||||
boards serial port (`riot/tty-<board-name>`) and the actual serial port
|
||||
(dev/ttyACM* or other). With this we can query the rest of the boards serial
|
||||
`dev` information (`DEBUG_ADAPTER_ID`, `PORT`, etc.) to always flash and open a
|
||||
terminal on the correct port.
|
||||
|
||||
Procedure:
|
||||
|
||||
- use `udevadm info /dev/ttyACM0` to query the udev database for information on
|
||||
device on port `/dev/ttyACM0`.
|
||||
|
||||
or use `udevadm info --attribute-walk --name /dev/ttyACM0` for more detailed
|
||||
output when the first level of information isn't enough
|
||||
|
||||
- create a udev rule with information of the device and one parent to create a
|
||||
matching rule in `/etc/udev/rules.d/70-riotboards.rules`.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
# samr21-xpro
|
||||
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", \
|
||||
ATTRS{idProduct}=="2111", ATTRS{manufacturer}=="Atmel Corp.", \
|
||||
ATTRS{serial}=="ATML2127031800004957", SYMLINK+="riot/tty-samr21-xpro"
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- reload rules: `udevadm control --reload-rules`
|
||||
|
||||
- Boards `PORT` are symlinked to /dev/riot/tty-`board-name`.
|
||||
|
||||
- Create a `makefile.pre` that will query the real `PORT` and the `DEBUG_ADAPTER_ID`
|
||||
from the `SYMLINK` info
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
PORT = /dev/riot/tty-$(BOARD)
|
||||
DEBUG_ADAPTER_ID = $(\
|
||||
shell udevadm info -q property $(PORT) |\
|
||||
sed -n ’/ID_SERIAL_SHORT/ {s/ID_SERIAL_SHORT=//p}’)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- You can now add `makefile.pre` to `RIOT_MAKEFILES_GLOBAL_PRE` as an environment
|
||||
variable or on each `make` call:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
$ RIOT_MAKEFILES_GLOBAL_PRE=/path/to/makefile.pre make -C examples/hello-world flash term
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
_note_: if set as an environment variable it would be a good idea to add a variable
|
||||
to enable/disable it, e.g:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
ifeq (1,$(ENABLE_LOCAL_BOARDS))
|
||||
PORT = /dev/riot/tty-$(BOARD)
|
||||
DEBUG_ADAPTER_ID = $(\
|
||||
shell udevadm info -q property $(PORT) |\
|
||||
sed -n ’/ID_SERIAL_SHORT/ {s/ID_SERIAL_SHORT=//p}’)
|
||||
endif
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Handling multiple versions of the same BOARD
|
||||
-------------------------------------------
|
||||
|
||||
The above procedure works fine when handling different boards, but not
|
||||
multiple times the same board, e.g: multiple `samr21-xpro`.
|
||||
|
||||
An option for this would be to add an identifier of that board to the mapped
|
||||
`riot/tty-*`, there are multiple ways of handling this but in the end it means
|
||||
having a way to identify every copy.
|
||||
|
||||
Another way would be to map the `DEBUG_ADAPTER_ID` in the name:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
SYMLINK+="riot/node-$attr{serial}
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
But it will require to know in advance the serial number of each board you want
|
||||
to use. Another option would be to add some kind of numbering and defining
|
||||
multiple symlinks for each board. e.g. for `samr21-xpro` number `n`:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
# samr21-xpro
|
||||
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", \
|
||||
ATTRS{idProduct}=="2111", ATTRS{manufacturer}=="Atmel Corp.", \
|
||||
ATTRS{serial}=="ATML2127031800004957", SYMLINK+="riot/tty-samr21-xpro", \
|
||||
SYMLINK+="riot/tty-samr21-xpro-n"
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Then, when flashing, the number can be specified and the parsing adapted:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
ifneq(,$(BOARD_NUM))
|
||||
PORT = /dev/riot/tty-$(BOARD)-$(BOARD_NUM)
|
||||
else
|
||||
PORT = /dev/riot/tty-$(BOARD)
|
||||
endif
|
||||
DEBUG_ADAPTER_ID = $(\
|
||||
shell udevadm info -q property $(PORT) |\
|
||||
sed -n ’/ID_SERIAL_SHORT/ {s/ID_SERIAL_SHORT=//p}’)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
BOARD=samr21-xpro BOARD_NUM=n make flash term
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the end, this would be the same as using the serial, but a simple number might
|
||||
be easier to handle.
|
||||
|
||||
Notes
|
||||
-----
|
||||
Udev only parses SUBSYSTEM and one parent. For others, we will rely on ENV
|
||||
variables defined by 60-serial.rules
|
||||
|
||||
So the current filename should be higher than 60-serial.rules
|
||||
|
||||
If for some reason re-writing the serial is needed there is a windows tool:
|
||||
https://remoteqth.com/wiki/index.php?page=How+to+set+usb+device+SerialNumber
|
||||
|
||||
|
||||
Documentation:
|
||||
--------------
|
||||
* The whole documentation
|
||||
http://reactivated.net/writing_udev_rules.html#udevinfo
|
||||
* Udev manpage
|
||||
http://manpages.ubuntu.com/manpages/eoan/en/man7/udev.7.html
|
||||
|
||||
Handling multiple boards without udev-rules {#multiple-boards-no-udev}
|
||||
===========================================
|
||||
|
||||
This is a simpler approach to the above mentioned issue. The solution here only
|
||||
uses a makefile script for selecting the debugger and serial port. No
|
||||
administrative privileges (e.g. to configure Udev) are required.
|
||||
|
||||
One of the limitations of the solution described here is that it currently
|
||||
doesn't work with multiple boards of the same type. This limitation is a
|
||||
limitation of the script and not of the mechanism used, it is possible to adapt
|
||||
the script to support multiple boards of the same type. This modification is
|
||||
left as an exercise to the reader.
|
||||
|
||||
The following Make snippet is used:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
LOCAL_BOARD_MAP ?= 1
|
||||
|
||||
# Adapt this list to your board collection
|
||||
SERIAL_nucleo-f103rb ?= 066BFF343633464257254156
|
||||
SERIAL_same54-xpro ?= ATML2748051800005053
|
||||
SERIAL_samr21-xpro ?= ATML2127031800008360
|
||||
SERIAL_nrf52dk ?= 000682223007
|
||||
|
||||
ifeq (1,$(LOCAL_BOARD_MAP))
|
||||
|
||||
# Retrieve the serial of the selected board
|
||||
BOARD_SERIAL = $(SERIAL_$(BOARD))
|
||||
|
||||
# Check if there is a serial for the board
|
||||
ifneq (,$(BOARD_SERIAL))
|
||||
|
||||
# Set the variables used by various debug tools to the selected serial
|
||||
SERIAL ?= $(BOARD_SERIAL)
|
||||
DEBUG_ADAPTER_ID ?= $(BOARD_SERIAL)
|
||||
JLINK_SERIAL ?= $(BOARD_SERIAL)
|
||||
|
||||
# Use the existing script to grab the matching /dev/ttyACM* device
|
||||
PORT ?= $(shell $(RIOTTOOLS)/usb-serial/ttys.py --most-recent --format path --serial $(SERIAL))
|
||||
endif
|
||||
endif
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The array of board serial numbers has to be edited to match your local boards.
|
||||
The serial numbers used here is the USB device serial number as reported by
|
||||
the debugger hardware. With the `make list-ttys` it is reported as the 'serial':
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
$ make list-ttys
|
||||
path | driver | vendor | model | model_db | serial | ctime
|
||||
-------------|---------|--------------------------|--------------------------------------|-----------------------|--------------------------|---------
|
||||
/dev/ttyUSB0 | cp210x | Silicon Labs | CP2102 USB to UART Bridge Controller | CP210x UART Bridge | 0001 | 15:58:13
|
||||
/dev/ttyACM1 | cdc_acm | STMicroelectronics | STM32 STLink | ST-LINK/V2.1 | 0671FF535155878281151932 | 15:58:04
|
||||
/dev/ttyACM3 | cdc_acm | Arduino (www.arduino.cc) | EOS High Power | Mega ADK R3 (CDC ACM) | 75230313733351110120 | 15:59:57
|
||||
/dev/ttyACM2 | cdc_acm | SEGGER | J-Link | J-Link | 000683475134 | 12:41:36
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the above make snippet is included as `RIOT_MAKEFILES_GLOBAL_PRE`, the
|
||||
serial number of the USB device is automatically set if the used board is
|
||||
included in the script. This will then ensure that the board debugger is used
|
||||
for flashing and the board serial device is used when starting the serial
|
||||
console.
|
||||
|
||||
It supports command line parameters to filter by vendor name, model name, serial
|
||||
number, or driver. In addition, the `--most-recent` argument will only print the
|
||||
most recently added interface (out of those matching the filtering by vendor,
|
||||
model, etc.). The `--format path` argument will result in only the device path
|
||||
being printed for convenient use in scripts.
|
||||
|
||||
Handling multiple boards: Simplest approach {#multiple-boards-simple}
|
||||
===========================================
|
||||
|
||||
Passing `MOST_RECENT_PORT=1` as environment variable or as parameter to
|
||||
make will result in the most recently connected board being preferred over the
|
||||
default PORT for the selected board.
|
||||
|
||||
Analyze dependency resolution {#analyze-depedency-resolution}
|
||||
=============================
|
||||
|
||||
|
351
doc/doxygen/src/flashing.md
Normal file
351
doc/doxygen/src/flashing.md
Normal file
@ -0,0 +1,351 @@
|
||||
Flashing via RIOT's Build System {#flashing}
|
||||
================================
|
||||
|
||||
[TOC]
|
||||
|
||||
General Approach {#flashing-general}
|
||||
================
|
||||
|
||||
In general, flashing a board from RIOT is as straight forward as typing in a
|
||||
shell (with the application directory as current working directory):
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
make BOARD=<BOARD-TO-FLASH> flash
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This will **rebuild** ***AND*** **flash** the application in the current working
|
||||
directory for board `<BOARD-TO-FLASH>`, using its default programming tool. If
|
||||
you want to use an alternative programming tool, say `stm32flash`, use:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
make BOARD=<BOARD-TO-FLASH> PROGRAMMER=stm32flash flash
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To flash without rebuilding use `flash-only` as target instead of `flash`.
|
||||
|
||||
|
||||
|
||||
|
||||
Compatibility Matrix {#flashing-compatibility}
|
||||
====================
|
||||
|
||||
Note that some programmers require additional configuration on a per board
|
||||
level or rely on features only available on some boards. Hence, a board `FOO` of
|
||||
MCU family `BAR` may not be supported by programmer `BAZ`, even though `BAZ` is
|
||||
listed as supported for MCU family `BAR`.
|
||||
|
||||
This table will use the value to pass to `PROGRAMMER=<value>` as title, rather
|
||||
than the official spelling of the programmer.
|
||||
|
||||
MCU Family | `adafruit-nrfutil` | `avrdude` | `bmp` | `bossa` | `cc2538-bsl`| `cpy2remed` | `dfu-util` | `edbg` | `elf2uf2` | `esptool` | `goodfet` | `jlink` | `lpc2k_pgm` | `mspdebug` | `nrfutil` | `openocd` | `pic32prog` | `pyocd` | `robotis-loader` | `stm32flash` | `stm32loader` | `uf2conv` | `uniflash`
|
||||
---------------|--------------------|-----------|-------|---------|-------------|-------------|------------|--------|-----------|-----------|-----------|---------|-------------|------------|-----------|-----------|-------------|---------|------------------|--------------|---------------|-----------|-----------
|
||||
ATmega | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
ATXmega | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
CC2538 | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
CC13xx / C26xx | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ (3) | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓
|
||||
EFM32 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
ESP8266 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
ESP32 (Xtensa) | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
ESP32 (RISC-V) | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
FE310 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
GD32V | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ (3) | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
Kinetis | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
LPC1768 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
LPC23xx | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
MIPS32r2 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
MSP430 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
nRF51 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
nRF52 | ✓ (1) | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✓ (1) | ✓ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗
|
||||
RP2040 | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
SAM | ✗ | ✗ | ✗ | ✓ (1) | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
Stellaris | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗
|
||||
STM32 | ✗ | ✗ | ✓ | ✗ | ✗ | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✗ | ✓ | ✗ | ✗ | ✓ (1) | ✓ | ✓ | ✗ | ✗
|
||||
|
||||
|
||||
Remarks:
|
||||
|
||||
1. Requires a bootloader to be flashed (rather than a bootloader in ROM)
|
||||
2. Requires specific hardware, e.g. an embedded programmer
|
||||
3. Requires a patched version of the programmer tool
|
||||
|
||||
Programmer Configuration {#flashing-configuration}
|
||||
========================
|
||||
|
||||
This section will list additional configuration options to control the behavior
|
||||
of a programming tool, such as selecting the hardware adapter used for
|
||||
programming.
|
||||
|
||||
OpenOCD Configuration {#flashing-configuration-openocd}
|
||||
---------------------
|
||||
|
||||
### `OPENOCD_DEBUG_ADAPTER`
|
||||
|
||||
`OPENOCD_DEBUG_ADAPTER` can be set via command line or as environment variable
|
||||
to use non-default flashing hardware.
|
||||
|
||||
### `OPENOCD_RESET_USE_CONNECT_ASSERT_SRST`
|
||||
|
||||
`OPENOCD_RESET_USE_CONNECT_ASSERT_SRST` can be set via command line or as
|
||||
environment variable to `0` to disable resetting the board via the `SRST` line.
|
||||
This is useful when the `SRST` signal is not connected to the debug adapter or
|
||||
when using cheap ST-Link V2 clones with broken `SRST` output. Note that it may
|
||||
not be possible to attach the debugger while the MCU is in deep sleeping mode.
|
||||
If this is set to `0` by the user, the user may need a carefully timed reset
|
||||
button press to be able to flash the board.
|
||||
|
||||
### `OPENOCD_PRE_FLASH_CMDS`
|
||||
|
||||
`OPENOCD_PRE_FLASH_CMDS` can be set as environment variable to pass additional
|
||||
commands to OpenOCD prior to flashing, e.g. to disable flash write protection.
|
||||
|
||||
### `OPENOCD_PRE_VERIFY_CMDS`
|
||||
|
||||
`OPENOCD_PRE_VERIFY_CMDS` can be set as environment variable to pass additional
|
||||
flags to OpenOCD prior to verifying the flashed firmware. E.g. this is used
|
||||
in the `pba-d-01-kw2x` to disable the watchdog to prevent it from disrupting
|
||||
the verification process.
|
||||
|
||||
### `OPENOCD_PRE_FLASH_CHECK_SCRIPT`
|
||||
|
||||
`OPENOCD_PRE_FLASH_CHECK_SCRIPT` can be set via command line or as
|
||||
environment variable to execute a script before OpenOCD starts flashing. It is
|
||||
used for Kinetis boards to prevent bricking a board by locking the flash via
|
||||
magic value in the flash configuration field protection bits.
|
||||
|
||||
The script is expected to exit with code `0` if flashing should resume, or with
|
||||
exit code `1` if flashing should be aborted.
|
||||
|
||||
### `OPENOCD_CONFIG`
|
||||
|
||||
`OPENOCD_DEBUG_ADAPTER` can be set via command line or as environment variable
|
||||
to use non-default OpenOCD configuration file.
|
||||
|
||||
### `OPENOCD_TRANSPORT`
|
||||
|
||||
`OPENOCD_TRANSPORT` can be set via command line or as environment variable to
|
||||
select a non-default transport protocol. E.g. to use JTAG rather than SWD for a
|
||||
board that defaults to SWD use:
|
||||
|
||||
```
|
||||
make PROGRAMMER=openocd OPENOCD_TRANSPORT=jtag
|
||||
```
|
||||
|
||||
Note that OpenOCD configuration file of a given board may only support SWD or
|
||||
JTAG. Also JTAG requires more signal lines to be connected compared to SWD and
|
||||
some internal programmers only have the SWD signal lines connected, so that
|
||||
JTAG will not be possible.
|
||||
|
||||
Handling Multiple Boards With UDEV-Rules {#multiple-boards-udev}
|
||||
========================================
|
||||
|
||||
When developing and working with multiple boards the default `PORT`
|
||||
configuration for a particular board might not apply anymore so `PORT` will need
|
||||
to be specified whenever calling `make term/test`. This can also happen if
|
||||
multiple `DEBUGGERS/PROGRAMMERS` are present so `DEBUG_ADAPTER_ID` will also
|
||||
need to be passed. Keeping track of this will become annoying.
|
||||
|
||||
One way of handling this is to use `udev` rules to define `SYMLINKS` between the
|
||||
boards serial port (`riot/tty-<board-name>`) and the actual serial port
|
||||
(dev/ttyACM* or other). With this we can query the rest of the boards serial
|
||||
`dev` information (`DEBUG_ADAPTER_ID`, `PORT`, etc.) to always flash and open a
|
||||
terminal on the correct port.
|
||||
|
||||
Procedure:
|
||||
|
||||
- use `udevadm info /dev/ttyACM0` to query the udev database for information on
|
||||
device on port `/dev/ttyACM0`.
|
||||
|
||||
or use `udevadm info --attribute-walk --name /dev/ttyACM0` for more detailed
|
||||
output when the first level of information isn't enough
|
||||
|
||||
- create a udev rule with information of the device and one parent to create a
|
||||
matching rule in `/etc/udev/rules.d/70-riotboards.rules`.
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
# samr21-xpro
|
||||
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", \
|
||||
ATTRS{idProduct}=="2111", ATTRS{manufacturer}=="Atmel Corp.", \
|
||||
ATTRS{serial}=="ATML2127031800004957", SYMLINK+="riot/tty-samr21-xpro"
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- reload rules: `udevadm control --reload-rules`
|
||||
|
||||
- Boards `PORT` are symlinked to /dev/riot/tty-`board-name`.
|
||||
|
||||
- Create a `makefile.pre` that will query the real `PORT` and the
|
||||
`DEBUG_ADAPTER_ID` from the `SYMLINK` info
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
PORT = /dev/riot/tty-$(BOARD)
|
||||
DEBUG_ADAPTER_ID = $(\
|
||||
shell udevadm info -q property $(PORT) |\
|
||||
sed -n ’/ID_SERIAL_SHORT/ {s/ID_SERIAL_SHORT=//p}’)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- You can now add `makefile.pre` to `RIOT_MAKEFILES_GLOBAL_PRE` as an environment
|
||||
variable or on each `make` call:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
$ RIOT_MAKEFILES_GLOBAL_PRE=/path/to/makefile.pre make -C examples/hello-world flash term
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@note if set as an environment variable it would be a good idea to add a
|
||||
variable to enable/disable it, e.g:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
ifeq (1,$(ENABLE_LOCAL_BOARDS))
|
||||
PORT = /dev/riot/tty-$(BOARD)
|
||||
DEBUG_ADAPTER_ID = $(\
|
||||
shell udevadm info -q property $(PORT) |\
|
||||
sed -n ’/ID_SERIAL_SHORT/ {s/ID_SERIAL_SHORT=//p}’)
|
||||
endif
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Handling Multiple Versions of the Same BOARD
|
||||
--------------------------------------------
|
||||
|
||||
The above procedure works fine when handling different boards, but not
|
||||
multiple times the same board, e.g: multiple `samr21-xpro`.
|
||||
|
||||
An option for this would be to add an identifier of that board to the mapped
|
||||
`riot/tty-*`, there are multiple ways of handling this but in the end it means
|
||||
having a way to identify every copy.
|
||||
|
||||
Another way would be to map the `DEBUG_ADAPTER_ID` in the name:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
SYMLINK+="riot/node-$attr{serial}
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
But it will require to know in advance the serial number of each board you want
|
||||
to use. Another option would be to add some kind of numbering and defining
|
||||
multiple symlinks for each board. e.g. for `samr21-xpro` number `n`:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
# samr21-xpro
|
||||
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{idVendor}=="03eb", \
|
||||
ATTRS{idProduct}=="2111", ATTRS{manufacturer}=="Atmel Corp.", \
|
||||
ATTRS{serial}=="ATML2127031800004957", SYMLINK+="riot/tty-samr21-xpro", \
|
||||
SYMLINK+="riot/tty-samr21-xpro-n"
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Then, when flashing, the number can be specified and the parsing adapted:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
ifneq(,$(BOARD_NUM))
|
||||
PORT = /dev/riot/tty-$(BOARD)-$(BOARD_NUM)
|
||||
else
|
||||
PORT = /dev/riot/tty-$(BOARD)
|
||||
endif
|
||||
DEBUG_ADAPTER_ID = $(\
|
||||
shell udevadm info -q property $(PORT) |\
|
||||
sed -n ’/ID_SERIAL_SHORT/ {s/ID_SERIAL_SHORT=//p}’)
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
BOARD=samr21-xpro BOARD_NUM=n make flash term
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the end, this would be the same as using the serial, but a simple number might
|
||||
be easier to handle.
|
||||
|
||||
Notes
|
||||
-----
|
||||
Udev only parses SUBSYSTEM and one parent. For others, we will rely on ENV
|
||||
variables defined by 60-serial.rules
|
||||
|
||||
So the current filename should be higher than 60-serial.rules
|
||||
|
||||
If for some reason re-writing the serial is needed there is a windows tool:
|
||||
https://remoteqth.com/wiki/index.php?page=How+to+set+usb+device+SerialNumber
|
||||
|
||||
|
||||
Documentation:
|
||||
--------------
|
||||
* The whole documentation
|
||||
http://reactivated.net/writing_udev_rules.html#udevinfo
|
||||
* Udev manpage
|
||||
http://manpages.ubuntu.com/manpages/eoan/en/man7/udev.7.html
|
||||
|
||||
Handling Multiple Boards Without UDEV-Rules {#multiple-boards-no-udev}
|
||||
===========================================
|
||||
|
||||
This is a simpler approach to the above mentioned issue. The solution here only
|
||||
uses a makefile script for selecting the debugger and serial port. No
|
||||
administrative privileges (e.g. to configure Udev) are required.
|
||||
|
||||
One of the limitations of the solution described here is that it currently
|
||||
doesn't work with multiple boards of the same type. This limitation is a
|
||||
limitation of the script and not of the mechanism used, it is possible to adapt
|
||||
the script to support multiple boards of the same type. This modification is
|
||||
left as an exercise to the reader.
|
||||
|
||||
The following Make snippet is used:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
LOCAL_BOARD_MAP ?= 1
|
||||
|
||||
# Adapt this list to your board collection
|
||||
SERIAL_nucleo-f103rb ?= 066BFF343633464257254156
|
||||
SERIAL_same54-xpro ?= ATML2748051800005053
|
||||
SERIAL_samr21-xpro ?= ATML2127031800008360
|
||||
SERIAL_nrf52dk ?= 000682223007
|
||||
|
||||
ifeq (1,$(LOCAL_BOARD_MAP))
|
||||
|
||||
# Retrieve the serial of the selected board
|
||||
BOARD_SERIAL = $(SERIAL_$(BOARD))
|
||||
|
||||
# Check if there is a serial for the board
|
||||
ifneq (,$(BOARD_SERIAL))
|
||||
|
||||
# Set the variables used by various debug tools to the selected serial
|
||||
SERIAL ?= $(BOARD_SERIAL)
|
||||
DEBUG_ADAPTER_ID ?= $(BOARD_SERIAL)
|
||||
JLINK_SERIAL ?= $(BOARD_SERIAL)
|
||||
|
||||
# Use the existing script to grab the matching /dev/ttyACM* device
|
||||
PORT ?= $(shell $(RIOTTOOLS)/usb-serial/ttys.py --most-recent --format path --serial $(SERIAL))
|
||||
endif
|
||||
endif
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The array of board serial numbers has to be edited to match your local boards.
|
||||
The serial numbers used here is the USB device serial number as reported by
|
||||
the debugger hardware. With the `make list-ttys` it is reported as the 'serial':
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
$ make list-ttys
|
||||
path | driver | vendor | model | model_db | serial | ctime
|
||||
-------------|---------|--------------------------|--------------------------------------|-----------------------|--------------------------|---------
|
||||
/dev/ttyUSB0 | cp210x | Silicon Labs | CP2102 USB to UART Bridge Controller | CP210x UART Bridge | 0001 | 15:58:13
|
||||
/dev/ttyACM1 | cdc_acm | STMicroelectronics | STM32 STLink | ST-LINK/V2.1 | 0671FF535155878281151932 | 15:58:04
|
||||
/dev/ttyACM3 | cdc_acm | Arduino (www.arduino.cc) | EOS High Power | Mega ADK R3 (CDC ACM) | 75230313733351110120 | 15:59:57
|
||||
/dev/ttyACM2 | cdc_acm | SEGGER | J-Link | J-Link | 000683475134 | 12:41:36
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When the above make snippet is included as `RIOT_MAKEFILES_GLOBAL_PRE`, the
|
||||
serial number of the USB device is automatically set if the used board is
|
||||
included in the script. This will then ensure that the board debugger is used
|
||||
for flashing and the board serial device is used when starting the serial
|
||||
console.
|
||||
|
||||
It supports command line parameters to filter by vendor name, model name, serial
|
||||
number, or driver. In addition, the `--most-recent` argument will only print the
|
||||
most recently added interface (out of those matching the filtering by vendor,
|
||||
model, etc.). The `--format path` argument will result in only the device path
|
||||
being printed for convenient use in scripts.
|
||||
|
||||
Handling Multiple Boards: Simplest Approach {#multiple-boards-simple}
|
||||
===========================================
|
||||
|
||||
Passing `MOST_RECENT_PORT=1` as environment variable or as parameter to
|
||||
make will result in the most recently connected board being preferred over the
|
||||
default PORT for the selected board.
|
||||
|
||||
For some boards `TTY_BOARD_FILTER` is provided, which filters TTYs e.g. by
|
||||
vendor or model to only considered TTYs that actually may belong to the selected
|
||||
board. E.g. for Nucleo boards this is `--model 'STM32 STLink'`, as they all use
|
||||
an integrated STLink as programmer. As long as only one TTY is provided from an
|
||||
STLink, this will reliably select the correct TTY for an Nucleo regardless of
|
||||
which TTY was most recently connected.
|
Loading…
Reference in New Issue
Block a user