Просмотр исходного кода

重庆测试,版本号为:1.2.1.10,新增:1.BMS-OTA更新功能,2.修改Fota-flag,区分0x88和0x01升级程序

CHENJIE-PC\QiXiang_CHENJIE 3 лет назад
Родитель
Сommit
a3ea2d08b2
7 измененных файлов с 930 добавлено и 106 удалено
  1. 3 2
      inc/Fota.h
  2. 30 26
      inc/UartTask.h
  3. 1 1
      inc/app.h
  4. 101 69
      src/Fota.c
  5. 4 3
      src/MainTask.c
  6. 2 2
      src/TcpTask.c
  7. 789 3
      src/UartTask.c

+ 3 - 2
inc/Fota.h

@@ -21,5 +21,6 @@ typedef struct _Fota_Type
     UINT8 Fota_CRC ;
 
 }Fota_Type;
-extern volatile bool Fota_update_flag;
-void Fota_Func(UINT8 *DataPtr,INT32 connectId,UINT8 FotaType);
+extern volatile bool NB_Fota_update_flag;
+extern volatile bool BMS_Fota_update_flag;
+void Fota_Func(UINT8 *DataPtr,INT32 connectId);

+ 30 - 26
inc/UartTask.h

@@ -64,39 +64,43 @@ typedef struct Uart_Write_Answer_Msg_Type
     uint8_t Bms_Address; 
     uint8_t Bms_Funcode; 
 }Uart_Write_Answer_Msg_Type;
-typedef struct BMS_Update_Recv_Msg_Type
-{
-	UINT8 startFlag;
-	UINT8 addrFlag;
-	UINT8 cmdRW;
-	UINT8 dataLen;
-	UINT8 cmd;
-	UINT8 data;
-	UINT8 checkSum;
-	UINT8 endFlag;
-}BMS_Update_Recv_Msg_Type;
-typedef enum
-{
-	UPDATE_STEP_CHECK_VERSION=0,
-	UPDATE_STEP_REQUEST_UPDATE,
-	UPDATE_STEP_START_UPDATE,	
-	UPDATE_STEP_SET_BAUD_RATE,
-	UPDATE_STEP_PREPARE_SEND_DATA_LEN,
-	UPDATE_STEP_SEND_DATA_LEN,
-	UPDATE_STEP_PREPARE_SEND_UPDATE_DATA,
-	UPDATE_STEP_SEND_UPDATE_DATA,
-	UPDATE_STEP_SEND_DATA_END,
-	UPDATE_STEP_START_INSTALL,
-	UPDATE_STEP_END,
-	UPDATE_STEP_ERROR
-}UpdateStep;
 typedef enum
 {
     PROCESS_UART_STATE_IDLE = 0,
     PROCESS_UART_STATE_READ,
     PROCESS_UART_STATE_WRITE,
+    PROCESS_UART_STATE_UPDATE,
     PROCESS_UART_STATE_SLEEP
 }process_Uart;
+typedef enum
+{
+        UPDATE_STEP_CHECK_VERSION=0,
+        UPDATE_STEP_REQUEST_UPDATE,
+        UPDATE_STEP_START_UPDATE,        
+        UPDATE_STEP_SET_BAUD_RATE,
+        UPDATE_STEP_PREPARE_SEND_DATA_LEN,
+        UPDATE_STEP_SEND_DATA_LEN,
+        UPDATE_STEP_PREPARE_SEND_UPDATE_DATA,
+        UPDATE_STEP_SEND_UPDATE_DATA,
+        UPDATE_STEP_SEND_DATA_END,
+        UPDATE_STEP_START_INSTALL,
+        UPDATE_STEP_END,
+        UPDATE_STEP_RESET, //exit download, and go to before UPDATE_STEP_PREPARE_SEND_UPDATE_DATA
+        UPDATE_STEP_DOWNLOAD_BREAK_OFF,  //exite download, and return boot mode(not app mode)
+        UPDATE_STEP_ERROR
+}UpdateStep;
+
+typedef struct BMS_Update_Recv_Msg_Type
+{
+        UINT8 startFlag;
+        UINT8 addrFlag;
+        UINT8 cmdRW;
+        UINT8 dataLen;
+        UINT8 cmd;
+        UINT8 data;
+        UINT8 checkSum;
+        UINT8 endFlag;
+}BMS_Update_Recv_Msg_Type;
 void UartTaskInit(void* arg);
 void UartTaskDeInit(void* arg);
 UINT8 SP_BMS_Update_Query(UINT8* pSend,UINT32 sendLen, UINT8* pRead, UINT32 readLen, UINT32 timeout);

+ 1 - 1
inc/app.h

