# 引导加载程序 - 仅限 RVC2

DepthAI 引导加载程序是一个小程序，负责处理启动过程，要么启动刷写的应用程序（参见 [独立模式](https://docs.luxonis.com/software-v3/depthai/tutorials/standalone.md)）， 要么初始化
OAK PoE 相机，以便 DepthAI API 能够连接。OAK PoE 相机出厂时已预刷工厂引导加载程序。

引导加载程序与 depthai 库绑定在一起，因此，例如要刷写最新的引导加载程序，应使用最新的 depthai 库。

## 设备管理器

device_manager.py 是一个 Python 脚本，用于与设备的引导加载程序及其配置进行交互。 该脚本可在
[depthai-core/utilities](https://github.com/luxonis/depthai-core/blob/main/utilities/device_manager.py) 找到。

### 关于设备

允许您选择要连接的设备，并查看已连接设备的元数据。

 * 首先，我们必须选择要连接（启动）的设备，可以使用以下方式选择：
   
   * 下拉菜单：包含已发现设备的 MX ID。仅当启动应用程序时下拉菜单才会更新。
   * 指定 IP 按钮：当您的 OAK PoE 相机不在同一局域网时使用。
   * 搜索功能：一个新窗口将显示一个表格，其中包含所有可用的相机（通过 USB 端口或局域网 - OAK PoE 相机）、它们的 MxId、名称和状态。单击表格行将选中该设备并启动至该设备。

### 配置设置

选择已刷写引导加载程序的设备后，您还可以配置引导加载程序配置。

 * 如果设备已刷写网络引导加载程序，您将能够设置其静态/动态 IP/掩码/网关、DNS、MAC 等。
 * 如果设备已刷写USB 引导加载程序，您将能够设置其 USB 最大速度和 USB 超时时间。

设置某些值后，必须单击 Flash configuration 按钮。您还可以 Clear configuration（清除配置）或 View configuration（查看配置，以 JSON 格式显示）。

### 应用程序设置

在涉及 [独立模式](https://docs.luxonis.com/software-v3/depthai/tutorials/standalone.md) 应用程序时很有用。

 * 刷写应用程序：选择要刷写到设备的 DepthAI 应用程序包（.dap）。下面是展示如何创建 dap 文件的代码片段。
 * 移除应用程序：从设备上移除/清除已刷写的应用程序。
 * 打开设备流式传输应用程序：开始从设备上所有已连接的相机流式传输帧。

```python
import depthai as dai
pipeline = dai.Pipeline()
# ... 向管道添加节点
dai.DeviceBootloader.saveDepthaiApplicationPackage(
    './file.dap', # 保存 .dap 文件的位置
    pipeline, # 我的管道
    compress=True, # 压缩固件和资源。在我的案例中，从 24MB 压缩到 9.5MB
    applicationName='myAppName' # 可选，以便之后知道刷写了哪个应用程序
  )
```

## 危险区域

> **软砖**
> 本部分可能导致设备变砖，请谨慎使用。

以下视频教程演示如何更新引导加载程序：

为防止设备变砖，OAK 设备（自 2023 年起）具有工厂引导加载程序和用户引导加载程序。如果用户刷写了损坏的用户引导加载程序，设备将回退到使用工厂引导加载程序。更新引导加载程序时，
设备管理器会先尝试刷写用户引导加载程序（如果已刷写的工厂引导加载程序支持）。如果无法刷写，则会刷写工厂引导加载程序。

 * 更新引导加载程序按钮将把最新的引导加载程序刷写到设备上。您可以选择 AUTO、USB 或 NETWORK 引导加载程序。
   
   * AUTO 将根据相机当前连接的引导加载程序连接类型自动选择。如果您通过 USB（执行恢复出厂设置）连接到 OAK PoE 相机，则不应选择 AUTO，因为它会刷写 USB 引导加载程序。
   * USB 引导加载程序将尝试启动存储在闪存中的应用程序。如果未找到刷写的应用程序，它将仅作为普通 USB OAK 设备运行 - 即等待主机计算机初始化应用程序。
   * NETWORK 引导加载程序由 OAK PoE 相机使用，并在出厂时刷写。它处理网络初始化，以便 OAK PoE 相机可以通过局域网启动。

 * 刷写工厂引导加载程序：如果您想刷写工厂引导加载程序，可以使用此按钮。即使已刷写用户引导加载程序，它也会刷写工厂引导加载程序。

 * 恢复出厂设置将擦除整个闪存内容，并仅用 USB 或 NETWORK 引导加载程序重新刷写。已刷写的应用程序（管道、资源）和引导加载程序配置将丢失。

 * 启动至 USB 恢复模式将强制例如 OAK PoE 相机通过 USB 连接器可用，即使其启动引脚设置为 PoE 启动。此功能主要由我们的固件开发人员使用。

### 工厂引导加载程序和用户引导加载程序

有两种类型的引导加载程序：

 * 工厂引导加载程序：在工厂烧录的引导加载程序。我们不建议重新刷新此引导加载程序，因为其本意不是供最终用户修改。
 * 用户引导加载程序：可由用户刷新的引导加载程序。如果启动失败（例如在刷新时损坏），它将回退到工厂引导加载程序。

USB 设备不支持用户引导加载程序。如果设备带有用户引导加载程序，则默认使用该程序。如果未烧录用户引导加载程序，则会回退到工厂引导加载程序。

## 启动开关

 * 从闪存启动 - DIP 开关：0x03（开关 5,6 打开）- 用于安装了引导加载程序的 OAK PoE 和 USB 摄像头。
 * USB 恢复模式 - DIP 开关：0x16（开关 2,4,5 打开）- 直接启动到 USB 模式，让摄像头等待主机通过 USB 连接。

在较新版本的 OAK 设备上，我们使用 0 欧姆电阻（见下图）代替 DIP 开关，这意味着 OAK
将默认从闪存启动。这些新设备已烧录引导加载程序，负责处理启动过程。此外，基板上还有一个额外的按钮，按下时可将启动切换为恢复模式，这在引导加载程序尚未烧录（例如早期设备）时可能很有用。需要在给设备上电（启动时）按下此按钮。

## API

DeviceBootloader 是一个用于与引导加载程序通信的类。它用于烧录创建的
[Pipeline](https://docs.luxonis.com/software-v3/depthai/depthai-components/pipeline.md)、depthai 应用程序包，或更新引导加载程序本身。

```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 参数接受一个回调函数，该函数将在每次进度更新时被调用（限制为每秒一次）。这主要用于告知用户当前的烧录进度。

### DepthAI 应用程序包 (.dap)

DepthAI 应用程序包 是一种二进制文件格式，用于存储数据段。该格式的目的是能够提取各个段，并在不更新所有数据的情况下进行 OTA 更新。例如：在用户应用程序的更新 1 和更新 2 之间，Depthai 固件、资产存储（50MiB
神经网络）和资产结构保持不变，但流水线中添加了一些额外的处理节点。无需传输整个包，只需发送并更新流水线描述即可。

DepthAI 应用程序包 (。dap) 包含：

 * SBR（描述数据段的 512B 头部）
 * Depthai 设备固件（段 "__firmware"）
 * 流水线描述（段 "pipeline"）
 * 资产结构（段 "assets"）
 * 资产存储（段 "asset_storage"）

## MAC 地址

所有 OAK PoE 摄像头都有一个唯一的 MAC 地址，用于在网络中标识设备。它是根据设备的 MxID 计算得出的，请参见
[此逻辑](https://gist.github.com/Erol444/85d6ef7ae9c946f5688854b86c548dc7)。 MAC 地址存储在 DeviceBootloader 配置中。
