# Bootloader - RVC2 only

DepthAI bootloader is a small program which handles the booting process by initializing the OAK PoE camera so DepthAI API can
connect to it. OAK PoE cameras already come with factory bootloader flashed at the factory.

Bootloader is bundled inside with the `depthai` library, so to eg. flash the newest bootloader, you should use the newest
`depthai` library.

You can update the bootloader on RVC2 devices with [OAK Viewer](https://docs.luxonis.com/software-v3/depthai/tools/oak-viewer.md),
which provides the guided flow below, or with the [`oakctl rvc2` command-line
tool](#Bootloader%20-%20RVC2%20only-Manage%20with%20oakctl).

> **Recommended bootloader update for OAK PoE devices**
> DepthAI 3.9.0 ships bootloader version `0.0.29`. We recommend updating OAK PoE devices to this version because it significantly improves device discoverability on the network.

## Update with OAK Viewer

You can update the bootloader from [OAK Viewer](https://docs.luxonis.com/software-v3/depthai/tools/oak-viewer.md). Before you
start, make sure OAK Viewer is updated to the latest version.

Click the detected device in OAK Viewer. If the bootloader is outdated, Viewer automatically detects it and prompts you to update
it. Your host needs a reliable network connection to start this step.

The bootloader is downloaded and flashed onto the device. Do not disturb the host or the device connection during this process.

Once the bootloader update finishes, the device reconnects automatically.

## Manage with oakctl

Use `oakctl rvc2` to manage RVC2 cameras from your computer. Install or update oakctl using the [oakctl
guide](https://docs.luxonis.com/software-v3/oak-apps/oakctl.md).

### Find and select a camera

List RVC2 cameras and inspect a selected camera:

```bash
oakctl rvc2 list
oakctl rvc2 info --device <MXID-or-IP>
```

`list` shows the camera's connection state and platform. `info` includes identity, connection, bootloader, flashed application,
and persistent configuration information. Both commands support `-f json`.

Use the MXID or IP address shown by `oakctl rvc2 list` with `--device` (or `-d`). You can omit the selector when exactly one RVC2
camera is discoverable. RVC2 devices are listed separately from OAK4 devices found in `oakctl list`.

Commands that change the camera prompt for confirmation. For automation, add `--yes` (or `-y`) after selecting the intended
device.

### Update the bootloader

Use the bootloader bundled with your installed oakctl version:

```bash
oakctl rvc2 bootloader update --device <MXID-or-IP>
```

The command chooses which bootloader to update based on the device's support:

 * If the device supports a user bootloader, it updates the recoverable user bootloader and leaves the factory bootloader
   unchanged.
 * If the device does not support a user bootloader, it flashes the factory bootloader instead.

Before flashing, oakctl shows the current and target versions and asks for confirmation, defaulting to No. The prompt warns that
an interrupted factory bootloader write can brick the device. There is no additional confirmation when the command selects factory
bootloader flashing. `--yes` (or `-y`) skips the confirmation prompt.

For bootloader background, see [Factory and User bootloader](#Bootloader%20-%20RVC2%20only-Factory%20and%20User%20bootloader).

Keep the camera powered and connected until flashing completes. An interrupted factory bootloader write can leave the device
requiring recovery.

#### Factory bootloader flashing

> **Risk of bricking the device**
> Flashing the factory bootloader can brick the device if the write fails or is interrupted. Prefer `oakctl rvc2 bootloader update` for routine updates, and keep the device powered and connected until flashing completes.

To flash the factory bootloader explicitly, use:

```bash
oakctl rvc2 bootloader flash-factory --device <MXID-or-IP> --type auto
```

`--type` accepts `auto` (default), `usb`, or `network`. This updates the factory bootloader and, on supported network devices, the
user bootloader. Add `--factory-only` to leave the user bootloader unchanged.

### Factory reset

Factory reset erases flash, including bootloader configuration and the standalone application, and restores the selected
bootloader type:

```bash
# USB camera.
oakctl rvc2 factory-reset --device <MXID> --type usb

# OAK PoE camera, including when connected through USB recovery.
oakctl rvc2 factory-reset --device <MXID-or-IP> --type network
```

Choose the type for the camera being restored. Factory reset requires uninterrupted power and connectivity during the write.

### Read and change configuration

Inspect the persistent bootloader configuration:

```bash
oakctl rvc2 config show --device <MXID-or-IP>
```

On a camera with a network bootloader, configure a static IPv4 address:

```bash
oakctl rvc2 config set --device <MXID-or-IP> \
  --ipv4-mode static \
  --ip 192.168.1.42 \
  --mask 255.255.255.0 \
  --gateway 192.168.1.1 \
  --dns 1.1.1.1
```

To return to dynamic IPv4 assignment:

```bash
oakctl rvc2 config set --device <MXID-or-IP> --ipv4-mode dynamic
```

On a camera with a USB bootloader, set the maximum USB speed or timeout:

```bash
oakctl rvc2 config set --device <MXID> --usb-speed super --usb-timeout-ms 5000
```

| Option | Description |
| --- | --- |
| `--ipv4-mode static|dynamic` | Select static addressing or DHCP. |
| `--ip`, `--mask`, `--gateway` | Set static IPv4 parameters. |
| `--dns`, `--dns-alt` | Set primary and alternate DNS servers. |
| `--network-timeout-ms` | Set the network timeout in milliseconds. |
| `--mac` | Set the device MAC address. |
| `--usb-speed` | Set the maximum USB speed: `low`, `full`, `high`, `super`, or `super-plus`. |
| `--usb-timeout-ms` | Set the USB timeout in milliseconds. |

Network options require a network bootloader; USB options require a USB bootloader. Changes are persistent and can change how the
camera is reached. Use its new IP address or MXID after changing network settings.

To clear persistent bootloader configuration:

```bash
oakctl rvc2 config clear --device <MXID-or-IP>
```

### Remove an existing standalone application

Remove the standalone application stored in the camera's flash:

```bash
oakctl rvc2 application remove --device <MXID-or-IP>
```

This is useful for existing [legacy RVC2 standalone deployments](https://docs.luxonis.com/software/depthai/standalone.md). The
command removes an existing application; application flashing is not provided by `oakctl rvc2`.

### Boot into USB ROM

Enter the USB ROM bootloader without erasing or flashing data:

```bash
oakctl rvc2 recovery usb-rom --device <MXID>
```

## Factory and User bootloader

There are two types of bootloaders:

 * Factory bootloader: bootloader that is flashed in the factory. We don't recommend re-flashing this bootloader, as it is not
   meant to be edited by end users.
 * User bootloader: bootloader that can be flashed by the user. If booting is unsuccessful (eg. gets corrupted when flashing), it
   will fallback to factory bootloader.

USB devices don't support user bootloader. If device has User bootloader, it will be used by default. If user bootloader is not
flashed, it will fallback to Factory bootloader.

## Boot switches

 * Boot from flash - DIP switch: 0x03 (switches 5,6 ON) - used by OAK PoE and USB cameras when bootloader is installed.
 * Recovery mode for USB - DIP switch: 0x16 (switches 2,4,5 ON) - to boot directly into USB mode, so camera waits for the host to
   connect to it via USB.

On newer versions of OAK devices we have 0 ohm resistors (see image below) instead of a DIP switch, which means OAK will boot into
flash by default. These new devices have the bootloader flashed, which handles the booting process. There's also an additional
button on the baseboard that switches boot to recovery mode when pressed, which can be useful if the bootloader hasn't yet been
flashed (eg. early access devices). You need to press this button when powering the device (when booting happens).

## API

DeviceBootloader is a class used to communicate with the bootloader, flash a created
[Pipeline](https://docs.luxonis.com/software-v3/depthai/depthai-components/pipeline.md), or update the bootloader itself. The
DAP-related API remains documented only as a legacy reference; RVC2 standalone deployments are unsupported.

```cpp
std::tuple<bool, std::string> flash(std::function<void(float)> progressCb, Pipeline& pipeline);

std::tuple<bool, std::string> flashDepthaiApplicationPackage(std::function<void(float)> progressCb, std::vector<uint8_t> package);

std::tuple<bool, std::string> flashBootloader(std::function<void(float)> progressCb, std::string path = "");
```

progressCb parameter takes a callback function, which will be called each time an progress update occurs (rate limited to 1
second). This is mainly used to inform the user of the current flashing progress.

### DepthAI Application Package (.dap)

> **Deprecated and unsupported**
> DepthAI Application Packages (`.dap`) and RVC2 standalone deployments are deprecated and no longer supported. Use peripheral mode for [RVC2-based](https://docs.luxonis.com/hardware/platform/rvc/rvc2.md) devices. For standalone deployments, use [RVC4-based](https://docs.luxonis.com/hardware/platform/rvc/rvc4.md) devices with [OAK Apps](https://docs.luxonis.com/software-v3/oak-apps.md).

DepthAI Application Package is a legacy binary file format which stores sections of data. The purpose of this format was to be
able to extract individual sections and do OTA updates without requiring to update all data. Example: Between update 1 and 2 of
users application, DepthAI firmware, Asset storage (50MiB neural network) and asset structure remained the same, but some
additional processing nodes were added to the pipeline. Instead of transferring the whole package, only Pipeline description can
be sent and updated.

DepthAI application package (.dap) consists of:

 * SBR (512B header which describes sections of data)
 * DepthAI device firmware (section "__firmware")
 * Pipeline description (section "pipeline")
 * Assets structure (section "assets")
 * Asset storage (section "asset_storage")

## MAC address

All OAK PoE cameras have a unique MAC address which is used to identify the device on the network. It is calculated from the MxID
of the device, see [logic here](https://gist.github.com/Erol444/85d6ef7ae9c946f5688854b86c548dc7). The MAC address is stored in
the DeviceBootloader configuration.