@@ -34,7 +34,7 @@ extern "C" {
 #define HWVERSION		    0x0102    //硬件主版本,现为V1.2板
 #define	BLSWVERSION		0x01020000    //BootLoader版本号V1.2.0.0
 #define	DRVSWVERSION		0x01040000     //驱动层版本号V1.4.0.0
-#define	APPSWVERSION		0x01020109      
+#define	APPSWVERSION		0x0102010A      
 
 //--------------------------------------------------------------------------------
 

+ 101 - 69
src/Fota.c

@@ -17,22 +17,16 @@ extern AppNVMDataType AppNVMData;
 static Fota_Type Fota_S;
 static UINT8 bcc_chk_fota(UINT8* data, UINT8 length);
 static UINT8 Fota_crc_chk(UINT8* data,UINT8 length);
-volatile bool Fota_update_flag = FALSE; //可以升级标志
-void Fota_Func(UINT8 *DataPtr,INT32 connectId,UINT8 FotaType)
+volatile bool NB_Fota_update_flag = FALSE; //NB可以升级标志
+volatile bool BMS_Fota_update_flag = FALSE; //NB可以升级标志
+void Fota_Func(UINT8 *DataPtr,INT32 connectId)
 {
     UINT8 Fota_Answer[43];
     UINT8 Fota_Cmd;
     INT8 ret;
-    if(FotaType==0x01)
+    if(*(DataPtr+30)==0x01)
     {
         Fota_S.Fota_Flash_Addres = FLASH_FOTA_REGION_START;
-    }
-    else if(FotaType == 0x88)
-    {
-        Fota_S.Fota_Flash_Addres = FLASH_BMS_FOTA_START_ADDR;
-    }
-    if(*(DataPtr+30)==0x01||*(DataPtr+30)==0x88)
-    {
         Fota_Cmd = *(DataPtr+31);
         Fota_Answer[0] = TCP_START_SYM1;
         Fota_Answer[1] = TCP_START_SYM2;
@@ -43,28 +37,111 @@ void Fota_Func(UINT8 *DataPtr,INT32 connectId,UINT8 FotaType)
             {
                 Fota_S.Fota_All_Data_Len = *(DataPtr+33)<<24|*(DataPtr+34)<<16|*(DataPtr+35)<<8|*(DataPtr+36);
                 Fota_S.Fota_Current_Addres = *(DataPtr+37)<<24|*(DataPtr+38)<<16|*(DataPtr+39)<<8|*(DataPtr+40);
-                if(FotaType==0x01)
+                if(Fota_S.Fota_All_Data_Len>=(FLASH_BMS_FOTA_START_ADDR - FLASH_FOTA_REGION_START))
+                {
+                    Fota_Answer[3] = 0x02;
+                }
+                else
+                {
+                    Fota_Answer[3] = 0x01;
+                }
+                memcpy(&Fota_Answer[4],(DataPtr+4),BATT_SN_LEN);
+                Fota_Answer[21] = TCP_ENCPT_DISABLE;
+                Fota_Answer[22] = 0x00;
+                Fota_Answer[23] = 0x12;
+                memcpy(&Fota_Answer[24],(DataPtr+24),18);
+                Fota_Answer[42] =  bcc_chk_fota(Fota_Answer,42);
+                tcpipConnectionSend(connectId,Fota_Answer,43,0,0,0);
+                if(Fota_Answer[3] == 0x01)
                 {
-                    if(Fota_S.Fota_All_Data_Len>=(FLASH_BMS_FOTA_START_ADDR - FLASH_FOTA_REGION_START))
+                    BSP_QSPI_Erase_Safe(Fota_S.Fota_Flash_Addres,Fota_S.Fota_All_Data_Len + 4 - (Fota_S.Fota_All_Data_Len%4)); //512k-32k = 480k -> 0x75300  0x78000
+                }
+                break;
+            }
+            case 0x02:
+            {
+                Fota_S.Fota_All_Data_Len = *(DataPtr+33)<<24|*(DataPtr+34)<<16|*(DataPtr+35)<<8|*(DataPtr+36);
+                Fota_S.Fota_Current_Addres = *(DataPtr+37)<<24|*(DataPtr+38)<<16|*(DataPtr+39)<<8|*(DataPtr+40);
+                Fota_S.Fota_Recv_Data_Len = *(DataPtr+41);
+                memset(Fota_S.Fota_Recv_Data,0x00,100);
+                memcpy(Fota_S.Fota_Recv_Data,(DataPtr+42),*(DataPtr+41));
+                Fota_S.Fota_CRC = Fota_crc_chk(Fota_S.Fota_Recv_Data,Fota_S.Fota_Recv_Data_Len);
+                if(Fota_S.Fota_CRC == *(DataPtr+Fota_S.Fota_Recv_Data_Len+42))
+                {
+                    if(Fota_S.Fota_Recv_Data_Len%4!=0)
                     {
-                        Fota_Answer[3] = 0x02;
+                    Fota_S.Fota_Recv_Data_Len = Fota_S.Fota_Recv_Data_Len + 4-(Fota_S.Fota_Recv_Data_Len%4);
                     }
-                    else
+                    ret = BSP_QSPI_Write_Safe(Fota_S.Fota_Recv_Data,Fota_S.Fota_Flash_Addres+Fota_S.Fota_Current_Addres,Fota_S.Fota_Recv_Data_Len);
+                    if(ret==QSPI_OK)
                     {
                         Fota_Answer[3] = 0x01;
                     }
-                }
-                if(FotaType==0x88)
-                {
-                    if(Fota_S.Fota_All_Data_Len>=(FLASH_BMS_FOTA_END_ADDR - FLASH_BMS_FOTA_START_ADDR))
-                    {
-                        Fota_Answer[3] = 0x02;
-                    }
                     else
                     {
-                        Fota_Answer[3] = 0x01;
+                        Fota_Answer[3] = 0x02;
                     }
                 }
+                else//数据校验失败
+                {
+                    Fota_Answer[3] = 0x02;
+                }
+                memcpy(&Fota_Answer[4],(DataPtr+4),BATT_SN_LEN);
+                Fota_Answer[21] = TCP_ENCPT_DISABLE;
+                Fota_Answer[22] = 0x00;
+                Fota_Answer[23] = 0x12;
+                memcpy(&Fota_Answer[24],(DataPtr+24),18);
+                Fota_Answer[42] =  bcc_chk_fota(Fota_Answer,42);
+                tcpipConnectionSend(connectId,Fota_Answer,43,0,0,0);
+                break;
+            }
+            case 0x03:
+            {
+                Fota_S.Fota_All_Data_Len = *(DataPtr+33)<<24|*(DataPtr+34)<<16|*(DataPtr+35)<<8|*(DataPtr+36);
+                Fota_S.Fota_Current_Addres = *(DataPtr+37)<<24|*(DataPtr+38)<<16|*(DataPtr+39)<<8|*(DataPtr+40);
+                Fota_Answer[3] = 0x01;
+                memcpy(&Fota_Answer[4],(DataPtr+4),BATT_SN_LEN);
+                Fota_Answer[21] = TCP_ENCPT_DISABLE;
+                Fota_Answer[22] = 0x00;
+                Fota_Answer[23] = 0x13;
+                memcpy(&Fota_Answer[24],(DataPtr+24),18);
+                Fota_Answer[42] =  bcc_chk_fota(Fota_Answer,42);
+                tcpipConnectionSend(connectId,Fota_Answer,43,0,0,0);
+                if(Fota_S.Fota_All_Data_Len==Fota_S.Fota_Current_Addres)
+                {
+                    NB_Fota_update_flag = TRUE;
+                }
+                else
+                {
+                    NB_Fota_update_flag = FALSE;
+                }
+                break;
+            }
+            default:
+                break;
+        }
+    }
+    else if(*(DataPtr+30)==0x88)//BMS升级文件存放
+    {
+        Fota_S.Fota_Flash_Addres = FLASH_BMS_FOTA_START_ADDR;
+        Fota_Cmd = *(DataPtr+31);
+        Fota_Answer[0] = TCP_START_SYM1;
+        Fota_Answer[1] = TCP_START_SYM2;
+        Fota_Answer[2] = TCP_CONCMD_SYM;
+        switch (Fota_Cmd)
+        {
+            case 0x01:
+            {
+                Fota_S.Fota_All_Data_Len = *(DataPtr+33)<<24|*(DataPtr+34)<<16|*(DataPtr+35)<<8|*(DataPtr+36);
+                Fota_S.Fota_Current_Addres = *(DataPtr+37)<<24|*(DataPtr+38)<<16|*(DataPtr+39)<<8|*(DataPtr+40);
+                if(Fota_S.Fota_All_Data_Len>=(FLASH_BMS_FOTA_END_ADDR - FLASH_BMS_FOTA_START_ADDR))
+                {
+                    Fota_Answer[3] = 0x02;
+                }
+                else
+                {
+                    Fota_Answer[3] = 0x01;
+                }
                 memcpy(&Fota_Answer[4],(DataPtr+4),BATT_SN_LEN);
                 Fota_Answer[21] = TCP_ENCPT_DISABLE;
                 Fota_Answer[22] = 0x00;
@@ -86,38 +163,13 @@ void Fota_Func(UINT8 *DataPtr,INT32 connectId,UINT8 FotaType)
                 memset(Fota_S.Fota_Recv_Data,0x00,100);
                 memcpy(Fota_S.Fota_Recv_Data,(DataPtr+42),*(DataPtr+41));
                 Fota_S.Fota_CRC = Fota_crc_chk(Fota_S.Fota_Recv_Data,Fota_S.Fota_Recv_Data_Len);
-                #ifdef USING_PRINTF1
-                    printf("\Data_Add:%x,Crc:%x,%x\n",Fota_S.Fota_Current_Addres,Fota_S.Fota_CRC,*(DataPtr+Fota_S.Fota_Recv_Data_Len+42));
-                    UINT8 temp[5] = {0x01,0x02,0x03,0x04,0x05};
-                    ret = BSP_QSPI_Write_Safe(temp,Fota_S.Fota_Flash_Addres+0xffe,5);
-                    UINT8 tPtr[1];
-                        printf("test:\n");
-                        for(UINT32 i = 0;i<5;i++)
-                        {
-                            BSP_QSPI_Read_Safe(tPtr,Fota_S.Fota_Flash_Addres+0xffe+i,1);
-                            printf("%x ",tPtr[0]);
-                        }
-                        printf("\ndata end\n");
-                #endif
                 if(Fota_S.Fota_CRC == *(DataPtr+Fota_S.Fota_Recv_Data_Len+42))
                 {
                     if(Fota_S.Fota_Recv_Data_Len%4!=0)
                     {
                     Fota_S.Fota_Recv_Data_Len = Fota_S.Fota_Recv_Data_Len + 4-(Fota_S.Fota_Recv_Data_Len%4);
                     }
-                    
-                    #ifdef USING_PRINTF1
-                        printf("\nlen:%x,%xFota_Data_Recv :",Fota_S.Fota_Recv_Data_Len,Fota_S.Fota_Current_Addres);
-                        for(UINT32 i = 0;i<Fota_S.Fota_Recv_Data_Len;i++)
-                        {
-                            printf("%x ",Fota_S.Fota_Recv_Data[i]);
-                        }
-                        printf("\ndata Recv end\n");
-                    #endif
                     ret = BSP_QSPI_Write_Safe(Fota_S.Fota_Recv_Data,Fota_S.Fota_Flash_Addres+Fota_S.Fota_Current_Addres,Fota_S.Fota_Recv_Data_Len);
-                    #ifdef USING_PRINTF1
-                        printf("\nret:%d\n",ret);
-                    #endif
                     if(ret==QSPI_OK)
                     {
                         Fota_Answer[3] = 0x01;
@@ -126,16 +178,6 @@ void Fota_Func(UINT8 *DataPtr,INT32 connectId,UINT8 FotaType)
                     {
                         Fota_Answer[3] = 0x02;
                     }
-                    #ifdef USING_PRINTF1
-                        UINT8 Ptr[1];
-                        printf("\nlen:%x,%xFota_Data :",Fota_S.Fota_Recv_Data_Len,Fota_S.Fota_Current_Addres);
-                        for(UINT32 i = 0;i<Fota_S.Fota_Recv_Data_Len;i++)
-                        {
-                            BSP_QSPI_Read_Safe(Ptr,Fota_S.Fota_Flash_Addres+Fota_S.Fota_Current_Addres+i,1);
-                            printf("%x ",Ptr[0]);
-                        }
-                        printf("\ndata end\n");
-                    #endif
                 }
                 else//数据校验失败
                 {
@@ -164,21 +206,11 @@ void Fota_Func(UINT8 *DataPtr,INT32 connectId,UINT8 FotaType)
                 tcpipConnectionSend(connectId,Fota_Answer,43,0,0,0);
                 if(Fota_S.Fota_All_Data_Len==Fota_S.Fota_Current_Addres)
                 {
-                    Fota_update_flag = TRUE;
-                    #ifdef USING_PRINTF1
-                        UINT8 *Ptr;
-                        printf("\nlen:%x,%xFota_Data :",Fota_S.Fota_All_Data_Len,Fota_S.Fota_Current_Addres);
-                        for(UINT32 i = 0;i<Fota_S.Fota_All_Data_Len;i++)
-                        {
-                            BSP_QSPI_Read_Safe(Ptr,Fota_Addres_Begin+i,1);
-                            printf("%x ",*(Ptr));
-                        }
-                        printf("\ndata end\n");
-                    #endif
+                    BMS_Fota_update_flag = TRUE;
                 }
                 else
                 {
-                    Fota_update_flag = FALSE;
+                    BMS_Fota_update_flag = FALSE;
                 }
                 break;
             }

+ 4 - 3
src/MainTask.c

@@ -32,7 +32,8 @@
 #include "Fota.h"
 #include "UartTask.h"
 extern UINT8 	UDSSwitch;
-extern volatile bool Fota_update_flag;
+extern volatile bool NB_Fota_update_flag;
+extern volatile bool BMS_Fota_update_flag;
 CHAR defaultBattSN[BATT_SN_LEN] = "GYTEST00000000003";//SN仍在测试
 //全局变量
 UINT32 Timer_count;//每100ms加1
@@ -158,7 +159,7 @@ static void MainTask(void* arg)
                     xTimerStop(montior_timer, 0);
                     PROC_MAIN_STATE_SWITCH(PROCESS_STATE_SLEEP);
                 }
-                if(TcpService!=0x00||UDSSwitch==1)
+                if(TcpService!=0x00||UDSSwitch==1||BMS_Fota_update_flag)
                 {
                     xTimerReset(work_timer,0);
                 }
@@ -177,7 +178,7 @@ static void MainTask(void* arg)
                     appSaveNVMData();
                 }
                 osDelay(5000);
-                if(Fota_update_flag)
+                if(NB_Fota_update_flag)
                 {
                     appSetCFUN(0);
                     osDelay(1000);

+ 2 - 2
src/TcpTask.c

@@ -461,11 +461,11 @@ static void TcpDataInfoRecvHandle()
                 TcpCmdAnswer[2] = TCP_CONCMD_SYM;
                 if(*(Ptr+30)==0x01)//远程升级命令
                 {
-                    Fota_Func(Ptr,socContext.id,0x01);
+                    Fota_Func(Ptr,socContext.id);
                 }
                 else if(*(Ptr+30)==0x88)//BMS远程升级数据传输命令
                 {
-                    Fota_Func(Ptr,socContext.id,0x88);
+                    Fota_Func(Ptr,socContext.id);
                 }
                 else if(*(Ptr+30)==0x80)//远程锁定命令
                 {

+ 789 - 3
src/UartTask.c

@@ -29,6 +29,7 @@
 #include "MainTask.h"
 #include "app.h"
 #include "numeric.h"
+#include "Fota.h"
 
 //全局变量输入区
 extern UINT32 Timer_count;
@@ -63,6 +64,10 @@ void battErrorStateDisplay(void);
 void battLockStateDisplay(UINT8 lockState);
 void SP_BMS_Update_Service(void);
 BOOL BattHeaterSwitch(UINT8* heaterSwitch);
+//BMS升级函数声明
+UINT8 SP_BMS_Update_CheckSUM(UINT8* pSendData,UINT8 len);
+void SP_BMS_Update_Service();
+UINT8 SP_BMS_Update_Query(UINT8* pSend,UINT32 sendLen, UINT8* pRead, UINT32 readLen, UINT32 timeout);
 
 //Uart线程任务区
 static void UartTask(void* arg)
@@ -133,7 +138,6 @@ static void UartTask(void* arg)
 				{
 					uartReadSuccessFlag = true;
 				}
-				
 				if(Timer_count-currentTimerCount >= 1)
 				{
 					if(AppNVMData.isBattLocked != 0)
@@ -147,6 +151,10 @@ static void UartTask(void* arg)
 					}
 				}
 				currentTimerCount = Timer_count;
+				if(BMS_Fota_update_flag)
+				{
+					PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_UPDATE);
+				}
                 break;
             }
             case PROCESS_UART_STATE_READ:
@@ -181,6 +189,11 @@ static void UartTask(void* arg)
                 PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
                 break;
             }
+			case PROCESS_UART_STATE_UPDATE:
+				SP_BMS_Update_Service();
+				PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE);
+				BMS_Fota_update_flag = FALSE;
+				break;
             case PROCESS_UART_STATE_SLEEP:
             {
                 USARTdrv->PowerControl(ARM_POWER_LOW);
@@ -812,13 +825,786 @@ UINT16  encryptionAlgorithm (UINT8 plainText)
 	}
 	return cipherText;
 }
