Index: yc_unsignAppVerify.h
===================================================================
--- /YC3121_SDK/fw/sdk/yc_unsignAppVerify.h	(revision 973)
+++ /YC3121_SDK/fw/sdk/yc_unsignAppVerify.h	(working copy)
@@ -1,8 +1,8 @@
 /*
 File Name    : yc_unsignAppVerify.h
 Author       : Yichip
-Version      : V1.0
-Date         : 2020/03/10
+Version      : V1.2
+Date         : 2022/07/29
 Description  : unsign app verify encapsulation.
 */
 
@@ -11,13 +11,17 @@
 
 #include "yc3121.h"
 
+#define APP_CHECK_FLAG_ADDR     (0x1000000+((512-12)*1024))     //0x107d000
 
 /**
   * @brief  verify app and send result to uart
-  *         Verification is performed only after the serial port is downloaded for the first time, which does not affect normal startup.
+  *         1、此函数需在main函数头上调用配合量产下载软件进行固件校验(有boot则放在boot main函数头上调用)
+  *         2、校验函数使用标记位控制，量产时只有下载完程序后的第一次启动才会执行校验流程，正常使用过程中不会进入校验流程
+  *         3、校验标记存储地址APP_CHECK_FLAG_ADDR由应用开发人员分配一个没有使用的flash sector(4k)地址,注意地址4k对齐
+  *         4、对于使用外部电子开关实现系统供电的方案，在调用次函数前需先使能电源hold IO，防止硬件开关抖动出现掉电导致读标记位异常
   * @param  none
   * @return none
   */
-void flash_app_check();
+void flash_app_check(void);
 
 #endif
Index: yc_unsignAppVerify.c
===================================================================
--- /YC3121_SDK/fw/sdk/yc_unsignAppVerify.c	(revision 973)
+++ /YC3121_SDK/fw/sdk/yc_unsignAppVerify.c	(working copy)
@@ -5,21 +5,53 @@
 
 //#define APP_CHECK_DEBUG
 
-#define APP_CHECK_FLAG_ADDR     0x1000140
+#define APP_CHECK_OK_FLAG       (0x55aa55aa)
+#define APP_CHECK_ERROR_FLAG    (0)
+#define IV_ADDR                 (0x1000000)
+#define IV_LEN                  (16)
+
+#define RESULT_CHECK_OK         (0x00)
+#define RESULT_CRC_ERROR        (0x01)
+#define RESULT_LEN_ERROR        (0x02)
+#define RESULT_WRITE_ERROR      (0x04)
+
+uint16_t crc_16(uint16_t base_crc,uint8_t* data,int len)
+{
+    uint16_t tempData;
+    for(int i=0;i<len;i++)
+    {
+        tempData = data[i];
+        base_crc  = (base_crc >> 8) | (base_crc << 8);
+        base_crc ^= tempData & 0xff;
+        base_crc ^= (base_crc & 0xff) >> 4;
+        base_crc ^= base_crc << 12;
+        base_crc ^= (base_crc & 0xff) << 5;
+        base_crc &= 0xffff;
+    }
+    return base_crc;
+}
+
 void flash_app_check()
 {
     uint8_t result[7]={0xaa,0x10,0x03,0x00};
     uint8_t data[0x1000];
-    uint16_t CRC = 0xffff;
-    uint16_t tempData;
+    uint16_t crc_app = 0xffff;
+    uint16_t crc_iv  = 0xffff;
     uint32_t app_len=0;
     uint32_t packet_len=0;
     uint32_t calculated_len=0;
-    uint32_t check_flag=0;
+    uint32_t check_data[2];
+    uint32_t check_data2[2];
 
+    //read iv
+    qspi_flash_read(IV_ADDR,data,IV_LEN);
+    qspi_flash_read(IV_ADDR,data+IV_LEN,IV_LEN);//second read check
     //read flag
-    enc_read_flash(APP_CHECK_FLAG_ADDR,(uint8_t*)&check_flag,4);
-    if(check_flag==0xffffffff)
+    qspi_flash_read(APP_CHECK_FLAG_ADDR,(uint8_t*)&check_data,sizeof(check_data));
+    qspi_flash_read(APP_CHECK_FLAG_ADDR,(uint8_t*)&check_data2,sizeof(check_data2));//second read check
+    
+    crc_iv=crc_16(crc_iv,data,16);
+    if((memcmp(data,data+IV_LEN,IV_LEN)==0) && (memcmp((uint8_t*)&check_data,(uint8_t*)&check_data2,sizeof(check_data))==0) && ((crc_iv!=check_data[1])||((check_data[0]!=APP_CHECK_OK_FLAG)&&(check_data[0]!=APP_CHECK_ERROR_FLAG))))
     {
 
         //init uart
@@ -42,9 +74,10 @@
         #ifdef APP_CHECK_DEBUG
         MyPrintf("app_len=%x\r\n",app_len);
         #endif
+        result[4]=0x00;
         if(app_len==0||app_len==0xffffffff)
         {
-            result[4]=0x01;//fail
+            result[4] |=RESULT_LEN_ERROR;
         }
         else
         {
@@ -53,38 +86,32 @@
             {
                 packet_len= (app_len-calculated_len)>sizeof(data) ? sizeof(data) : app_len-calculated_len;
                 enc_read_flash_fast(0x1000200+calculated_len,data,packet_len);
-                for(int i=0;i<packet_len;i++)
-                {
-                    tempData = data[i];
-                    CRC  = (CRC >> 8) | (CRC << 8);
-                    CRC ^= tempData & 0xff;
-                    CRC ^= (CRC & 0xff) >> 4;
-                    CRC ^= CRC << 12;
-                    CRC ^= (CRC & 0xff) << 5;
-                    CRC &= 0xffff;
-                }
+                crc_app=crc_16(crc_app,data,packet_len);
                 calculated_len +=packet_len;
             }
-            //write flag
-            memset(data,0xff,32);
-            data[0]=0xaa;
-            data[1]=0x55;
-            data[2]=0xaa;
-            data[3]=0x55;
-            enc_erase_flash_32byte(APP_CHECK_FLAG_ADDR);
-            enc_write_flash(APP_CHECK_FLAG_ADDR,data,32);
             #ifdef APP_CHECK_DEBUG
-            MyPrintf("CRC=%x\r\n",CRC);
+            MyPrintf("crc_app=%x\r\n",crc_app);
             #endif
-            if(CRC==0x00)
+            if(crc_app==0x00)
             {
-               result[4]=0x00;//ok
+                result[4] = RESULT_CHECK_OK;
+                check_data[0]=APP_CHECK_OK_FLAG;
             }
             else
             {
-                result[4]=0x01;//fail
+                result[4] |= RESULT_CRC_ERROR;
+                check_data[0]=APP_CHECK_ERROR_FLAG;
+            }
+            check_data[1]=crc_iv;
+            qspi_flash_sectorerase(APP_CHECK_FLAG_ADDR);
+            delay_ms(10);
+            qspi_flash_write(APP_CHECK_FLAG_ADDR,(uint8_t*)&check_data,sizeof(check_data));
+            delay_ms(10);
+            qspi_flash_read(APP_CHECK_FLAG_ADDR,(uint8_t*)&check_data2,sizeof(check_data2));
+            if(memcmp((uint8_t*)&check_data,(uint8_t*)&check_data2,sizeof(check_data))!=0)
+            {
+                result[4] |= RESULT_WRITE_ERROR;
             }
-
         }
         ((void(*)(uint8_t* bufData, uint32_t DataLen))(0x6a14+1))(result,sizeof(result)-2);
         UART_SendBuf(UART0,result,sizeof(result));
