From c8240d55741f0ed86099a0a8c616f4fc68372134 Mon Sep 17 00:00:00 2001
From: yincheng.zhong <634916154@qq.com>
Date: 星期四, 25 十二月 2025 10:17:55 +0800
Subject: [PATCH] OTA功能测试完成,4G超时时间异常,出现4G中断情况,等杜工修改。
---
STM32H743/APL/OTAUpgrade.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 155 insertions(+), 22 deletions(-)
diff --git a/STM32H743/APL/OTAUpgrade.c b/STM32H743/APL/OTAUpgrade.c
index 2769b15..d416899 100644
--- a/STM32H743/APL/OTAUpgrade.c
+++ b/STM32H743/APL/OTAUpgrade.c
@@ -12,6 +12,8 @@
#include "HIDO_Debug.h"
#include "HIDO_Util.h"
#include "string.h"
+#include "BootMark.h" // Boot鏍囪绠$悊妯″潡
+#include "SoftCRC.h" // 杞欢CRC
// 寮曞叆AES瑙e瘑绠楁硶
#include "../decryption/aes.h"
@@ -194,7 +196,14 @@
{
HIDO_INT32 i32Ret;
- HIDO_Debug("[OTA] Callback: RespCode=%d, DataLen=%d\r\n", _u32RespCode, _u32Len);
+ HIDO_Debug("[OTA] Callback: RespCode=%d, DataLen=%d, State=%d\r\n",
+ _u32RespCode, _u32Len, l_stOTAInfo.eState);
+
+ // 濡傛灉宸茬粡杩涘叆瑙e瘑/鏍¢獙闃舵锛屽拷鐣ュ悗缁殑涓嬭浇鍥炶皟锛圚TTP杩炴帴鍏抽棴鏃剁殑鍥炶皟锛�
+ if (l_stOTAInfo.eState >= OTA_STATE_DECRYPTING) {
+ HIDO_Debug("[OTA] Ignoring download callback (already in decrypt/verify phase)\r\n");
+ return HIDO_OK;
+ }
// 妫�鏌TTP鍝嶅簲鐮�
if (_u32RespCode != 200 && _u32RespCode != 206) {
@@ -242,6 +251,9 @@
i32Ret = OTA_FlashWriteAligned(OTA_ENCRYPTED_FLASH_ADDR,
l_u32FlashWrittenBytes,
_pu8Data, _u32Len);
+
+ HIDO_Debug("[OTA-DBG] FlashWriteAligned ret=%d\r\n", i32Ret);
+
if (i32Ret < 0) {
HIDO_Debug("[OTA] Flash write failed at offset: 0x%X\r\n",
l_stOTAInfo.u32DownloadedSize);
@@ -263,6 +275,10 @@
// 姣�10%鎵撳嵃涓�娆¤繘搴�
static HIDO_UINT8 s_u8LastLogProgress = 0;
+ if (l_stOTAInfo.u8Progress == 0) {
+ s_u8LastLogProgress = 0;
+ }
+
if (l_stOTAInfo.u8Progress >= s_u8LastLogProgress + 10) {
HIDO_Debug("[OTA] Download progress: %d%% (%d/%d bytes)\r\n",
l_stOTAInfo.u8Progress,
@@ -272,15 +288,22 @@
}
}
+ HIDO_Debug("[OTA-DBG] Check completion: Downloaded=%d, Total=%d\r\n",
+ l_stOTAInfo.u32DownloadedSize, l_stOTAInfo.u32TotalSize);
+
// 涓嬭浇瀹屾垚
if (l_stOTAInfo.u32DownloadedSize >= l_stOTAInfo.u32TotalSize &&
l_stOTAInfo.u32TotalSize > 0) {
+ HIDO_Debug("[OTA] Download complete check passed, flushing buffer...\r\n");
+
// 鍒锋柊缂撳啿鍖猴紙鍐欏叆鍓╀綑鏁版嵁锛�
if (l_u32FlashWriteBufferLen > 0) {
+ HIDO_Debug("[OTA] Flushing %d bytes...\r\n", l_u32FlashWriteBufferLen);
OTA_FlushFlashWriteBuffer(OTA_ENCRYPTED_FLASH_ADDR,
l_u32FlashWrittenBytes,
&l_u32FlashWrittenBytes);
+ HIDO_Debug("[OTA] Flush completed\r\n");
}
l_stOTAInfo.eState = OTA_STATE_DOWNLOAD_COMPLETE;
@@ -339,8 +362,8 @@
i32Ret = MCUFlash_Write(u32FlashAddr, l_au8FlashWriteBuffer, OTA_FLASH_ALIGN_SIZE);
if (i32Ret != HIDO_OK) {
- HIDO_Debug("[OTA] MCUFlash_Write failed at 0x%08X (TotalWritten=0x%X)\r\n",
- u32FlashAddr, _u32WrittenBytes + u32FlashWrittenThisCall);
+ HIDO_Debug("[OTA] MCUFlash_Write failed at 0x%08X (TotalWritten=0x%X), ret=%d\r\n",
+ u32FlashAddr, _u32WrittenBytes + u32FlashWrittenThisCall, i32Ret);
return HIDO_ERR;
}
@@ -365,12 +388,20 @@
HIDO_UINT32 *_pu32GlobalWrittenBytes)
{
if (l_u32FlashWriteBufferLen > 0) {
- // 鍓╀綑閮ㄥ垎鐢�0xFF濉厖鍒�32瀛楄妭瀵归綈
+ HIDO_Debug("[OTA] Flush: bufLen=%d, addr=0x%08X\r\n",
+ l_u32FlashWriteBufferLen, _u32BaseAddr + _u32WrittenBytes);
+
+ // 鍓╀綑閮ㄥ垎鐢�00xFF濉厖鍒�32瀛楄妭瀵归綈
memset(l_au8FlashWriteBuffer + l_u32FlashWriteBufferLen, 0xFF,
OTA_FLASH_ALIGN_SIZE - l_u32FlashWriteBufferLen);
HIDO_UINT32 u32FlashAddr = _u32BaseAddr + _u32WrittenBytes;
- if (MCUFlash_Write(u32FlashAddr, l_au8FlashWriteBuffer, OTA_FLASH_ALIGN_SIZE) != HIDO_OK) {
+
+ HIDO_Debug("[OTA] Calling MCUFlash_Write...\r\n");
+ HIDO_INT32 ret = MCUFlash_Write(u32FlashAddr, l_au8FlashWriteBuffer, OTA_FLASH_ALIGN_SIZE);
+ HIDO_Debug("[OTA] MCUFlash_Write returned: %d\r\n", ret);
+
+ if (ret != HIDO_OK) {
HIDO_Debug("[OTA] Flush buffer failed at 0x%08X\r\n", u32FlashAddr);
return HIDO_ERR;
}
@@ -389,10 +420,13 @@
/**
* @brief 鍚姩鍥轰欢瑙e瘑
+ * @details 鍒ゆ柇褰撳墠杩愯鐨凙PP锛屽喅瀹氱洰鏍嘇PP鍦板潃锛岀洿鎺ヨВ瀵嗗埌鐩爣APP鍖哄煙
*/
HIDO_INT32 OTA_StartDecrypt(HIDO_VOID)
{
HIDO_INT32 ret;
+ uint32_t vtor;
+ uint32_t targetAppAddr;
// 鐘舵�佹鏌�
if (l_stOTAInfo.eState != OTA_STATE_DOWNLOAD_COMPLETE) {
@@ -400,11 +434,18 @@
return HIDO_ERR;
}
- // 鎿﹂櫎瑙e瘑鍥轰欢瀛樺偍鍖�
- HIDO_Debug("[OTA] Erasing decrypted flash area: 0x%08X, size: %d KB\r\n",
- OTA_DECRYPTED_FLASH_ADDR, OTA_DECRYPTED_FLASH_SIZE / 1024);
+ // 鐩爣濮嬬粓鏄殏瀛樺尯 (Single Bank with Staging)
+ targetAppAddr = BOOT_OTA_STAGING_ADDR;
+ HIDO_Debug("[OTA] Target: Staging Area (0x%08X)\r\n", targetAppAddr);
- if (MCUFlash_Erase(OTA_DECRYPTED_FLASH_ADDR, OTA_DECRYPTED_FLASH_SIZE) != HIDO_OK) {
+ // 淇濆瓨鐩爣APP鍦板潃
+ l_stOTAInfo.u32TargetAppAddr = targetAppAddr;
+
+ // 鎿﹂櫎鐩爣APP鍖哄煙锛�256KB锛�
+ HIDO_Debug("[OTA] Erasing target APP area: 0x%08X, size: %d KB\r\n",
+ targetAppAddr, BOOT_APP_MAX_SIZE / 1024);
+
+ if (MCUFlash_Erase(targetAppAddr, BOOT_APP_MAX_SIZE) != HIDO_OK) {
HIDO_Debug("[OTA] Flash erase failed\r\n");
l_stOTAInfo.eState = OTA_STATE_DECRYPT_FAILED;
l_stOTAInfo.eLastError = OTA_ERR_FLASH_ERASE_FAILED;
@@ -426,7 +467,7 @@
// 楠岃瘉Flash鏄惁宸叉摝闄わ紙妫�鏌ュ墠64瀛楄妭锛�
HIDO_UINT8 au8VerifyBuf[64];
- if (MCUFlash_Read(OTA_DECRYPTED_FLASH_ADDR, au8VerifyBuf, 64) == HIDO_OK) {
+ if (MCUFlash_Read(targetAppAddr, au8VerifyBuf, 64) == HIDO_OK) {
HIDO_BOOL bEraseOk = HIDO_TRUE;
for (HIDO_UINT32 i = 0; i < 64; i++) {
if (au8VerifyBuf[i] != 0xFF) {
@@ -484,7 +525,7 @@
if (l_stOTAInfo.u32DecryptedSize >= l_stOTAInfo.u32TotalSize) {
// 瑙e瘑瀹屾垚锛屽埛鏂扮紦鍐插尯
if (l_u32FlashWriteBufferLen > 0) {
- OTA_FlushFlashWriteBuffer(OTA_DECRYPTED_FLASH_ADDR,
+ OTA_FlushFlashWriteBuffer(l_stOTAInfo.u32TargetAppAddr,
l_u32DecryptFlashWrittenBytes,
&l_u32DecryptFlashWrittenBytes);
}
@@ -531,11 +572,11 @@
l_au8DecryptBuffer[0], l_au8DecryptBuffer[1], l_au8DecryptBuffer[2], l_au8DecryptBuffer[3],
l_au8DecryptBuffer[4], l_au8DecryptBuffer[5], l_au8DecryptBuffer[6], l_au8DecryptBuffer[7]);
HIDO_Debug("[OTA] Writing to: BaseAddr=0x%08X, WrittenBytes=0x%X, Len=0x%X\r\n",
- OTA_DECRYPTED_FLASH_ADDR, l_u32DecryptFlashWrittenBytes, u32ReadLen);
+ l_stOTAInfo.u32TargetAppAddr, l_u32DecryptFlashWrittenBytes, u32ReadLen);
}
- // 鍐欏叆瑙e瘑鍚庣殑鏁版嵁
- i32Ret = OTA_FlashWriteAligned(OTA_DECRYPTED_FLASH_ADDR,
+ // 鍐欏叆瑙e瘑鍚庣殑鏁版嵁鍒扮洰鏍嘇PP鍦板潃
+ i32Ret = OTA_FlashWriteAligned(l_stOTAInfo.u32TargetAppAddr,
l_u32DecryptFlashWrittenBytes,
l_au8DecryptBuffer, u32ReadLen);
if (i32Ret < 0) {
@@ -596,7 +637,7 @@
HIDO_UINT32 u32SearchLen = l_stOTAInfo.u32TotalSize - u32SearchStart;
// 璇诲彇鏂囦欢鏈熬鏁版嵁
- if (MCUFlash_Read(OTA_DECRYPTED_FLASH_ADDR + u32SearchStart, au8SearchBuf, u32SearchLen) != HIDO_OK) {
+ if (MCUFlash_Read(l_stOTAInfo.u32TargetAppAddr + u32SearchStart, au8SearchBuf, u32SearchLen) != HIDO_OK) {
HIDO_Debug("[OTA] Read flash failed for terminator search\r\n");
l_stOTAInfo.eState = OTA_STATE_VERIFY_FAILED;
l_stOTAInfo.eLastError = OTA_ERR_DECRYPT_FAILED;
@@ -642,7 +683,7 @@
// 璁$畻鏍¢獙鍜岋紙鍥轰欢鏁版嵁閮ㄥ垎锛屼笉鍖呮嫭鏍¢獙鍜屽拰缁撴潫绗︼級
for (i = 0; i < u32DataEndPos; i++) {
- if (MCUFlash_Read(OTA_DECRYPTED_FLASH_ADDR + i, &u8Byte, 1) != HIDO_OK) {
+ if (MCUFlash_Read(l_stOTAInfo.u32TargetAppAddr + i, &u8Byte, 1) != HIDO_OK) {
HIDO_Debug("[OTA] Read flash failed at offset: 0x%X\r\n", i);
l_stOTAInfo.eState = OTA_STATE_VERIFY_FAILED;
l_stOTAInfo.eLastError = OTA_ERR_DECRYPT_FAILED;
@@ -653,7 +694,7 @@
u32CalculatedSum &= 0xFFFFFFFF;
// 璇诲彇瀛樺偍鐨勬牎楠屽拰锛�0x0D鍓�4瀛楄妭锛屽皬绔簭锛�
- if (MCUFlash_Read(OTA_DECRYPTED_FLASH_ADDR + u32ChecksumPos,
+ if (MCUFlash_Read(l_stOTAInfo.u32TargetAppAddr + u32ChecksumPos,
au8ChecksumBytes, 4) != HIDO_OK) {
HIDO_Debug("[OTA] Read checksum failed\r\n");
l_stOTAInfo.eState = OTA_STATE_VERIFY_FAILED;
@@ -675,6 +716,10 @@
l_stOTAInfo.eState = OTA_STATE_VERIFY_SUCCESS;
l_stOTAInfo.eLastError = OTA_ERR_NONE;
HIDO_Debug("[OTA] Firmware verification SUCCESS!\r\n");
+
+ // 鏍¢獙鎴愬姛鍚庯紝鏇存柊Boot鏍囪
+ OTA_UpdateBootMark();
+
return HIDO_OK;
} else {
l_stOTAInfo.eState = OTA_STATE_VERIFY_FAILED;
@@ -753,6 +798,14 @@
// 妫�鏌ヤ笅杞借秴鏃舵垨澶辫触
if (l_stOTAInfo.eState == OTA_STATE_DOWNLOADING) {
+ // 妫�鏌ユ槸鍚﹀凡缁忎笅杞藉畬鎴愪絾鐘舵�佹湭鏇存柊锛堝彲鑳藉崱鍦ㄥ洖璋冨嚱鏁颁腑锛�
+ if (l_stOTAInfo.u32DownloadedSize >= l_stOTAInfo.u32TotalSize &&
+ l_stOTAInfo.u32TotalSize > 0 &&
+ u32ElapsedMs > 5000) { // 5绉掑悗杩樻病杞崲鐘舵��
+ HIDO_Debug("[OTA] WARNING: Download finished but state not updated! Forcing complete...\r\n");
+ l_stOTAInfo.eState = OTA_STATE_DOWNLOAD_COMPLETE;
+ }
+
// 濡傛灉瓒呰繃30绉掓病鏈夎繘搴︼紝璁や负涓嬭浇瓒呮椂
if (u32ElapsedMs > OTA_DOWNLOAD_TIMEOUT_MS) {
HIDO_Debug("[OTA] Download timeout! No data received for %d ms\r\n", u32ElapsedMs);
@@ -764,13 +817,15 @@
}
}
- // 澶勭悊涓嬭浇澶辫触锛屽皾璇曢噸璇�
- if (l_stOTAInfo.eState == OTA_STATE_DOWNLOAD_FAILED) {
+ // 澶勭悊澶辫触锛堜笅杞姐�佽В瀵嗘垨鏍¢獙澶辫触锛夛紝灏濊瘯閲嶈瘯
+ if (l_stOTAInfo.eState == OTA_STATE_DOWNLOAD_FAILED ||
+ l_stOTAInfo.eState == OTA_STATE_DECRYPT_FAILED ||
+ l_stOTAInfo.eState == OTA_STATE_VERIFY_FAILED) {
// 妫�鏌ユ槸鍚﹁繕鏈夐噸璇曟満浼�
if (l_u8RetryCount < OTA_MAX_RETRY_COUNT) {
l_u8RetryCount++;
- HIDO_Debug("[OTA] Retry attempt %d/%d...\r\n",
- l_u8RetryCount, OTA_MAX_RETRY_COUNT);
+ HIDO_Debug("[OTA] Error detected (State=%d). Retry attempt %d/%d...\r\n",
+ l_stOTAInfo.eState, l_u8RetryCount, OTA_MAX_RETRY_COUNT);
// 閲嶇疆HTTP瀹㈡埛绔姸鎬侊紙鍏抽棴涔嬪墠鐨勮繛鎺ワ級
HIDO_Debug("[OTA] Resetting HTTP client...\r\n");
@@ -788,7 +843,7 @@
}
} else {
// 宸茶揪鍒版渶澶ч噸璇曟鏁帮紝褰诲簳鏀惧純
- HIDO_Debug("[OTA] Download failed after %d retries - GIVING UP\r\n", OTA_MAX_RETRY_COUNT);
+ HIDO_Debug("[OTA] Operation failed after %d retries - GIVING UP\r\n", OTA_MAX_RETRY_COUNT);
l_stOTAInfo.eState = OTA_STATE_IDLE; // 鍥炲埌绌洪棽鐘舵�侊紝鍋滄閲嶈瘯
l_stOTAInfo.eLastError = OTA_ERR_HTTP_FAILED;
l_u8RetryCount = 0; // 閲嶇疆閲嶈瘯璁℃暟
@@ -808,3 +863,81 @@
OTA_ProcessDecryptTask();
}
}
+
+/**
+ * @brief 鏇存柊Boot鏍囪锛圤TA鍗囩骇鎴愬姛鍚庤皟鐢級
+ * @details 鏍规嵁褰撳墠杩愯鐨凙PP锛屽皢鏂板浐浠舵爣璁板啓鍏ュ彟涓�涓狝PP鍖哄煙
+ */
+HIDO_VOID OTA_UpdateBootMark(HIDO_VOID)
+{
+ int32_t ret;
+ BootMark_t bootMark;
+ uint32_t targetAppAddr;
+ uint32_t firmwareSize;
+ uint32_t firmwareCRC;
+
+ HIDO_Debug("[OTA] Updating boot mark...\r\n");
+
+ // 浣跨敤瑙e瘑闃舵宸茬‘瀹氱殑鐩爣APP鍦板潃 (Staging)
+ targetAppAddr = l_stOTAInfo.u32TargetAppAddr;
+
+ // 璁$畻瑙e瘑鍚庡浐浠剁殑澶у皬锛堜笉鍖呭惈鏍¢獙鍜屽拰0x0D 0x0A锛�
+ // 鍥轰欢瀹為檯澶у皬 = u32TotalSize - 4瀛楄妭鏍¢獙鍜� - 2瀛楄妭缁撴潫绗�
+ firmwareSize = l_stOTAInfo.u32TotalSize - 6;
+
+ // 璁$畻鍥轰欢鐨凜RC32锛堜粠鏆傚瓨鍖鸿鍙栵級
+ uint32_t wordCount = (firmwareSize + 3) / 4; // 鍚戜笂鍙栨暣鍒�32浣嶅瓧
+ firmwareCRC = SoftCRC_Calculate((uint32_t *)targetAppAddr, wordCount);
+
+ HIDO_Debug("[OTA] Firmware size: %u bytes, CRC32: 0x%08X\r\n",
+ firmwareSize, firmwareCRC);
+
+ // 璇诲彇褰撳墠Boot鏍囪浠ヨ幏鍙栫増鏈彿锛堝鏋滄湁鐨勮瘽锛�
+ uint32_t newVersion = 1;
+ BootMark_t currentMark;
+ if (BootMark_Read(¤tMark) == BOOT_OK) {
+ newVersion = currentMark.u32Version + 1;
+ }
+
+ // 濉厖鏂扮殑Boot鏍囪
+ memset(&bootMark, 0, sizeof(BootMark_t));
+ bootMark.u32Magic = BOOT_MARK_MAGIC;
+ bootMark.u32UpdateFlag = BOOT_UPDATE_PENDING; // 鏍囪涓哄緟鏇存柊
+ bootMark.u32FirmwareSize = firmwareSize;
+ bootMark.u32FirmwareCRC = firmwareCRC;
+ bootMark.u32Version = newVersion;
+ bootMark.u32SrcAddress = targetAppAddr; // 婧愶細鏆傚瓨鍖�
+ bootMark.u32DstAddress = BOOT_APP_ADDR; // 鐩爣锛欰PP杩愯鍖�
+ bootMark.u32BootMarkCRC = BootMark_CalculateCRC(&bootMark);
+
+ // 璋冭瘯锛氭墦鍗癇oot鏍囪鍐呭
+ HIDO_Debug("[OTA] BootMark before write:\r\n");
+ HIDO_Debug(" Magic: 0x%08X\r\n", bootMark.u32Magic);
+ HIDO_Debug(" Update: 0x%08X\r\n", bootMark.u32UpdateFlag);
+ HIDO_Debug(" Size: %u\r\n", bootMark.u32FirmwareSize);
+ HIDO_Debug(" CRC: 0x%08X\r\n", bootMark.u32FirmwareCRC);
+ HIDO_Debug(" Version: %u\r\n", bootMark.u32Version);
+ HIDO_Debug(" Src: 0x%08X\r\n", bootMark.u32SrcAddress);
+ HIDO_Debug(" Dst: 0x%08X\r\n", bootMark.u32DstAddress);
+ HIDO_Debug(" MarkCRC: 0x%08X\r\n", bootMark.u32BootMarkCRC);
+
+ // 鍐欏叆Boot鏍囪
+ HIDO_Debug("[OTA] Writing boot mark (Request Update)...\r\n");
+ ret = BootMark_Write(&bootMark);
+ if (ret != BOOT_OK) {
+ HIDO_Debug("[OTA] ERROR: Failed to write boot mark: %d\r\n", ret);
+ return;
+ }
+
+ HIDO_Debug("[OTA] Boot mark updated successfully!\r\n");
+ HIDO_Debug("[OTA] System will restart in 2 seconds...\r\n");
+
+ // 绛夊緟涓插彛鍙戦�佸畬鎴�
+ HAL_Delay(2000);
+
+ // 绯荤粺閲嶅惎
+ HIDO_Debug("[OTA] Restarting system now!\r\n");
+ HAL_Delay(100); // 绛夊緟鏈�鍚庝竴鏉℃棩蹇楀彂閫佸畬鎴�
+
+ NVIC_SystemReset(); // 鎵ц绯荤粺澶嶄綅
+}
--
Gitblit v1.10.0