ODrive Firmware Deployment System
Warning
The DFU system described on this page is currently under beta testing and not intended for production use yet. During the beta phase, physical access to the ODrive may be required to recover from unexpected issues.
Feedback
Running into issues? Instructions unclear? Or everything working smoothly? We’re happy to hear your feedback on Discord or this form!
Note
The new DFU system described on this page cannot be used to install firmware older than v0.6.5. If you need to install older firmware, you need to uninstall the new bootloader and use the legacy DFU system.
Overview
The new ODrive DFU system described on this page replaces the legacy system that was the default on ODrives sold up to now. Once the beta phase is over, this new system will be the default way to upgrade firmware on ODrives.
To use this new system, you will need to perform a per-ODrive one-time installation of the new bootloader. This one-time setup is performed using the legacy DFU system. The one-time setup thus requires using the command line, requires that Python is installed, may require driver setup, and requires access to the DFU switch. However once set up, you can take full advantage of the new system.
Features
Supports ODrive Pro, ODrive S1 and future ODrive products
Supports both CAN and USB
Run updates from the ODrive Web GUI
Alternatively, run updates from the command line with a standalone tool
Requires no driver setup, no Zadig, no libusb installation, no Python
Recoverable even without physical access, regardless of DFU interruptions or firmware bugs
In a small number of scenarios, recovery might require power cycling the ODrive while the update host remains powered.
Faster and safer than the legacy system
How to install the bootloader
This procedure sets up your ODrive for the new DFU system. It is only required once per device.
Ensure you have firmware version 0.6.5 or newer installed. If unsure, follow the legacy DFU instructions to install the latest firmware.
Download the latest bootloader binary from the devel channel on this page.
Then, follow the legacy DFU instructions to install the downloaded bootloader. To do so, substitute the command
odrivetool dfu
from the instructions with:odrivetool dfu --no-erase-all /path/to/downloaded/firmware.elf
In
odrivetool
, activate the bootloader by running:odrv0.enter_dfu_mode2()
. The ODrive will disconnect fromodrivetool
and a purple pulsating status LED indicates that the ODrive is now in bootloader mode. You can power cycle the ODrive to return to the main firmware.Running this command sets the bootloader as the first thing that runs on ODrive power-up, and ensures that you can install new firmware even when there is a problem with the installed firmware.
Note
After installing the custom bootloader, the legacy DFU method still works if you pass it the option --no-erase-all
(e.g. odrivetool dfu --no-erase-all
) or
run odrv0.disable_bootloader()
beforehand.
The “DFU” DIP switch still forces the legacy DFU mode.
Updating firmware over USB
See also
Looking to install firmware via CAN instead of USB? See below.
Warning
Currently, the user configuration is erased during a firmware update.
(optional) If you want to run updates from the command line, download ODrive Updater. Otherwise, if you’re going to use the GUI, you can skip this step.
Obtain the firmware that you want to install from the firmware release page.
Make sure your ODrive is connected to your host computer via USB.
If the ODrive’s LED isn’t already pulsating purple, put it into DFU mode using any of the following methods:
In the Inspector tab, search for enter_dfu_mode2 and drag the item into the Controls section. Then press Call.
In
odrivetool
or in a Python script, run:odrv0.enter_dfu_mode2()
This method does not require any known, valid or working configuration or firmware to be on the device (apart from the bootloader itself). However it requires that you can control the ODrive’s power supply separately from the host that runs the update.
When the ODrive boots, for a brief period of 1 second, it presents itself to the USB host as “ODrive Pro/S1 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.The following Python script polls for ODrives in bootloader 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 stop sending the force-DFU message (exit the script with Ctrl+C). The ODrive will stay in bootloader mode until the next power cycle unless told otherwise.
Install the new firmware via USB.
Go to https://gui.odriverobotics.com/dfu. Press “Select file…” to open the firmware file that you previously downloaded and press “Select Device” to connect to a device. Then, press “Connect” and “Install” to perform the firmware update.
Note
The “+” button in the bottom bar cannot be used to select an ODrive in DFU mode.
The following command will update the first ODrive that is found on USB in DFU mode (see
odriveupdater --help
for more options):/path/to/odriveupdater --usb firmware.elf
Example Output
loading firmware image...... [odriveupdater] loadable sections in firmware image: [odriveupdater] 0x08000000 ... 0x080002ab .isr_vector [odriveupdater] 0x080002c0 ... 0x08052593 .text [odriveupdater] 0x08052600 ... 0x08073baf .rodata [odriveupdater] 0x08073bb0 ... 0x08073c97 .ARM.extab [odriveupdater] 0x08073c98 ... 0x08073e5f .ARM [odriveupdater] 0x08073e60 ... 0x08073e8b .init_array [odriveupdater] 0x08073e8c ... 0x08073e8f .fini_array [odriveupdater] 0x08073e90 ... 0x0807486f .data [odriveupdater] 0x08074870 ... 0x080748db .fw_manifest [odriveupdater] Firmware info: [odriveupdater] Hardware: ODrive Pro (4, 4, 58) [odriveupdater] Version: 0.6.7 [odriveupdater] Build: 1ec4ed5486e2be016f34fc233f92849678cb3d looking for devices on USB... [odriveupdater] found candidate on USB [odriveupdater] found matching interface: 1 [odriveupdater] Max transfer size: IN: 2047, OUT: 2047 [odriveupdater] clearing halt... [odriveupdater] clearing halt... [odriveupdater] cleared halt [odriveupdater] found ODrive Pro 356E395D3339 updating ODrive Pro 356E395D3339 [odriveupdater] getting sector info... [odriveupdater] Device has 128 sectors [odriveupdater] # Address Range Flags [odriveupdater] 0 0x08000000...0x08001fff readable, writable [odriveupdater] 1 0x08002000...0x08003fff readable, writable [odriveupdater] 2 0x08004000...0x08005fff readable, writable [odriveupdater] 3 0x08006000...0x08007fff readable, writable [odriveupdater] 4 0x08008000...0x08009fff readable, writable [odriveupdater] 5 0x0800a000...0x0800bfff readable, writable [odriveupdater] 6 0x0800c000...0x0800dfff readable, writable [odriveupdater] 7 0x0800e000...0x0800ffff readable, writable [odriveupdater] 8 0x08010000...0x08011fff readable, writable [odriveupdater] 9 0x08012000...0x08013fff readable, writable [odriveupdater] 10 0x08014000...0x08015fff readable, writable [odriveupdater] 11 0x08016000...0x08017fff readable, writable [odriveupdater] 12 0x08018000...0x08019fff readable, writable [odriveupdater] 13 0x0801a000...0x0801bfff readable, writable [odriveupdater] 14 0x0801c000...0x0801dfff readable, writable [odriveupdater] 15 0x0801e000...0x0801ffff readable, writable [odriveupdater] 16 0x08020000...0x08021fff readable, writable [odriveupdater] 17 0x08022000...0x08023fff readable, writable [odriveupdater] 18 0x08024000...0x08025fff readable, writable [odriveupdater] 19 0x08026000...0x08027fff readable, writable [odriveupdater] 20 0x08028000...0x08029fff readable, writable [odriveupdater] 21 0x0802a000...0x0802bfff readable, writable [odriveupdater] 22 0x0802c000...0x0802dfff readable, writable [odriveupdater] 23 0x0802e000...0x0802ffff readable, writable [odriveupdater] 24 0x08030000...0x08031fff readable, writable [odriveupdater] 25 0x08032000...0x08033fff readable, writable [odriveupdater] 26 0x08034000...0x08035fff readable, writable [odriveupdater] 27 0x08036000...0x08037fff readable, writable [odriveupdater] 28 0x08038000...0x08039fff readable, writable [odriveupdater] 29 0x0803a000...0x0803bfff readable, writable [odriveupdater] 30 0x0803c000...0x0803dfff readable, writable [odriveupdater] 31 0x0803e000...0x0803ffff readable, writable [odriveupdater] 32 0x08040000...0x08041fff readable, writable [odriveupdater] 33 0x08042000...0x08043fff readable, writable [odriveupdater] 34 0x08044000...0x08045fff readable, writable [odriveupdater] 35 0x08046000...0x08047fff readable, writable [odriveupdater] 36 0x08048000...0x08049fff readable, writable [odriveupdater] 37 0x0804a000...0x0804bfff readable, writable [odriveupdater] 38 0x0804c000...0x0804dfff readable, writable [odriveupdater] 39 0x0804e000...0x0804ffff readable, writable [odriveupdater] 40 0x08050000...0x08051fff readable, writable [odriveupdater] 41 0x08052000...0x08053fff readable, writable [odriveupdater] 42 0x08054000...0x08055fff readable, writable [odriveupdater] 43 0x08056000...0x08057fff readable, writable [odriveupdater] 44 0x08058000...0x08059fff readable, writable [odriveupdater] 45 0x0805a000...0x0805bfff readable, writable [odriveupdater] 46 0x0805c000...0x0805dfff readable, writable [odriveupdater] 47 0x0805e000...0x0805ffff readable, writable [odriveupdater] 48 0x08060000...0x08061fff readable, writable [odriveupdater] 49 0x08062000...0x08063fff readable, writable [odriveupdater] 50 0x08064000...0x08065fff readable, writable [odriveupdater] 51 0x08066000...0x08067fff readable, writable [odriveupdater] 52 0x08068000...0x08069fff readable, writable [odriveupdater] 53 0x0806a000...0x0806bfff readable, writable [odriveupdater] 54 0x0806c000...0x0806dfff readable, writable [odriveupdater] 55 0x0806e000...0x0806ffff readable, writable [odriveupdater] 56 0x08070000...0x08071fff readable, writable [odriveupdater] 57 0x08072000...0x08073fff readable, writable [odriveupdater] 58 0x08074000...0x08075fff readable, writable [odriveupdater] 59 0x08076000...0x08077fff readable, writable [odriveupdater] 60 0x08078000...0x08079fff readable, writable [odriveupdater] 61 0x0807a000...0x0807bfff readable, writable [odriveupdater] 62 0x0807c000...0x0807dfff readable, writable [odriveupdater] 63 0x0807e000...0x0807ffff readable, writable [odriveupdater] 64 0x08100000...0x08101fff readable, writable [odriveupdater] 65 0x08102000...0x08103fff readable, writable [odriveupdater] 66 0x08104000...0x08105fff readable, writable [odriveupdater] 67 0x08106000...0x08107fff readable, writable [odriveupdater] 68 0x08108000...0x08109fff readable, writable [odriveupdater] 69 0x0810a000...0x0810bfff readable, writable [odriveupdater] 70 0x0810c000...0x0810dfff readable, writable [odriveupdater] 71 0x0810e000...0x0810ffff readable, writable [odriveupdater] 72 0x08110000...0x08111fff readable, writable [odriveupdater] 73 0x08112000...0x08113fff readable, writable [odriveupdater] 74 0x08114000...0x08115fff readable, writable [odriveupdater] 75 0x08116000...0x08117fff readable, writable [odriveupdater] 76 0x08118000...0x08119fff readable, writable [odriveupdater] 77 0x0811a000...0x0811bfff readable, writable [odriveupdater] 78 0x0811c000...0x0811dfff readable, writable [odriveupdater] 79 0x0811e000...0x0811ffff readable, writable [odriveupdater] 80 0x08120000...0x08121fff readable, writable [odriveupdater] 81 0x08122000...0x08123fff readable, writable [odriveupdater] 82 0x08124000...0x08125fff readable, writable [odriveupdater] 83 0x08126000...0x08127fff readable, writable [odriveupdater] 84 0x08128000...0x08129fff readable, writable [odriveupdater] 85 0x0812a000...0x0812bfff readable, writable [odriveupdater] 86 0x0812c000...0x0812dfff readable, writable [odriveupdater] 87 0x0812e000...0x0812ffff readable, writable [odriveupdater] 88 0x08130000...0x08131fff readable, writable [odriveupdater] 89 0x08132000...0x08133fff readable, writable [odriveupdater] 90 0x08134000...0x08135fff readable, writable [odriveupdater] 91 0x08136000...0x08137fff readable, writable [odriveupdater] 92 0x08138000...0x08139fff readable, writable [odriveupdater] 93 0x0813a000...0x0813bfff readable, writable [odriveupdater] 94 0x0813c000...0x0813dfff readable, writable [odriveupdater] 95 0x0813e000...0x0813ffff readable, writable [odriveupdater] 96 0x08140000...0x08141fff readable, writable [odriveupdater] 97 0x08142000...0x08143fff readable, writable [odriveupdater] 98 0x08144000...0x08145fff readable, writable [odriveupdater] 99 0x08146000...0x08147fff readable, writable [odriveupdater] 100 0x08148000...0x08149fff readable, writable [odriveupdater] 101 0x0814a000...0x0814bfff readable, writable [odriveupdater] 102 0x0814c000...0x0814dfff readable, writable [odriveupdater] 103 0x0814e000...0x0814ffff readable, writable [odriveupdater] 104 0x08150000...0x08151fff readable, writable [odriveupdater] 105 0x08152000...0x08153fff readable, writable [odriveupdater] 106 0x08154000...0x08155fff readable, writable [odriveupdater] 107 0x08156000...0x08157fff readable, writable [odriveupdater] 108 0x08158000...0x08159fff readable, writable [odriveupdater] 109 0x0815a000...0x0815bfff readable, writable [odriveupdater] 110 0x0815c000...0x0815dfff readable, writable [odriveupdater] 111 0x0815e000...0x0815ffff readable, writable [odriveupdater] 112 0x08160000...0x08161fff readable [odriveupdater] 113 0x08162000...0x08163fff readable [odriveupdater] 114 0x08164000...0x08165fff readable [odriveupdater] 115 0x08166000...0x08167fff readable [odriveupdater] 116 0x08168000...0x08169fff readable [odriveupdater] 117 0x0816a000...0x0816bfff readable [odriveupdater] 118 0x0816c000...0x0816dfff readable [odriveupdater] 119 0x0816e000...0x0816ffff readable [odriveupdater] 120 0x08170000...0x08171fff readable [odriveupdater] 121 0x08172000...0x08173fff readable [odriveupdater] 122 0x08174000...0x08175fff readable [odriveupdater] 123 0x08176000...0x08177fff readable [odriveupdater] 124 0x08178000...0x08179fff readable [odriveupdater] 125 0x0817a000...0x0817bfff readable [odriveupdater] 126 0x0817c000...0x0817dfff readable [odriveupdater] 127 0x0817e000...0x0817ffff readable [odriveupdater] will write 59 sectors: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58] erasing sector 0 (1 / 59)... erasing sector 1 (2 / 59)... erasing sector 2 (3 / 59)... erasing sector 3 (4 / 59)... erasing sector 4 (5 / 59)... erasing sector 5 (6 / 59)... erasing sector 6 (7 / 59)... erasing sector 7 (8 / 59)... erasing sector 8 (9 / 59)... erasing sector 9 (10 / 59)... erasing sector 10 (11 / 59)... erasing sector 11 (12 / 59)... erasing sector 12 (13 / 59)... erasing sector 13 (14 / 59)... erasing sector 14 (15 / 59)... erasing sector 15 (16 / 59)... erasing sector 16 (17 / 59)... erasing sector 17 (18 / 59)... erasing sector 18 (19 / 59)... erasing sector 19 (20 / 59)... erasing sector 20 (21 / 59)... erasing sector 21 (22 / 59)... erasing sector 22 (23 / 59)... erasing sector 23 (24 / 59)... erasing sector 24 (25 / 59)... erasing sector 25 (26 / 59)... erasing sector 26 (27 / 59)... erasing sector 27 (28 / 59)... erasing sector 28 (29 / 59)... erasing sector 29 (30 / 59)... erasing sector 30 (31 / 59)... erasing sector 31 (32 / 59)... erasing sector 32 (33 / 59)... erasing sector 33 (34 / 59)... erasing sector 34 (35 / 59)... erasing sector 35 (36 / 59)... erasing sector 36 (37 / 59)... erasing sector 37 (38 / 59)... erasing sector 38 (39 / 59)... erasing sector 39 (40 / 59)... erasing sector 40 (41 / 59)... erasing sector 41 (42 / 59)... erasing sector 42 (43 / 59)... erasing sector 43 (44 / 59)... erasing sector 44 (45 / 59)... erasing sector 45 (46 / 59)... erasing sector 46 (47 / 59)... erasing sector 47 (48 / 59)... erasing sector 48 (49 / 59)... erasing sector 49 (50 / 59)... erasing sector 50 (51 / 59)... erasing sector 51 (52 / 59)... erasing sector 52 (53 / 59)... erasing sector 53 (54 / 59)... erasing sector 54 (55 / 59)... erasing sector 55 (56 / 59)... erasing sector 56 (57 / 59)... erasing sector 57 (58 / 59)... erasing sector 58 (59 / 59)... writing sector 0 (1 / 59)... writing sector 1 (2 / 59)... writing sector 2 (3 / 59)... writing sector 3 (4 / 59)... writing sector 4 (5 / 59)... writing sector 5 (6 / 59)... writing sector 6 (7 / 59)... writing sector 7 (8 / 59)... writing sector 8 (9 / 59)... writing sector 9 (10 / 59)... writing sector 10 (11 / 59)... writing sector 11 (12 / 59)... writing sector 12 (13 / 59)... writing sector 13 (14 / 59)... writing sector 14 (15 / 59)... writing sector 15 (16 / 59)... writing sector 16 (17 / 59)... writing sector 17 (18 / 59)... writing sector 18 (19 / 59)... writing sector 19 (20 / 59)... writing sector 20 (21 / 59)... writing sector 21 (22 / 59)... writing sector 22 (23 / 59)... writing sector 23 (24 / 59)... writing sector 24 (25 / 59)... writing sector 25 (26 / 59)... writing sector 26 (27 / 59)... writing sector 27 (28 / 59)... writing sector 28 (29 / 59)... writing sector 29 (30 / 59)... writing sector 30 (31 / 59)... writing sector 31 (32 / 59)... writing sector 32 (33 / 59)... writing sector 33 (34 / 59)... writing sector 34 (35 / 59)... writing sector 35 (36 / 59)... writing sector 36 (37 / 59)... writing sector 37 (38 / 59)... writing sector 38 (39 / 59)... writing sector 39 (40 / 59)... writing sector 40 (41 / 59)... writing sector 41 (42 / 59)... writing sector 42 (43 / 59)... writing sector 43 (44 / 59)... writing sector 44 (45 / 59)... writing sector 45 (46 / 59)... writing sector 46 (47 / 59)... writing sector 47 (48 / 59)... writing sector 48 (49 / 59)... writing sector 49 (50 / 59)... writing sector 50 (51 / 59)... writing sector 51 (52 / 59)... writing sector 52 (53 / 59)... writing sector 53 (54 / 59)... writing sector 54 (55 / 59)... writing sector 55 (56 / 59)... writing sector 56 (57 / 59)... writing sector 57 (58 / 59)... writing sector 58 (59 / 59)... validating sector 0 (1 / 59)... validating sector 1 (2 / 59)... validating sector 2 (3 / 59)... validating sector 3 (4 / 59)... validating sector 4 (5 / 59)... validating sector 5 (6 / 59)... validating sector 6 (7 / 59)... validating sector 7 (8 / 59)... validating sector 8 (9 / 59)... validating sector 9 (10 / 59)... validating sector 10 (11 / 59)... validating sector 11 (12 / 59)... validating sector 12 (13 / 59)... validating sector 13 (14 / 59)... validating sector 14 (15 / 59)... validating sector 15 (16 / 59)... validating sector 17 (18 / 59)... validating sector 19 (20 / 59)... validating sector 21 (22 / 59)... validating sector 23 (24 / 59)... validating sector 26 (27 / 59)... validating sector 27 (28 / 59)... validating sector 28 (29 / 59)... validating sector 29 (30 / 59)... validating sector 30 (31 / 59)... validating sector 31 (32 / 59)... validating sector 32 (33 / 59)... validating sector 33 (34 / 59)... validating sector 34 (35 / 59)... validating sector 35 (36 / 59)... validating sector 36 (37 / 59)... validating sector 37 (38 / 59)... validating sector 38 (39 / 59)... validating sector 39 (40 / 59)... validating sector 40 (41 / 59)... validating sector 41 (42 / 59)... validating sector 42 (43 / 59)... validating sector 43 (44 / 59)... validating sector 44 (45 / 59)... validating sector 45 (46 / 59)... validating sector 46 (47 / 59)... validating sector 47 (48 / 59)... validating sector 48 (49 / 59)... validating sector 49 (50 / 59)... validating sector 50 (51 / 59)... validating sector 51 (52 / 59)... validating sector 52 (53 / 59)... validating sector 53 (54 / 59)... validating sector 54 (55 / 59)... validating sector 55 (56 / 59)... validating sector 56 (57 / 59)... validating sector 57 (58 / 59)... validating sector 58 (59 / 59)... leaving DFU mode...
After successful completion, the status LED will go back to the normal pattern (blue / cyan), indicating that the main firmware is running.
Updating firmware over CAN
See also
Looking to install firmware via USB instead of CAN? See above.
Warning
Currently, the user configuration is erased during a firmware update. Instructions to restore the configuration over CAN will be added soon.
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 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 using any of the following methods:
This method requires that the ODrive’s firmware boots normally and the default CAN Protocol is enabled with a known
node_id
.In this case, you can send a CAN message with the message ID
(node_id << 5 | 0x1f)
to enter DFU mode.For example using Python:
import can node_id = 0 # change if needed with can.interface.Bus("can0", bustype="socketcan") as bus: bus.send(can.Message(arbitration_id=(node_id << 5 | 0x1f), data=[], is_extended_id=False))
This method does not require any known, valid or working configuration or firmware to be on the device (apart from the bootloader itself). However it requires that you can control the ODrive’s power supply separately from the host that runs the update.
It works by sending a force-DFU CAN message with the data
0xa8, 0x94, 0x18, 0x5c, 0xa8, 0xe6, 0x0c, 0x56
at an interval <100ms while the ODrive is rebooting.The message ID can be chosen freely as long as it does not conflict with any other protocols that may be running on the bus. In the example below we’re using ID 0 to ensure that our message gets through even on high bus load.
For example using Python:
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)
While this message is being sent, reboot the ODrive (e.g. power cycle).
Shortly after power-on (<1 second), the ODrive LED should start pulsating purple and you can stop sending the force-DFU message (exit the script with Ctrl+C). The ODrive will stay in bootloader mode until the next power cycle unless told otherwise.
The status LED should now be pulsating purple.
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.
ODrive Updater
Firmware can be installed either with the GUI or with the standalone command line utility odriveupdater
.
odriveupdater
is intended for situations where the GUI cannot be used (when using CAN, on headless systems or for automation).
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
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 (USB support only)
Run ./path/to/odriveupdater --help
for general usage hints or proceed with the instructions on this page.
Specifications
Supported interfaces: USB, CAN
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 (ODrives in bootloader mode + updater hosts) are allowed on one bus.
Supported baudrates (autodetected): 1Mbps, 500kbps, 250kbps, 125kbps, 40kbps, 10kbps
The ODrive bootloader can coexist with CAN-FD devices on the same bus but does not use CAN-FD messages.
Known issues
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.
How to uninstall the bootloader
This is only required if you wish to install legacy firmware (<0.6.5) or use the legacy DFU system.
If your ODrive doesn’t have bootable firmware (purple pulsating LED when turning it on), first install recent firmware.
Either via the normal DFU-over-CAN or DFU-over-USB process.
Or via the legacy method:
Flick the DFU switch to “DFU”.
Power cycle the board.
Run
odrivetool dfu --no-erase-all --channel devel
In
odrivetool
, runodrv0.disable_bootloader()
.
The custom ODrive bootloader is now disabled and you can use the legacy DFU method as usual.