mkyx-001/esp_target_flasher

0.2.0

Latest
uploaded 1 day ago
ESP host-to-target firmware flasher wrapper over esp-serial-flasher

Readme

# esp_target_flasher

> ESP 主机给 ESP 从机烧录固件的共享组件,封装 [espressif/esp-serial-flasher](https://components.espressif.com/components/espressif/esp-serial-flasher) v2。

## 概述

本组件提供 **ESP → ESP** UART 烧录的统一接口,从 V4PRO 量产代码提炼,去掉了项目硬编码:

| 特性 | 说明 |
|------|------|
| 目标型号安全校验 | 连接后比对 `expected` vs `detected`,防错刷(C5 固件不会误刷到 C2) |
| Stub / ROM 双模式 | Stub 高速 + MD5 校验;ROM 分块模式兜底(C5 大镜像) |
| 三种数据源 | RAM 缓冲 / 文件流式 / 回调流式(HTTP、加密分区等) |
| 目标 WDT 禁用 | 连接后自动禁用 RTC WDT + 启用 SWD 自动喂狗 |
| Flash size 兜底 | 自动检测失败时强制指定值(如 2MB) |
| 共享 BOOT 互斥锁 | 多目标共用 BOOT 引脚时 `esp_tf_lock/unlock` |
| UART 生命周期钩子 | `prepare/restore` 回调支持 UART 分时复用 |

## 依赖

```yaml
dependencies:
  espressif/esp-serial-flasher: "~2.0.0"
  idf: ">=5.5"
```

## 快速开始

```c
#include "esp_target_flasher.h"

/* 1. 初始化组件 */
esp_tf_init();

/* 2. 描述目标 */
esp_tf_target_t target = {
    .label           = "C3",
    .chip            = ESP_TF_CHIP_ESP32_C3,
    .uart_port       = UART_NUM_1,
    .tx_pin          = GPIO_NUM_4,
    .rx_pin          = GPIO_NUM_5,
    .reset_pin       = GPIO_NUM_6,
    .boot_pin        = GPIO_NUM_7,
    .baud_connect    = 115200,
    .baud_flash      = 0,        /* 不切换波特率 */
    .target_flash_size = 4 * 1024 * 1024,
};

/* 3. 烧录参数 */
esp_tf_image_t image = ESP_TF_IMAGE_DEFAULT();

/* 4. 从内存缓冲烧录 */
esp_tf_err_t err = esp_tf_flash_buffer(&target, &image,
                                       fw_data, fw_size,
                                       NULL, NULL, my_progress_cb);
if (err != ESP_TF_OK) {
    ESP_LOGE(TAG, "Flash failed: %s", esp_tf_err_to_str(err));
}
```

## API 分层

### 便捷 API(一步到位)

| 函数 | 数据源 | 典型场景 |
|------|--------|----------|
| `esp_tf_flash_buffer()` | RAM 缓冲 | 小体积固件 / PSRAM 缓冲 |
| `esp_tf_flash_file()` | 文件路径 | LittleFS / SPIFFS 固件 |
| `esp_tf_flash_stream()` | 回调 | HTTP 下载 / 加密分区 |

### 会话 API(需要多步操作时)

```c
esp_tf_session_t *sess;
esp_tf_session_open(&sess, &target, &hooks, &gpio_ops, true);
// 可在此读取 MAC、改 baud 等
esp_tf_session_flash(sess, &image, read_cb, ctx, total, progress_cb);
esp_tf_session_close(sess, true);  /* true = 复位目标运行新固件 */
```

## 烧录模式选择

| 模式 | `use_stub` | `rom_chunked` | 速度 | MD5 | 适用 |
|------|------------|---------------|------|-----|------|
| Stub 标准 | `true` | `false` | 高速 | ✅ | **推荐**,>2MB 镜像 |
| ROM 标准 | `false` | `false` | 慢 | ✅ | Flash/RAM 紧张 |
| ROM 分块 | `false` | `true` | 慢 | ❌ | C5 大镜像兜底 |

## 自定义下载时序

若不用 loader 内置 `reset_pin`/`boot_pin` 触发(如经模拟开关选路):

```c
static void my_enter_download(void *ctx) {
    gpio_set_level(MUX_A0, ...);  /* 选通目标 */
    gpio_set_level(BOOT_PIN, 0);   /* 拉 BOOT */
    gpio_set_level(RST_PIN, 0);    /* RST 低 */
    vTaskDelay(pdMS_TO_TICKS(100));
    gpio_set_level(RST_PIN, 1);    /* 释放 RST */
    vTaskDelay(pdMS_TO_TICKS(100));
    gpio_set_level(BOOT_PIN, 1);   /* 释放 BOOT */
}

static void my_reset_target(void *ctx) {
    gpio_set_level(BOOT_PIN, 1);   /* 确保 BOOT 回运行电平 */
    gpio_set_level(RST_PIN, 0);
    vTaskDelay(pdMS_TO_TICKS(100));
    gpio_set_level(RST_PIN, 1);
}

esp_tf_gpio_ops_t gpio = {
    .enter_download = my_enter_download,
    .reset_target   = my_reset_target,
    .ctx            = NULL,
};
esp_tf_flash_file(&target, &image, "/lfs/fw.bin", NULL, &gpio, progress_cb);
```

## 常见故障

| 现象 | 原因 | 解决 |
|------|------|------|
| `CHIP_MISMATCH` | UART 接错了型号的目标 | 检查接线,或设 `ESP_TF_CHIP_AUTO` |
| `FLASH_FINISH (MD5)` | `flash_cfg` 未全程复用同一变量 | 组件已处理,若自定义调用注意 |
| 连接超时 | RST/BOOT 极性反了 | 检查 `CONFIG_SERIAL_FLASHER_*_INVERT` |
| 擦写超时 | 目标 WDT 复位 | 组件已自动禁用 WDT |

## 许可证

Apache License 2.0

Links

To add this component to your project, run:

idf.py add-dependency "mkyx-001/esp_target_flasher^0.2.0"

download archive

Stats

  • Archive size
    Archive size ~ 26.72 KB
  • Downloaded in total
    Downloaded in total 0 times
  • Downloaded this version
    This version: 0 times

Badge

mkyx-001/esp_target_flasher version: 0.2.0
|