+
+void SP_BMS_Update_Service() //超力源BMS升级服务
+{
+	
+	UINT8 errorCount = 0;
+	UINT8 resetCount = 0;	
+	UINT16 currentPackage = 0;	
+	UINT32 updateDataTotalByteLen = 0;
+	UpdateStep updateStep = UPDATE_STEP_CHECK_VERSION;	
+	
+	UINT8 i,j,ret=0;
+	UINT8 dataLen = 0;
+		
+	UINT8 pUpdateMsgSend[80];
+	UINT32 updateMsgSendLen = 0;	
+	UINT32 currentPackageStartAddr = 0;
+	BMS_Update_Recv_Msg_Type pUpdateMsgRecv;
+	UINT8 bmsUpdateFlag = 1;
+	//BMS_Update_Recv_Msg_Type bmsMsg;
+	//static UpdateStep step = UPDATE_STEP_CHECK_VERSION;
+	while(bmsUpdateFlag)
+	{
+		switch (updateStep)
+		{
+			case UPDATE_STEP_CHECK_VERSION:
+
+				dataLen = 0;
+				updateMsgSendLen = 7;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x01; //read
+				pUpdateMsgSend[3] = 0x03;	//data len
+				pUpdateMsgSend[4] = 0x90;	//cmd
+				pUpdateMsgSend[5] = 0x93;	//checksum
+				pUpdateMsgSend[6] = 0xF5;	//end flag		
+				//printf("updateMsgSendLen0 = %x\n",updateMsgSendLen);
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv),sizeof(BMS_Update_Recv_Msg_Type), 500);
+				//printf("updateMsgSendLen1 = %x\n",updateMsgSendLen);
+				if(ret!=0)
+				{
+					if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
+					{
+						if(pUpdateMsgRecv.cmd == 0x90)
+						{
+							if(pUpdateMsgRecv.data != 0xFF)
+							{
+								updateStep = UPDATE_STEP_REQUEST_UPDATE;
+								errorCount = 0;
+							}
+							else
+							{
+								updateStep = UPDATE_STEP_SET_BAUD_RATE;
+								errorCount = 0;
+							}
+						}
+						else
+						{
+							errorCount++;
+						}
+					}
+					else
+					{
+						errorCount++;
+					}
+				}			
+				else
+				{
+					errorCount++;
+				}
+				#ifdef USING_PRINTF
+							//printf("update step:%d\n",updateStep);
+							printf("query:");
+							
+							for(j=0;j<updateMsgSendLen;j++)
+							{
+								printf("%x ",pUpdateMsgSend[j]);
+							}
+							
+							printf("\nanswer:");
+							for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+							{
+								printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+							}
+							printf("\n");
+							printf("next update step:%d\n",updateStep);
+				#endif
+				if(errorCount>10)
+				{
+					updateStep = UPDATE_STEP_ERROR;
+					errorCount = 0;
+				}
+				osDelay(50);
+				break;
+			
+			case UPDATE_STEP_REQUEST_UPDATE:
+				dataLen = 1;
+				updateMsgSendLen = 8;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x04;	//data len
+				pUpdateMsgSend[4] = 0x80;	//cmd
+				pUpdateMsgSend[5] = 0x22;	//data
+				pUpdateMsgSend[6] = 0xA6;	//check
+				pUpdateMsgSend[7] = 0xF5;	//end flag
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
+				if(ret!=0)
+				{
+					if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
+					{
+						if(pUpdateMsgRecv.cmd == 0x80)
+						{
+							if(pUpdateMsgRecv.data == 0x33)
+							{
+								updateStep = UPDATE_STEP_START_UPDATE;
+								errorCount = 0;
+							}
+							else
+							{
+								errorCount++;
+							}						
+						}
+						else
+						{
+							errorCount++;
+						}
+					}
+					else
+					{
+						errorCount++;
+					}
+				}			
+				else
+				{
+					errorCount++;
+				}
+
+				if(errorCount>10)
+				{
+					updateStep = UPDATE_STEP_ERROR;
+					errorCount = 0;
+				}
+				
+				#ifdef USING_PRINTF
+							printf("update step:%d\n",updateStep);
+							printf("query:");
+							for(j=0;j<updateMsgSendLen;j++)
+							{
+								printf("%x ",pUpdateMsgSend[j]);
+							}
+							printf("\nanswer:");
+							for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+							{
+								printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+							}
+							printf("\n");
+							printf("next update step:%d\n",updateStep);
+				#endif
+				osDelay(50);
+				break;
+
+			case UPDATE_STEP_START_UPDATE:
+				dataLen = 1;
+				updateMsgSendLen = 8;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x04;	//data len
+				pUpdateMsgSend[4] = 0x80;	//cmd
+				pUpdateMsgSend[5] = 0x55;	//data
+				pUpdateMsgSend[6] = 0xD9;	//check
+				pUpdateMsgSend[7] = 0xF5;	//end flag
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), 0, 500);
+				//updateStep = UPDATE_STEP_SET_BAUD_RATE;
+				updateStep = UPDATE_STEP_SET_BAUD_RATE;
+				#ifdef USING_PRINTF
+							
+							printf("query:");
+							for(j=0;j<updateMsgSendLen;j++)
+							{
+								printf("%x ",pUpdateMsgSend[j]);
+							}
+							printf("\nanswer:");
+							for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+							{
+								printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+							}
+							
+							printf("\n");		
+							printf("next update step:%d\n",updateStep);
+				#endif
+				osDelay(50);
+				break;
+			case UPDATE_STEP_SET_BAUD_RATE:
+				printf("start step %d\n",updateStep);
+				dataLen = 4;
+				updateMsgSendLen = 12;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x08;	//data len
+				pUpdateMsgSend[4] = 0x81;	//cmd
+				pUpdateMsgSend[5] = 0x33;	//data
+				pUpdateMsgSend[6] = 0x00;	//baud rate:9600
+				pUpdateMsgSend[7] = 0x00;
+				pUpdateMsgSend[8] = 0x25;
+				pUpdateMsgSend[9] = 0x80;
+				pUpdateMsgSend[10] = 0x61;	//check
+				pUpdateMsgSend[11] = 0xF5;	//end flag
+				
+				printf("query:");
+				for(j=0;j<updateMsgSendLen;j++)
+				{
+					printf("%x ",pUpdateMsgSend[j]);
+				}
+				printf("\n");
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
+				printf("ret = %d\n",ret);
+				if(ret!=0)
+				{
+					if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
+					{
+						if(pUpdateMsgRecv.cmd == 0x81)
+						{
+							if(pUpdateMsgRecv.data == 0x11)
+							{
+								updateStep = UPDATE_STEP_PREPARE_SEND_DATA_LEN;
+								errorCount = 0;
+							}
+							else
+							{
+								errorCount++;
+							}						
+						}
+						else
+						{
+							errorCount++;
+						}
+					}
+					else
+					{
+						errorCount++;
+					}
+				}			
+				else
+				{
+					errorCount++;
+				}
+
+				if(errorCount>10)
+				{
+					updateStep = UPDATE_STEP_ERROR;
+					errorCount = 0;
+				}
+				
+				#ifdef USING_PRINTF
+					//printf("update step:%d\n",updateStep);
+					printf("query:");
+					for(j=0;j<updateMsgSendLen;j++)
+					{
+						printf("%x ",pUpdateMsgSend[j]);
+					}
+					printf("\nanswer:");
+					for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+					{
+						printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+					}
+					printf("\n");
+					printf("next update step:%d\n",updateStep);
+				#endif
+				osDelay(50);
+				break;
+			
+			
+			case UPDATE_STEP_PREPARE_SEND_DATA_LEN:
+				printf("start step %d\n",updateStep);
+				dataLen = 1;
+				updateMsgSendLen = 8;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x04;	//data len
+				pUpdateMsgSend[4] = 0x81;	//cmd
+				pUpdateMsgSend[5] = 0x44;	//data
+				pUpdateMsgSend[6] = 0xC9;	//check
+				pUpdateMsgSend[7] = 0xF5;	//end flag
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
+				if(ret!=0)
+				{
+					if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
+					{
+						if(pUpdateMsgRecv.cmd == 0x81)
+						{
+							if(pUpdateMsgRecv.data == 0x11)
+							{
+								updateStep = UPDATE_STEP_SEND_DATA_LEN;
+								errorCount = 0;
+							}
+							else
+							{
+								errorCount++;
+							}						
+						}
+						else
+						{
+							errorCount++;
+						}
+					}
+					else
+					{
+						errorCount++;
+					}
+				}			
+				else
+				{
+					errorCount++;
+				}
+
+				if(errorCount>10)
+				{
+					updateStep = UPDATE_STEP_ERROR;
+					errorCount = 0;
+				}
+				
+				#ifdef USING_PRINTF
+					//printf("update step:%d\n",updateStep);
+					printf("query:");
+					for(j=0;j<updateMsgSendLen;j++)
+					{
+						printf("%x ",pUpdateMsgSend[j]);
+					}
+					printf("\nanswer:");
+					for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+					{
+						printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+					}
+					printf("\n");	
+					printf("next update step:%d\n",updateStep);
+				#endif
+				osDelay(50);
+				break;		
+			case UPDATE_STEP_SEND_DATA_LEN:
+				
+				dataLen = 4;
+				BSP_QSPI_Read_Safe(&updateDataTotalByteLen,FLASH_BMS_FOTA_START_ADDR,4);
+				updateDataTotalByteLen = (((updateDataTotalByteLen)&0xFF)<<24)|(((updateDataTotalByteLen>>8)&0xFF)<<16)|(((updateDataTotalByteLen>>16)&0xFF)<<8)|(((updateDataTotalByteLen>>24)&0xFF));
+				updateMsgSendLen = 11;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x07;	//data len
+				pUpdateMsgSend[4] = 0x82;	//cmd
+				pUpdateMsgSend[5] = (updateDataTotalByteLen>>24)&0xFF;	//data: package byte len
+				pUpdateMsgSend[6] = (updateDataTotalByteLen>>16)&0xFF;	
+				pUpdateMsgSend[7] = (updateDataTotalByteLen>>8)&0xFF;	
+				pUpdateMsgSend[8] = (updateDataTotalByteLen)&0xFF;
+				pUpdateMsgSend[9] = SP_BMS_Update_CheckSUM(&pUpdateMsgSend[3], dataLen+2);	//check sum
+				pUpdateMsgSend[10] = 0xF5;	//end flag
+				
+				memset((UINT8*)(&pUpdateMsgRecv),0,sizeof(BMS_Update_Recv_Msg_Type));
+				ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
+				if(ret!=0)
+				{
+					if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
+					{
+						if(pUpdateMsgRecv.cmd == 0x81)
+						{
+							if(pUpdateMsgRecv.data == 0x11)
+							{
+								updateStep = UPDATE_STEP_PREPARE_SEND_UPDATE_DATA;
+								errorCount = 0;
+							}
+							else
+							{
+								errorCount++;
+							}						
+						}
+						else
+						{
+							errorCount++;
+						}
+					}
+					else
+					{
+						errorCount++;
+					}
+				}			
+				else
+				{
+					errorCount++;
+				}
+
+				if(errorCount>10)
+				{
+					updateStep = UPDATE_STEP_ERROR;
+					errorCount = 0;
+				}
+				
+				#ifdef USING_PRINTF
+							//printf("update step:%d\n",updateStep);
+							printf("query:");
+							for(j=0;j<updateMsgSendLen;j++)
+							{
+								printf("%x ",pUpdateMsgSend[j]);
+							}
+							printf("\nanswer:");
+							for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+							{
+								printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+							}
+							printf("\n");
+							printf("next update step:%d\n",updateStep);
+				#endif
+				osDelay(50);
+				break;	
+				
+			case UPDATE_STEP_PREPARE_SEND_UPDATE_DATA:
+				dataLen = 1;
+				updateMsgSendLen = 8;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x04;	//data len
+				pUpdateMsgSend[4] = 0x81;	//cmd
+				pUpdateMsgSend[5] = 0x55;	//data
+				pUpdateMsgSend[6] = 0xDA;	//check
+				pUpdateMsgSend[7] = 0xF5;	//end flag
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen,(UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
+				if(ret!=0)
+				{
+					if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
+					{
+						if(pUpdateMsgRecv.cmd == 0x81)
+						{
+							if(pUpdateMsgRecv.data == 0x11)
+							{
+								updateStep = UPDATE_STEP_SEND_UPDATE_DATA;
+								errorCount = 0;
+							}
+							else
+							{
+								errorCount++;
+							}						
+						}
+						else
+						{
+							errorCount++;
+						}
+					}
+					else
+					{
+						errorCount++;
+					}
+				}			
+				else
+				{
+					errorCount++;
+				}
+
+				if(errorCount>10)
+				{
+					updateStep = UPDATE_STEP_ERROR;
+					errorCount = 0;
+				}
+				
+				#ifdef USING_PRINTF
+					//printf("update step:%d\n",updateStep);
+					printf("query:");
+					for(j=0;j<updateMsgSendLen;j++)
+					{
+						printf("%x ",pUpdateMsgSend[j]);
+					}
+					printf("\nanswer:");
+					for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+					{
+						printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+					}
+					printf("\n");	
+					printf("next update step:%d\n",updateStep);
+				#endif
+				osDelay(50);
+				break;
+			case UPDATE_STEP_SEND_UPDATE_DATA:
+				dataLen = 64;
+				updateMsgSendLen = 75;
+							
+				for(currentPackage=0;currentPackage<updateDataTotalByteLen/64;currentPackage++)
+				{
+					currentPackageStartAddr = currentPackage*64;
+				
+					pUpdateMsgSend[0] = 0xEB; //start flag
+					pUpdateMsgSend[1] = 0x01;	//add flag
+					pUpdateMsgSend[2] = 0x00; //write
+					pUpdateMsgSend[3] = 0x47;	//data len			
+					pUpdateMsgSend[4] = 0x82;	//cmd
+					pUpdateMsgSend[5] = (currentPackageStartAddr>>24)&0xFF;
+					pUpdateMsgSend[6] = (currentPackageStartAddr>>16)&0xFF;
+					pUpdateMsgSend[7] = (currentPackageStartAddr>>8)&0xFF;
+					pUpdateMsgSend[8] = currentPackageStartAddr&0xFF;
+					BSP_QSPI_Read_Safe(&pUpdateMsgSend[9], FLASH_BMS_FOTA_START_ADDR+4+currentPackage*dataLen, dataLen);  //data			
+					pUpdateMsgSend[8+dataLen+1] = SP_BMS_Update_CheckSUM(&pUpdateMsgSend[3], dataLen+6);  //check sum
+					pUpdateMsgSend[8+dataLen+2] = 0xF5;	//end flag
+					memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+					ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
+					if(ret!=0)
+					{
+						if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
+						{
+							if(pUpdateMsgRecv.cmd == 0x81)
+							{
+								if(pUpdateMsgRecv.data == 0x11)
+								{
+									if(currentPackage+1 == updateDataTotalByteLen/64)
+									{
+										updateStep = UPDATE_STEP_SEND_DATA_END;
+									}
+									errorCount = 0;
+								}
+								else
+								{
+									errorCount++;
+								}						
+							}
+							else
+							{
+								errorCount++;
+							}
+						}
+						else
+						{
+							errorCount++;
+						}
+					}			
+					else
+					{
+						errorCount++;
+					}
+
+					if(errorCount>10)
+					{					
+						updateStep = UPDATE_STEP_RESET;
+						errorCount = 0;
+						break;
+					}
+				#ifdef USING_PRINTF
+							//printf("update step:%d\n",updateStep);
+							printf("query:");
+							for(j=0;j<updateMsgSendLen;j++)
+							{
+								printf("%x ",pUpdateMsgSend[j]);
+							}
+							printf("\nanswer:");
+							for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+							{
+								printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+							}
+							printf("\n");
+							printf("next update step:%d\n",updateStep);
+				#endif
+				}
+				osDelay(50);
+				break;
+
+			case UPDATE_STEP_SEND_DATA_END:
+				dataLen = 1;
+				updateMsgSendLen = 8;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x04;	//data len
+				pUpdateMsgSend[4] = 0x81;	//cmd
+				pUpdateMsgSend[5] = 0x66;	//data
+				pUpdateMsgSend[6] = 0xEB;	//check
+				pUpdateMsgSend[7] = 0xF5;	//end flag
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				ret = SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), sizeof(BMS_Update_Recv_Msg_Type), 500);
+				if(ret!=0)
+				{
+					if(pUpdateMsgRecv.startFlag == 0xEB && pUpdateMsgRecv.endFlag == 0xF5)
+					{
+						if(pUpdateMsgRecv.cmd == 0x81)
+						{
+							if(pUpdateMsgRecv.data == 0x11)
+							{
+								updateStep = UPDATE_STEP_START_INSTALL;
+								errorCount = 0;
+							}
+							else
+							{
+								errorCount++;
+							}						
+						}
+						else
+						{
+							errorCount++;
+						}
+					}
+					else
+					{
+						errorCount++;
+					}
+				}			
+				else
+				{
+					errorCount++;
+				}
+
+				if(errorCount>10)
+				{
+					updateStep = UPDATE_STEP_ERROR;
+					errorCount = 0;
+				}
+				
+				#ifdef USING_PRINTF
+							//printf("update step:%d\n",updateStep);
+							printf("query:");
+							for(j=0;j<updateMsgSendLen;j++)
+							{
+								printf("%x ",pUpdateMsgSend[j]);
+							}
+							printf("\nanswer:");
+							for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+							{
+								printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+							}
+							printf("\n");
+							printf("next update step:%d\n",updateStep);
+				#endif
+				osDelay(50);
+				break;			
+
+			case UPDATE_STEP_START_INSTALL:
+				dataLen = 1;
+				updateMsgSendLen = 8;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x04;	//data len
+				pUpdateMsgSend[4] = 0x81;	//cmd
+				pUpdateMsgSend[5] = 0x99;	//data
+				pUpdateMsgSend[6] = 0x1E;	//check
+				pUpdateMsgSend[7] = 0xF5;	//end flag
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), 0, 500);
+				
+				updateStep = UPDATE_STEP_END;
+				
+				#ifdef USING_PRINTF
+							//printf("update step:%d\n",updateStep);
+							printf("query:");
+							for(j=0;j<updateMsgSendLen;j++)
+							{
+								printf("%x ",pUpdateMsgSend[j]);
+							}
+							printf("\nanswer:");
+							for(j=0;j<sizeof(BMS_Update_Recv_Msg_Type);j++)
+							{
+								printf("%x ",*(((UINT8*)&pUpdateMsgRecv)+j));
+							}
+							printf("\n");	
+							printf("next update step:%d\n",updateStep);
+				#endif
+				osDelay(50);
+				break;
+			case UPDATE_STEP_END:
+				updateStep = UPDATE_STEP_CHECK_VERSION;
+				printf("update end\n");
+				bmsUpdateFlag = 0;
+				break;
+			case UPDATE_STEP_RESET:
+				dataLen = 1;
+				updateMsgSendLen = 8;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x04;	//data len
+				pUpdateMsgSend[4] = 0x81;	//cmd
+				pUpdateMsgSend[5] = 0xAA;	//data
+				pUpdateMsgSend[6] = 0x2F;	//check
+				pUpdateMsgSend[7] = 0xF5;	//end flag
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), 0, 500);
+				osDelay(50);
+				
+				resetCount++;
+				if(resetCount>=2)
+				{
+					updateStep = UPDATE_STEP_DOWNLOAD_BREAK_OFF;
+					resetCount = 0;
+				}
+				else
+				{
+					updateStep = UPDATE_STEP_PREPARE_SEND_DATA_LEN;
+				}
+			#ifdef USING_PRINTF
+				printf("update error!!\n rest and start send data lenth again!!\n continue update!\n");
+			#endif
+				break;
+			case UPDATE_STEP_DOWNLOAD_BREAK_OFF:
+				dataLen = 1;
+				updateMsgSendLen = 8;
+				pUpdateMsgSend[0] = 0xEB; //start flag
+				pUpdateMsgSend[1] = 0x01;	//add flag
+				pUpdateMsgSend[2] = 0x00; //write
+				pUpdateMsgSend[3] = 0x04;	//data len
+				pUpdateMsgSend[4] = 0x81;	//cmd
+				pUpdateMsgSend[5] = 0xBB;	//data
+				pUpdateMsgSend[6] = 0x40;	//check
+				pUpdateMsgSend[7] = 0xF5;	//end flag
+				memset((UINT8*)(&pUpdateMsgRecv) , 0, sizeof(BMS_Update_Recv_Msg_Type));
+				SP_BMS_Update_Query(pUpdateMsgSend, updateMsgSendLen, (UINT8*)(&pUpdateMsgRecv), 0, 500);
+				osDelay(50);
+				updateStep = UPDATE_STEP_ERROR;
+				break;
+			case UPDATE_STEP_ERROR:
+				updateStep = UPDATE_STEP_CHECK_VERSION;
+				printf("update error end\n");
+				bmsUpdateFlag = 0;
+			break;
+
+			default:
+				updateStep = UPDATE_STEP_CHECK_VERSION;
+				printf("update default end\n");
+				bmsUpdateFlag = 0;
+			break;
+		}
+	}
+}
+
+UINT8 SP_BMS_Update_Query(UINT8* pSend,UINT32 sendLen, UINT8* pRead, UINT32 readLen, UINT32 timeout)
+{
+	UINT8 timeCount = 0;
+	UINT8 j=0;
+	USARTdrv->Send(pSend,sendLen);
+	if(readLen>0)
+	{
+		USARTdrv->Receive(pRead,readLen);         
+		while((isRecvTimeout == false) && (isRecvComplete == false))
+		{
+			timeCount++;
+			osDelay(100);
+			if (timeCount>=timeout/100)
+			{
+				timeCount =0;
+				isRecvTimeout = true;
+				break;
+			}
+		}	
+		if (isRecvComplete == true)
+		{
+			isRecvComplete = false;
+			return readLen;
+		}
+		else
+		{
+			memset(pRead,0x00,readLen);
+			isRecvTimeout = false;
+			return 0;
+		}
+	}
+	else
+	{
+			return 1;
+	}
+}
+
+
 UINT8 SP_BMS_Update_CheckSUM(UINT8* pSendData,UINT8 len)
 {
 	UINT8 ret = 0;
 	UINT8 i=0;
 	for(i=0;i<len;i++)
 	{
-		ret +=*(pSendData+i);
+			ret +=*(pSendData+i);
 	}
 	return ret&0xFF;
-}
+}