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(&currentMark) == 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