You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ESP32 Rainmaker实现ATSAM4的OTA升级且不刷写ESP32

实现ESP32转发ATSAM4 OTA固件的方案

核心思路是绕开ESP Rainmaker默认的ESP32 OTA刷写流程,自定义处理OTA事件,将ATSAM4固件下载后通过通信接口转发给目标芯片,具体步骤如下:

1. 拦截Rainmaker的OTA事件,自定义处理逻辑

Rainmaker的OTA默认会自动刷写ESP32自身固件,需注册自定义回调函数识别ATSAM4的OTA包并跳过默认流程:

  • 在初始化Rainmaker后,调用esp_rmaker_ota_set_cb注册OTA回调
  • 在回调的ESP_RMAKER_OTA_START事件中,读取OTA包元数据(比如自定义的fw_type字段),判断是否为ATSAM4固件
  • 如果是ATSAM4固件,返回ESP_RMAKER_OTA_SKIP阻止默认刷写;否则按默认逻辑处理

示例代码:

static esp_err_t custom_ota_cb(esp_rmaker_ota_cb_event_t event, void *data)
{
    if (event == ESP_RMAKER_OTA_START) {
        esp_rmaker_ota_data_t *ota_data = (esp_rmaker_ota_data_t *)data;
        // 用元数据中"fw_type"字段区分固件类型,"sam4"代表ATSAM4固件
        const char *fw_type = esp_rmaker_ota_get_metadata(ota_data, "fw_type");
        if (fw_type && strcmp(fw_type, "sam4") == 0) {
            return ESP_RMAKER_OTA_SKIP;
        }
    }
    return ESP_RMAKER_OTA_CONTINUE;
}

// 在Rainmaker初始化后注册回调
esp_rmaker_ota_set_cb(custom_ota_cb, NULL);

2. 下载ATSAM4固件到ESP32专用存储分区

需提前在ESP32分区表中定义专门存储ATSAM4固件的分区,避免和自身OTA分区冲突:

  • 修改partitions.csv,添加类似分区:
    sam4_fw,  data,  fat,    0x100000,  0x200000,
    
    地址和大小根据实际固件调整,确保空间充足
  • 在自定义逻辑中获取ATSAM4固件的下载URL,通过esp_http_client分块下载到该分区
  • 下载完成后,用OTA元数据中的sha256字段验证固件哈希,确保数据完整性

3. 与ATSAM4建立通信并转发固件

根据选用的通信方式(UART/SPI/I2C),实现固件转发逻辑:

前置准备(ATSAM4端)

  • 实现ISP模式触发逻辑:比如通过串口指令或GPIO电平触发进入固件升级模式
  • 实现分块接收、校验、写入Flash的逻辑,支持ACK反馈

ESP32端处理

  • 发送触发指令,等待ATSAM4返回进入升级模式的确认信号
  • 从sam4_fw分区读取固件数据,分块发送给ATSAM4,每块发送后等待ACK
  • 加入CRC校验,每块数据附带校验值,ATSAM4验证后再写入

示例UART转发代码片段:

#define SAM4_UART_NUM UART_NUM_1
#define FW_BLOCK_SIZE 512

void sam4_fw_transfer(void)
{
    // 触发ATSAM4进入ISP模式
    uart_write_bytes(SAM4_UART_NUM, "ENTER_ISP\r\n", strlen("ENTER_ISP\r\n"));
    uint8_t ack_buf[16];
    uart_read_bytes(SAM4_UART_NUM, ack_buf, sizeof(ack_buf), portMAX_DELAY);
    if (strcmp((char *)ack_buf, "ISP_READY") != 0) {
        return;
    }

    // 映射分区并读取固件数据
    spi_flash_mmap_handle_t mmap_handle;
    uint32_t fw_addr = 0x100000; // 对应sam4_fw分区起始地址
    uint32_t fw_size = 0x200000;
    uint8_t *fw_data;
    spi_flash_mmap(fw_addr, fw_size, SPI_FLASH_MMAP_DATA, (void **)&fw_data, &mmap_handle);

    for (int i = 0; i < fw_size; i += FW_BLOCK_SIZE) {
        uint32_t block_len = MIN(FW_BLOCK_SIZE, fw_size - i);
        // 发送块长度、数据、CRC
        uart_write_bytes(SAM4_UART_NUM, (const char *)&block_len, sizeof(block_len));
        uart_write_bytes(SAM4_UART_NUM, fw_data + i, block_len);
        uint32_t crc = crc32_le(0, fw_data + i, block_len);
        uart_write_bytes(SAM4_UART_NUM, (const char *)&crc, sizeof(crc));
        // 等待ACK,失败则重试
        uart_read_bytes(SAM4_UART_NUM, ack_buf, sizeof(ack_buf), portMAX_DELAY);
        if (strcmp((char *)ack_buf, "BLOCK_OK") != 0) {
            i -= FW_BLOCK_SIZE;
            continue;
        }
    }

    // 发送升级完成指令
    uart_write_bytes(SAM4_UART_NUM, "UPGRADE_DONE\r\n", strlen("UPGRADE_DONE\r\n"));
    spi_flash_munmap(mmap_handle);
}

4. 上报ATSAM4升级状态到Rainmaker

升级完成后,通过Rainmaker自定义参数上报ATSAM4固件版本或升级状态:

  • 在Rainmaker设备中添加自定义参数,比如sam4_fw_version
  • 升级成功后调用esp_rmaker_param_update_and_report更新参数值

示例代码:

// 创建自定义参数
esp_rmaker_param_t *sam4_version_param = esp_rmaker_param_create("sam4_fw_version", NULL,
    esp_rmaker_str("v1.0"), PROP_FLAG_READ | PROP_FLAG_WRITE);
esp_rmaker_device_add_param(device, sam4_version_param);

// 升级成功后更新并上报
esp_rmaker_param_update_and_report(sam4_version_param, esp_rmaker_str("v1.1"));

关键注意事项

  • 分区表配置:确保ATSAM4固件存储分区不与ESP32自身的OTA、应用分区重叠
  • 固件校验:下载后必须验证哈希值,避免转发损坏的固件
  • 通信可靠性:添加重传机制,处理通信过程中的丢包或错误
  • ATSAM4 ISP兼容性:确保ATSAM4的ISP逻辑支持分块写入和校验,避免升级失败

内容的提问来源于stack exchange,提问作者JOO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 18:35:00