乐鑫技术交流
直播中

李华

7年用户 1352经验值
私信 关注
[问答]

esp32如何先将OAT下来的固件进行sha256或者MD5校验,再写入相应的flash区域?

esp32如何先将OAT下来的固件进行sha256或者MD5校验,再写入相应的flash区域,OAT下来的固件先放在哪里?

回帖(1)

笑过就走

2024-6-7 10:59:22
要在ESP32上实现对OAT(Over-The-Air)下载的固件进行SHA256或MD5校验,然后写入相应的Flash区域,可以按照以下步骤操作:

1. **下载固件**:首先,需要将固件从服务器下载到ESP32。这可以通过HTTP或MQTT等协议实现。

2. **存储固件**:下载的固件可以先存储在ESP32的内存中,例如使用动态分配的内存(malloc)或者静态分配的数组。确保分配的内存足够大以存储整个固件。

3. **计算校验和**:在固件下载完成后,使用SHA256或MD5算法计算固件的校验和。ESP32的ESP-IDF框架提供了相应的库来实现这些算法。例如,使用`esp_sha()`函数计算SHA256校验和,或者使用`esp_md5()`函数计算MD5校验和。

4. **验证校验和**:将计算出的校验和与服务器提供的校验和进行比较。如果校验和匹配,则可以继续进行固件烧录;如果不匹配,则需要重新下载固件或报告错误。

5. **烧录固件**:如果校验和验证成功,可以使用ESP-IDF的`esp_partition_write()`函数将固件写入相应的Flash区域。首先,需要获取目标分区的句柄,然后使用`esp_partition_write()`函数将固件数据写入该分区。

6. **设置跳转**:烧录完成后,需要设置ESP32的跳转地址,使其从新烧录的固件启动。这可以通过修改`app_cpu_boot_addr`配置项实现。

7. **重启设备**:最后,重启ESP32设备,使其从新烧录的固件启动。

以下是一个简化的示例代码,展示了如何实现上述步骤:

```c
#include "esp_partition.h"
#include "esp_sha.h"
#include "esp_ota_ops.h"

void download_and_verify_firmware(const char *url, const char *expected_sha256) {
    // 1. 下载固件到内存
    uint8_t *firmware_data;
    size_t firmware_size;
    download_firmware(url, &firmware_data, &firmware_size);

    // 2. 计算SHA256校验和
    esp_sha256_handle_t handle = esp_sha256_new();
    esp_sha256_update(handle, firmware_data, firmware_size);
    uint8_t calculated_sha256[32];
    esp_sha256_final(handle, calculated_sha256);
    esp_sha256_free(handle);

    // 3. 验证校验和
    if (memcmp(calculated_sha256, expected_sha256, 32) != 0) {
        printf("校验和不匹配,重新下载固件。n");
        return;
    }

    // 4. 烧录固件到Flash
    const esp_partition_t *partition = get_target_partition();
    esp_partition_erase_range(partition, 0, partition->size);
    esp_partition_write(partition, 0, firmware_data, firmware_size);

    // 5. 设置跳转地址
    set_boot_address(partition->address);

    // 6. 重启设备
    esp_restart();
}

void download_firmware(const char *url, uint8_t **data, size_t *size) {
    // 实现HTTP或MQTT下载固件的逻辑
}

const esp_partition_t *get_target_partition() {
    // 获取目标分区的逻辑
}

void set_boot_address(uint32_t address) {
    // 设置跳转地址的逻辑
}
```

请注意,这只是一个示例,实际实现可能需要根据您的具体需求进行调整。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分