Firmware Update
Note
This page describes the new ODrive DFU system that is use since Q2 2024. Migration instructions can be found here. See also: Legacy Firmware Update.
Quick Summary
Updating the firmware on your ODrive is easy and safe and works directly from your browser via USB. Head over to the Web GUI > Firmware Update and press Install Firmware.
Alternatively, you can install updates from the command line. Experimental support for firmware updates via CAN is also available.
Specifications
Supported firmware:
0.6.7 or newer when using GUI
0.6.5 or newer when using
odrivetool
(use the legancy DFU system to install older firmware)
Supported interfaces: USB (stable), CAN (experimental)
Recoverable even without physical access, see Recovering from a failed update and Recovering from unbootable firmware.
CAN specifications:
The DFU-over-CAN protocol uses extended (29-bit) IDs. It is not currently guaranteed to work with other 29bit ID CAN messages on the bus. If you wish to use other vendor’s 29bit CAN protocols on the same bus, please contact us and let us know what vendor and messages you are looking to use, so we can work towards ensuring compatibility.
Up to 62 devices that speak the DFU protocol (ODrives in DFU mode + updater hosts) are allowed on one bus. The bus can have additional devices that use other protocols (ODrives in run mode, third party devices), as long as they don’t conflict with the other points listed here.
Supported baudrates (autodetected): 1Mbps, 500kbps, 250kbps, 125kbps, 40kbps, 10kbps
The ODrive bootloader does not send any CAN-FD messages but is ok with other CAN-FD messages going on the same bus (sent by other devices).
Updating firmware from the command line
Warning
Your configuration will be erased during a firmware update. See Configuration Backup if you want to keep it.
Install (or update)
odrivetool
on your computer:python3 -m pip install odrive --upgrade
For more detailed installation instructions, see odrivetool Installation.
Run the following command to install the latest firmware on your ODrive:
odrivetool new-dfu
For more options, see odrivetool new-dfu --help
or next section.
Other Options
Install firmware from our semi-stable development channel (see Firmware Channels):
odrivetool new-dfu --channel devel
Install a specific firmware version (0.6.9 in this example):
odrivetool new-dfu --version 0.6.9
Install a local firmware file:
odrivetool new-dfu firmware.elf
You can manually download firmware files from here.
If you want to avoid insalling Python, you can use the standalone utility
odriveupdater
instead ofodrivetool
. This requires manually downloading the files and manually commanding the ODrive into DFU mode.
Updating firmware over CAN
Warning
DFU over CAN is currently under beta testing and not intended for production use yet. During the beta phase, USB or physical access to the ODrive may be required to recover from unexpected issues.
You will need a Linux device with a CAN interface for this.
We assume that your CAN interface is called can0
, but this may differ on your system.
Download ODrive Updater. (The GUI and
odrivetool
can only perform firmware updates via USB.)Obtain the firmware that you want to install from the firmware release page.
If you have set a custom baudrate on the ODrive before, make sure to revert to the firmware default of 250k on all devices on the bus.
odrv0.can.config.baud_rate = 250000
If you haven’t touched this value before, you can ignore this step.
Note
While the DFU process itself supports other baudrates too, we recommend a baudrate of 250kbps because the user configuration is currently not preserved during the firmware update. That means when the update completes, the ODrive will default to a baudrate of 250kbps, which would crash the CAN bus if any devices (including the update host) use a different baudrate.
Configure and enable the host computer’s CAN interface.
sudo ip link set dev can0 type can bitrate 250000 sudo ip link set dev can0 txqueuelen 256 sudo ip link set dev can0 up
Make sure your host computer and ODrive are connected via CAN.
If the ODrive’s LED isn’t already pulsating purple, put it into DFU mode:
If the ODrive’s default CAN Protocol is enabled, you can send a CAN message with the message ID
(node_id << 5 | 0x16)
and payload 0x03 to enter DFU mode (see Reboot). You can use the broadcastnode_id
of0x3f
to put all ODrives into DFU mode at once.For example using Python:
import can node_id = 0x3f # broadcast address with can.interface.Bus("can0", bustype="socketcan") as bus: bus.send(can.Message(arbitration_id=(node_id << 5 | 0x16), data=[0x03], is_extended_id=False))
This method won’t work if you manually disabled the CAN Protocol. In that case, see Recovering from unbootable firmware instead.
Install the new firmware via CAN.
The following command will update the first ODrive in DFU mode that’s found on the bus (see
odriveupdater --help
for more options):/path/to/odriveupdater --can can0 firmware.elf
Example Output
loading firmware image...... [odriveupdater] loadable sections in firmware image: [odriveupdater] 0x08000000 ... 0x080002cb .isr_vector [odriveupdater] 0x08000300 ... 0x080481b3 .text [odriveupdater] 0x08048200 ... 0x08059417 .rodata [odriveupdater] 0x08059418 ... 0x080594ff .ARM.extab [odriveupdater] 0x08059500 ... 0x080596c7 .ARM [odriveupdater] 0x080596c8 ... 0x080596f3 .init_array [odriveupdater] 0x080596f4 ... 0x080596f7 .fini_array [odriveupdater] 0x080596f8 ... 0x0805a4d7 .data [odriveupdater] 0x0805a4d8 ... 0x0805a543 .fw_manifest [odriveupdater] Firmware info: [odriveupdater] Hardware: ODrive S1 (5, 2, 0) [odriveupdater] Version: 0.6.3 [odriveupdater] Build: 94ffcb6175679d4745579cbac25fa32fb5f142b [odriveupdater] can0 parameters: [odriveupdater] TX queue length: 256 [odriveupdater] CAN-FD capable: yes [odriveupdater] driver: mcp251xfd [odriveupdater] version: 5.10.63-v8+ [odriveupdater] firmware version: [odriveupdater] bus-info: spi0.1 looking for devices on can0... connecting to device 13... [odriveupdater] found ODrive S1 395F356F3231 updating ODrive S1 395F356F3231 [odriveupdater] getting sector info... [odriveupdater] Device has 8 sectors [odriveupdater] # Address Range Flags [odriveupdater] 0 0x08000000...0x0801ffff readable, writable [odriveupdater] 1 0x08020000...0x0803ffff readable, writable [odriveupdater] 2 0x08040000...0x0805ffff readable, writable [odriveupdater] 3 0x08060000...0x0807ffff readable, writable [odriveupdater] 4 0x08080000...0x0809ffff readable, writable [odriveupdater] 5 0x080a0000...0x080bffff readable, writable [odriveupdater] 6 0x080c0000...0x080dffff readable, writable [odriveupdater] 7 0x080e0000...0x080fffff readable [odriveupdater] will write 3 sectors: [0, 1, 2] erasing sector 0 (1 / 3)... erasing sector 1 (2 / 3)... erasing sector 2 (3 / 3)... writing sector 0 (1 / 3)... [SocketCan] got sent confirmation for unknown message # spurious error message repeating several times [SocketCan] got sent confirmation for unknown message [SocketCan] got sent confirmation for unknown message writing sector 1 (2 / 3)... writing sector 2 (3 / 3)... validating sector 0 (1 / 3)... validating sector 1 (2 / 3)... validating sector 2 (3 / 3)... leaving DFU mode...
Troubleshooting
If
odriveupdater
gets stuck atlooking for devices on can0...
double-check your CAN connection and CAN interface state.Note that if your host CAN interface and your ODrive in run mode are configured to different baudrates, your host interface will go into bus-off state.
You can check for this using the following command (note
can state BUS-OFF
in the output):ip -details -statistics link show can0
4: can0: <NO-CARRIER,NOARP,UP,ECHO> mtu 16 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 256 link/can promiscuity 0 minmtu 0 maxmtu 0 can state BUS-OFF restart-ms 0 bitrate 1000000 sample-point 0.666 tq 166 prop-seg 1 phase-seg1 2 phase-seg2 2 sjw 1 mcp251x: tseg1 3..16 tseg2 2..8 sjw 1..4 brp 1..64 brp-inc 1 clock 6000000 re-started bus-errors arbit-lost error-warn error-pass bus-off 0 0 0
When this happens, you need to restart the CAN interface (see above) to clear the
BUS-OFF
state.After successful completion, the status LED will go back to the normal pattern (blue / cyan), indicating that the main firmware is running.
Note
The
odriveupdater
utility does currently not terminate when the update is done. Press Ctrl+C to exit.Configuration and calibration is erased during a firmware update. You can re-apply it by following the instructions here: Setting up the ODrive (CAN only).
Limitations
When updating firmware over CAN,
odriveupdater
will not exit automatically once complete or when the device is disconnected. Press Ctrl+C to exit.When updating firmware over CAN, the device does currently not recognize when the host disconnects after enumeration or during the update. That means in case of a failed/cancelled DFU attempt, or if the device was interrogated while updating another device, it needs to be restarted to correctly handle a new DFU attempt.
The bootloader does not reject simultaneous update attempts from two separate hosts. The result of such a situation is undefined.
Recovering from a failed update
If the firmware update is interrupted (e.g. due to power loss), the ODrive will automatically start into DFU mode on the next power up and you can restart the DFU process. No physical access is required for this.
Note
The hardware “DFU” DIP switch on ODrive Pro and ODrive S1 is deprecated and should be left in “RUN” state when the new DFU system is used.
Recovering from unbootable firmware
In rare corner cases, the ODrive might get into a state where there’s valid looking firmware installed but the firmware fails to start correctly so that the ODrive cannot accept an “enter DFU mode” command. This should never happen during normal usage and is only expected in these cases:
Installing untested development or custom firmware builds that happen to be broken
Setting special untested configuration that is not correctly handled by the firmware
Unexpected hardware damage that is not properly handled by the firmware
You can recover from such a state by power-cycling the ODrive and sending a “Force DFU” message during one second after power-up. This can be done without physical access as long as the ODrive’s power supply can be controlled independently from the power supply of the update host (e.g. robot’s on-board computer).
Force DFU via USB: When the ODrive boots, for a brief period of 1 second, it presents itself to the USB host as “ODrive Pro/S1/Micro Bootloader”. During this period, the host can send a Vendor Setup Request with
bRequest = 0x0D
andwValue = 0x0001
to force the ODrive to stay in DFU mode.Example Script
The following Python script polls for ODrives in DFU mode as fast as possible and sends the “Force DFU” command each time one is found.
import usb.core import usb.util while True: print(f"scanning...") devices = list(usb.core.find(find_all=True, idVendor=0x1209, idProduct=0x0D32)) print(f"found {len(devices)} ODrives...") bootloader_odrives = [] for device in devices: try: if usb.util.get_string(device, device.iProduct).endswith(" Bootloader"): bootloader_odrives.append(device) except ValueError: pass except usb.core.USBError as e: print(f"USBError: {str(e)}") if len(bootloader_odrives) > 0: print(f"sending FORCE DFU command to {len(bootloader_odrives)} devices...") for device in bootloader_odrives: try: # Send a vendor setup request request_type = usb.util.build_request_type( usb.util.CTRL_OUT, usb.util.CTRL_TYPE_VENDOR, usb.util.CTRL_RECIPIENT_DEVICE, ) request = 0x0D # vendor code: ODrive value = 0x0001 # command: force DFU index = 0x00 device.ctrl_transfer(request_type, request, value, index) except usb.core.USBError as e: print(f"USBError: {str(e)}")
Start the script, and while it is running, reboot the ODrive (e.g. power cycle). Shortly after power-on (<1 second), the ODrive LED should start pulsating purple, and you can exit the script with Ctrl+C.
Force DFU via CAN: Send a message with the data
0xa8, 0x94, 0x18, 0x5c, 0xa8, 0xe6, 0x0c, 0x56
at an interval <100ms while the ODrive is rebooting.Any message ID can be used as long as it does not conflict with any other protocols that may be running on the bus. Any supported baudrate can be used.
Example Script
In this example we’re using message ID 0 to ensure that our message gets through even on high bus load.
import can import time with can.interface.Bus("can0", bustype="socketcan") as bus: while True: bus.send(can.Message(arbitration_id=0, data=[0xa8, 0x94, 0x18, 0x5c, 0xa8, 0xe6, 0x0c, 0x56], is_extended_id=False)) time.sleep(0.02)
Start the script, and while it is running, reboot the ODrive (e.g. power cycle). Shortly after power-on (<1 second), the ODrive LED should start pulsating purple, and you can exit the script with Ctrl+C.
If successful, the status LED should be pulsating purple, indicating that the ODrive is in DFU mode. The ODrive will stay in DFU mode until the next power cycle unless told otherwise. At this point you can run a normal firmware update using your preferred method.
ODrive Updater
odriveupdater
is a standalone command line utility that serves as a light-weight alternative
to odrivetool new-dfu
when Python is not available and the GUI cannot be used (on headless systems or for automation).
Currently it is also the only way to run updates over CAN (experimental).
odriveupdater 0.5 (Linux AArch64) (e.g. Raspberry Pi 4, Nvidia Jetson, …)
Unpack the downloaded zip file, and then run:
chmod +x /path/to/odriveupdater
Currently only supports USB (not CAN).
odriveupdater 0.5 (Intel Macs) — macOS 10.15 Catalina or newer
odriveupdater 0.5 (Apple Silicon) — macOS 11.0 Big Sur or newer
Unpack the downloaded zip file, and then run:
chmod +x /path/to/odriveupdater
xattr -dr com.apple.quarantine /path/to/odriveupdater
coming soon
Run ./path/to/odriveupdater --help
for general usage hints or proceed with the instructions on this page.
Firmware Channels
Firmware updates are made available on two channels: master
and devel
.
The master
channel is considered stable and recommended for most users and
production use.
The devel
channel is our internal development channel and contains the latest features and bug fixes, however it may not always be stable.
The effective differences are:
Firmware on
master
is guaranteed to have fully passed our internal hardware-in-the-loop test suite. Firmware ondevel
is usually tested with the same test suite, however it is not guaranteed to have passed it (e.g. due to mainenance).After larger changes,
devel
firmware is more likely to contain bugs that are not covered by our test suite.master
firmware is only released if enough time has passed since the last larger change.devel
firmware may not be fully supported by the Web GUI.Some features or changes on
devel
may be refined before reachingmaster
. Onmaster
we try to do incompatible changes only when necessary.Firmware on
master
carries version names (X.Y.Z) that equal the version number reported by the firmware itself. Firmware ondevel
uses 40-digit hashes as version names.Updates on
master
happen more sparsely, thus avoiding to distract users for whom the updates may not be relevant.
Users are advised to back up configuration files and test firmware upgrades thoroughly prior to fleet deployment, as ODrive endpoints or behavior may change. For a full list of changes for each version, please see the Changelog.
How to migrate from the legacy DFU system
If your ODrive was purchased before Q3 2024, you need to run a one-time migration step to use the new DFU system.
Note
Your configuration will be erased during this migration. See Configuration Backup if you want to keep it.
First, make sure the ODrive Web GUI is closed before you continue. Then run:
python3 -m pip install odrive --upgrade
odrivetool install-bootloader
For troubleshooting, see odrivetool Installation and Legacy Firmware Update.
Why migrate?
If you’re previously used the legacy DFU system on the ODrive, the new DFU system will get you these benefits:
Experimental support for DFU via CAN
Recoverable without physical access (on-board “DFU” DIP switch deprecated)
Requires no driver setup, no Zadig, no libusb installation
Supports multiple update methods:
From the browser (ODrive Web GUI)
standalone odriveupdater (no Python required)
As before with
odrivetool new-dfu
- works almost identically toodrivetool dfu
that you might be familiar with.
Faster and safer than the legacy system
Should you ever want to disable the new DFU system, you can do so with odrv0.disable_bootloader()
or by running odrivetool legacy-dfu
.