2026-08-10 21:18:36 +08:00
|
|
|
|
/* net_wifi_ota.c - WiFi ͨ<><CDA8> OTA <20>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
*
|
|
|
|
|
|
* ESP-01S <EFBFBD>ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CIPMUX=0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>OTA <EFBFBD>ڼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MQTT <EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>("+++") <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> HTTP GET <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>չ̼<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* <EFBFBD><EFBFBD> ÿ 3072B д W25Q64 <EFBFBD><EFBFBD> B + <EFBFBD>ض<EFBFBD>У<EFBFBD><EFBFBD> + <EFBFBD>ۼ<EFBFBD> CRC16
|
|
|
|
|
|
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> CRC + <EFBFBD>̼<EFBFBD>ͷУ<EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD> MQTT <EFBFBD>ϱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD> д OTA <EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD> <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD> BL
|
|
|
|
|
|
*
|
|
|
|
|
|
* <EFBFBD>ο<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̡<EFBFBD>4·<EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴ<EFBFBD>WIFI<EFBFBD><EFBFBD>4G V3.4 WIFI<EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˼·<EFBFBD><EFBFBD>
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> W25Q64 ˫<EFBFBD><EFBFBD> + CRC + <EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD> + BootLoader <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵ<EFBFBD><EFBFBD><EFBFBD>Ȳο<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
* д<EFBFBD>ڲ<EFBFBD> Flash APP2 <EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD><EFBFBD>öࣩ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¿<EFBFBD> TCP <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>MCU <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>մ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><EFBFBD><EFBFBD>٣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ᶪ<EFBFBD>ֽڡ<EFBFBD>
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "net_wifi_ota.h"
|
|
|
|
|
|
#include "net_wifi.h"
|
|
|
|
|
|
#include "esp8266.h"
|
|
|
|
|
|
#include "network.h"
|
|
|
|
|
|
#include "air780e.h" /* bg_delay / U2_CopyBuff / Verify_Firmware_External / crc16_modbus_update */
|
|
|
|
|
|
#include "ota_app.h" /* Application_Size */
|
|
|
|
|
|
#include "uart.h"
|
|
|
|
|
|
#include "relay.h"
|
|
|
|
|
|
#include "feed_scale.h"
|
|
|
|
|
|
#include "led.h"
|
|
|
|
|
|
#include "log.h"
|
|
|
|
|
|
#include "reset_log.h"
|
|
|
|
|
|
#include "../W25Q64/w25q64.h"
|
|
|
|
|
|
#include "stdio.h"
|
|
|
|
|
|
#include "string.h"
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define WIFI_OTA_CHUNK 3072u /* <20><> 4G OTA <20><>ͬ<EFBFBD>ķֿ<C4B7><D6BF><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
#define WIFI_OTA_HDR_TIMEOUT 15000u /* <20><> HTTP <20><>Ӧͷ<D3A6><CDB7>ʱ */
|
|
|
|
|
|
#define WIFI_OTA_IDLE_TIMEOUT 20000u /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ʱ<EFBFBD><CAB1>TCP <20><><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>٣<EFBFBD> */
|
|
|
|
|
|
|
|
|
|
|
|
static uint8_t s_blk[WIFI_OTA_CHUNK]; /* <20>ֿ<EFBFBD><D6BF>ݴ棺дflash/У<><D0A3>/CRC <20><><EFBFBD><EFBFBD><EFBFBD>鴦<EFBFBD><E9B4A6> */
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD>ư<EFBFBD>ȫ<EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
static uint8_t *ota_memfind(uint8_t *hay, uint16_t hay_len, const char *needle)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint16_t nlen = strlen(needle);
|
|
|
|
|
|
if (hay_len < nlen) return NULL;
|
|
|
|
|
|
for (uint16_t i = 0; i <= hay_len - nlen; i++) {
|
|
|
|
|
|
if (memcmp(hay + i, needle, nlen) == 0) return hay + i;
|
|
|
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><>Сд<D0A1><D0B4><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD><D0B2>ң<EFBFBD>Content-Length ͷ<><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сд<D0A1><D0B4>һ<EFBFBD><D2BB> */
|
|
|
|
|
|
static uint8_t *ota_memfind_i(uint8_t *hay, uint16_t hay_len, const char *needle)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint16_t nlen = strlen(needle);
|
|
|
|
|
|
if (hay_len < nlen) return NULL;
|
|
|
|
|
|
for (uint16_t i = 0; i <= hay_len - nlen; i++) {
|
|
|
|
|
|
uint16_t j;
|
|
|
|
|
|
for (j = 0; j < nlen; j++) {
|
|
|
|
|
|
char a = hay[i + j], b = needle[j];
|
|
|
|
|
|
if (a >= 'A' && a <= 'Z') a += 32;
|
|
|
|
|
|
if (b >= 'A' && b <= 'Z') b += 32;
|
|
|
|
|
|
if (a != b) break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (j == nlen) return hay + i;
|
|
|
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD>ѽ<EFBFBD><D1BD>ջ<EFBFBD><D5BB><EFBFBD>ǰ n <20>ֽ<EFBFBD> */
|
|
|
|
|
|
static void ota_consume(uint16_t n)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (n >= U2_CopyIndex) {
|
|
|
|
|
|
U2_CopyIndex = 0;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
memmove(U2_CopyBuff, U2_CopyBuff + n, U2_CopyIndex - n);
|
|
|
|
|
|
U2_CopyIndex -= n;
|
|
|
|
|
|
}
|
|
|
|
|
|
U2_CopyBuff[U2_CopyIndex] = '\0';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*==== HTTP Range <20>ֿ<EFBFBD><D6BF><EFBFBD><EFBFBD>ع̼<D8B9><CCBC><EFBFBD> W25Q64 <20><> B<><42><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD> 0 <20><> *out_size=<3D>̼<EFBFBD><CCBC><EFBFBD>С ====
|
|
|
|
|
|
* ÿ<EFBFBD><EFBFBD> 3072B һ<EFBFBD><EFBFBD> GET<EFBFBD><EFBFBD>Range: bytes=off-end<EFBFBD><EFBFBD><EFBFBD><EFBFBD>MCU <EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ࣺ
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>ֻ<EFBFBD><EFBFBD>һ<EFBFBD>飬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>౬<EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⣨ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
|
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 6 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 57KB<EFBFBD><EFBFBD>MCU д flash <EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽڣ<EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
static int wifi_ota_download(const char *host, int port, const char *path,
|
|
|
|
|
|
uint16_t crc16, uint32_t *out_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
char req[224];
|
|
|
|
|
|
uint32_t offset = 0, total_size = 0;
|
|
|
|
|
|
uint16_t crc_acc = 0xFFFF;
|
|
|
|
|
|
int last_pct = -1;
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD> MQTT <20><><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><CCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬΪ<CEAA><CDB8>ģʽ<C4A3><CABD> */
|
|
|
|
|
|
esp_exit_transparent();
|
|
|
|
|
|
if (esp_enter_transparent(host, (uint16_t)port) != 0) {
|
|
|
|
|
|
log_warn("> WiFi OTA: <20><><EFBFBD>ӹ̼<D3B9><CCBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>");
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD>һ<EFBFBD>鰴<EFBFBD>ܴ<EFBFBD>С<EFBFBD>ضϣ<D8B6>total_size <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> */
|
|
|
|
|
|
uint32_t want_end = offset + WIFI_OTA_CHUNK - 1;
|
|
|
|
|
|
if (total_size > 0 && want_end >= total_size) want_end = total_size - 1;
|
|
|
|
|
|
|
|
|
|
|
|
/* HTTP/1.1 Ĭ<><C4AC> keep-alive<76><65>ͬһ TCP <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD><F2B7A2B6><EFBFBD> Range <20><><EFBFBD><EFBFBD> */
|
|
|
|
|
|
snprintf(req, sizeof(req),
|
|
|
|
|
|
"GET %s HTTP/1.1\r\nHost: %s:%d\r\nUser-Agent: esp8266-ota\r\nAccept: */*\r\nRange: bytes=%u-%u\r\n\r\n",
|
|
|
|
|
|
path, host, port, (unsigned)offset, (unsigned)want_end);
|
|
|
|
|
|
esp_rx_clear();
|
|
|
|
|
|
esp_send((uint8_t *)req, strlen(req));
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\r\n\r\n <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
uint32_t hdr_end = 0;
|
|
|
|
|
|
uint32_t tick = HAL_GetTick();
|
|
|
|
|
|
while (HAL_GetTick() - tick < WIFI_OTA_HDR_TIMEOUT) {
|
|
|
|
|
|
bg_delay(50);
|
|
|
|
|
|
uint8_t *p = ota_memfind(U2_CopyBuff, U2_CopyIndex, "\r\n\r\n");
|
|
|
|
|
|
if (p) { hdr_end = (uint32_t)(p - U2_CopyBuff) + 4; break; }
|
|
|
|
|
|
if (ota_memfind(U2_CopyBuff, U2_CopyIndex, "CLOSED")) {
|
|
|
|
|
|
log_warn("> WiFi OTA: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD> @%u", (unsigned)offset);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
if (hdr_end == 0) {
|
|
|
|
|
|
log_warn("> WiFi OTA: <20><>Ӧͷ<D3A6><CDB7>ʱ @%u", (unsigned)offset);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD> 206<30><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7> Range<67><65>200 ˵<><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Range<67><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѳ<EFBFBD><D1B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
if (strncmp((char *)U2_CopyBuff, "HTTP/", 5) != 0) {
|
|
|
|
|
|
log_warn("> WiFi OTA: <20><>Ӧ<EFBFBD>쳣 @%u", (unsigned)offset);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!ota_memfind(U2_CopyBuff, 16, " 206")) {
|
|
|
|
|
|
U2_CopyBuff[hdr_end < 120 ? hdr_end : 120] = '\0';
|
|
|
|
|
|
log_warn("> WiFi OTA: <20><> 206 <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7> Range?<3F><>: %.60s", U2_CopyBuff);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><>һ<EFBFBD>飺<EFBFBD><E9A3BA> Content-Range: bytes 0-x/TOTAL <20><><EFBFBD>ܴ<EFBFBD>С<EFBFBD><D0A1>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> B */
|
|
|
|
|
|
if (total_size == 0) {
|
|
|
|
|
|
uint8_t *cr = ota_memfind_i(U2_CopyBuff, hdr_end, "content-range:");
|
|
|
|
|
|
uint8_t *slash = cr ? (uint8_t *)strchr((char *)cr, '/') : NULL;
|
|
|
|
|
|
if (slash) total_size = (uint32_t)atoi((char *)slash + 1);
|
|
|
|
|
|
if (total_size == 0 || total_size > Application_Size) {
|
|
|
|
|
|
log_warn("> WiFi OTA: <20>̼<EFBFBD><CCBC>ܴ<EFBFBD>С<EFBFBD>쳣 %u", (unsigned)total_size);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
log_info("**************************************");
|
|
|
|
|
|
log_info("* WiFi OTA <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ *");
|
|
|
|
|
|
log_info("* <20>̼<EFBFBD><CCBC><EFBFBD>С: %u <20>ֽ<EFBFBD> *", (unsigned)total_size);
|
|
|
|
|
|
log_info("**************************************");
|
|
|
|
|
|
log_info("> <20><><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD> W25Q64 <20>²<EFBFBD>λ...");
|
|
|
|
|
|
W25Q64_EraseRegion(W25Q64_SLOT_NEW_ADDR, W25Q64_SLOT_SIZE);
|
|
|
|
|
|
log_info("> W25Q64 <20>²<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD>鳤<EFBFBD><E9B3A4> = Content-Length<74><68><EFBFBD><EFBFBD>3072<37><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ܸ<EFBFBD>С<EFBFBD><D0A1> */
|
|
|
|
|
|
uint32_t clen = 0;
|
|
|
|
|
|
{
|
|
|
|
|
|
uint8_t *cl = ota_memfind_i(U2_CopyBuff, hdr_end, "content-length:");
|
|
|
|
|
|
if (cl) clen = (uint32_t)atoi((char *)cl + 15);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (clen == 0 || clen > WIFI_OTA_CHUNK) {
|
|
|
|
|
|
log_warn("> WiFi OTA: <20>鳤<EFBFBD><E9B3A4><EFBFBD>쳣 %u @%u", (unsigned)clen, (unsigned)offset);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
ota_consume((uint16_t)hdr_end);
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><>ȷ<EFBFBD><C8B7> clen <20>ֽڹ̼<DAB9><CCBC>嵽<EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD> */
|
|
|
|
|
|
uint16_t got = 0;
|
|
|
|
|
|
tick = HAL_GetTick();
|
|
|
|
|
|
while (got < clen) {
|
|
|
|
|
|
if (U2_CopyIndex > 0) {
|
|
|
|
|
|
tick = HAL_GetTick();
|
|
|
|
|
|
uint16_t n = U2_CopyIndex;
|
|
|
|
|
|
if (n > (uint16_t)(clen - got)) n = (uint16_t)(clen - got);
|
|
|
|
|
|
memcpy(s_blk + got, U2_CopyBuff, n);
|
|
|
|
|
|
got += n;
|
|
|
|
|
|
ota_consume(n);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (HAL_GetTick() - tick > WIFI_OTA_IDLE_TIMEOUT) {
|
|
|
|
|
|
log_warn("> WiFi OTA: <20><><EFBFBD>ݽ<EFBFBD><DDBD>ճ<EFBFBD>ʱ @%u <20><><EFBFBD><EFBFBD> %u/%u",
|
|
|
|
|
|
(unsigned)offset, got, (unsigned)clen);
|
|
|
|
|
|
log_warn("> OTA <20><><EFBFBD><EFBFBD>: CNDTR=%u RxState=%u rxcplt=%u ore=%u pending=%u",
|
|
|
|
|
|
(unsigned)huart4.hdmarx->Instance->CNDTR,
|
|
|
|
|
|
(unsigned)huart4.RxState,
|
|
|
|
|
|
(unsigned)g_uart4_rxcplt_cnt,
|
|
|
|
|
|
(unsigned)g_uart4_ore_cnt,
|
|
|
|
|
|
(unsigned)U2_CopyIndex);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
bg_delay(20);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* д W25Q64 <20><> B + <20>ض<EFBFBD>У<EFBFBD><D0A3> + <20>ۼ<EFBFBD> CRC */
|
|
|
|
|
|
W25Q64_WriteBuffer(W25Q64_SLOT_NEW_ADDR + offset, s_blk, clen);
|
|
|
|
|
|
if (!W25Q64_Verify(W25Q64_SLOT_NEW_ADDR + offset, s_blk, clen)) {
|
|
|
|
|
|
log_error("> WiFi OTA: W25Q64 <20>ض<EFBFBD>У<EFBFBD><D0A3>ʧ<EFBFBD><CAA7> offset=%u", (unsigned)offset);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
for (uint16_t i = 0; i < clen; i++) {
|
|
|
|
|
|
crc_acc = crc16_modbus_update(crc_acc, s_blk[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
offset += clen;
|
|
|
|
|
|
|
|
|
|
|
|
int pct = (int)(offset * 100 / total_size);
|
|
|
|
|
|
if (pct > 100) pct = 100;
|
|
|
|
|
|
if (pct / 10 > last_pct / 10) {
|
|
|
|
|
|
last_pct = pct;
|
|
|
|
|
|
log_info("> [%3d%%] %u/%uB", pct, (unsigned)offset, (unsigned)total_size);
|
|
|
|
|
|
LED2_TOGGLE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (offset >= total_size) break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD> CRC16 У<><D0A3> */
|
|
|
|
|
|
log_info("> W25Q64 CRC16=0x%04X (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>=0x%04X)", crc_acc, crc16);
|
|
|
|
|
|
if (crc16 != 0 && crc_acc != crc16) {
|
|
|
|
|
|
log_error("> WiFi OTA: CRC16 У<>鲻ƥ<E9B2BB>䣡<EFBFBD><E4A3A1>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>");
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* <20>̼<EFBFBD>ͷ<EFBFBD>Ϸ<EFBFBD><CFB7><EFBFBD>У<EFBFBD>飨ջ<E9A3A8><D5BB>/<2F><>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
if (!Verify_Firmware_External(W25Q64_SLOT_NEW_ADDR, total_size)) {
|
|
|
|
|
|
log_error("> WiFi OTA: <20>̼<EFBFBD>ͷУ<CDB7><D0A3><EFBFBD><EFBFBD>Ч");
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*out_size = total_size;
|
|
|
|
|
|
log_info("> WiFi OTA: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD>%uB У<><D0A3>ͨ<EFBFBD><CDA8>", (unsigned)total_size);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*==== WiFi OTA <20><><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD> air780e_trigger_ota <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ====
|
|
|
|
|
|
* <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> result=1 <EFBFBD><EFBFBD>д<EFBFBD><EFBFBD>Ϣ<EFBFBD><EFBFBD>ֱ<EFBFBD>Ӹ<EFBFBD>λ<EFBFBD><EFBFBD> BootLoader<EFBFBD><EFBFBD>
|
|
|
|
|
|
* ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD>ϱ<EFBFBD> result=0<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD> MQTT <EFBFBD><EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD> */
|
|
|
|
|
|
void net_wifi_ota(const char *host, int port, const char *path,
|
|
|
|
|
|
const char *ota_id, uint16_t new_ver, uint16_t crc16)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t file_size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
log_info("> WiFi OTA: <20><>ʼ");
|
|
|
|
|
|
feedScaleStop(); /* <20><><EFBFBD><EFBFBD>ģʽ<C4A3><CABD>ֹͣͶι״̬<D7B4><CCAC> */
|
|
|
|
|
|
relaySet(1, 0); /* <20><EFBFBD>ģʽ<C4A3><CABD>ֱ<EFBFBD>ӶϿ<D3B6>Ͷι<CDB6>̵<EFBFBD><CCB5><EFBFBD> */
|
|
|
|
|
|
|
|
|
|
|
|
/* MQTT <20><><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD>ʼ<EFBFBD><CABC>progress 0<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><EFBFBD> */
|
|
|
|
|
|
NET_mqtt_report("iot.ota.progress.post", ota_id, 0);
|
|
|
|
|
|
bg_delay(500);
|
|
|
|
|
|
g_net_tx_busy = 1;
|
|
|
|
|
|
g_wifi_mqtt_ready = 0; /* MQTT <20><>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD> OTA <20><><EFBFBD>Ӷ<EFBFBD><D3B6><EFBFBD> */
|
|
|
|
|
|
|
|
|
|
|
|
int ret = wifi_ota_download(host, port, path, crc16, &file_size);
|
|
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD> MQTT<54><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WiFi <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λģ<CEBB><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>AP<41><50><EFBFBD><CDB8><EFBFBD><EFBFBD>CONNECT/SUB<55><42><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
if (net_wifi_init() == 0) {
|
|
|
|
|
|
g_net_tx_busy = 0;
|
|
|
|
|
|
NET_mqtt_report("iot.ota.result.post", ota_id, ret == 0 ? 1 : 0);
|
|
|
|
|
|
bg_delay(2000); /* <20>Ƚ<EFBFBD><C8BD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD> */
|
|
|
|
|
|
} else {
|
|
|
|
|
|
g_net_tx_busy = 0;
|
|
|
|
|
|
log_warn("> WiFi OTA: MQTT <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD>ʧ");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (ret == 0) {
|
|
|
|
|
|
log_info("**************************************");
|
|
|
|
|
|
log_info("* WiFi OTA <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD> *");
|
|
|
|
|
|
log_info("* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> BootLoader... *");
|
|
|
|
|
|
log_info("**************************************");
|
|
|
|
|
|
/* ֻ<>ѹ̼<D1B9><CCBC><EFBFBD>Ϣд<CFA2><D0B4> W25Q64<36><34><EFBFBD>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD> APP ȷ<>ϳɹ<CFB3><C9B9><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4> EEPROM */
|
2026-08-19 23:10:15 +08:00
|
|
|
|
W25Q64_OTA_SetNewInfo(new_ver, file_size, crc16);
|
2026-08-10 21:18:36 +08:00
|
|
|
|
reset_log_mark(RSN_OTA_UPDATE);
|
|
|
|
|
|
bg_delay(100);
|
|
|
|
|
|
NVIC_SystemReset();
|
|
|
|
|
|
}
|
|
|
|
|
|
log_warn("> WiFi OTA: <20><><EFBFBD><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|
|
|
|
|
}
|