/**************************************************************************** * * Copy right: Qx. * File name: UartTask.c * Description: 串口任务 * History: 2021-03-05 * * 2021-04-11:可以通过Ota线路升级Bms保护板 ****************************************************************************/ #include "bsp.h" #include "bsp_custom.h" #include "osasys.h" #include "ostask.h" #include "queue.h" #include "ps_event_callback.h" #include "cmisim.h" #include "cmimm.h" #include "cmips.h" #include "sockets.h" #include "psifevent.h" #include "ps_lib_api.h" #include "lwip/netdb.h" //#include #include "debug_log.h" #include "slpman_ec616.h" #include "plat_config.h" #include "ec_tcpip_api.h" #include "hal_module_adapter.h" #include "UartTask.h" #include "MainTask.h" #include #include "app.h" #include "numeric.h" #include "Fota.h" #include "signal.h" //全局变量输入区 extern UINT32 Timer_count; extern volatile BOOL Sleep_flag; extern AppNVMDataType AppNVMData; extern AppDataBody AppDataInfo; //全局变量输出区 BOOL UartBattInfoRecvFlag = false; QueueHandle_t UartWriteCmdHandle = NULL; UINT8 BattChrgEndFlag; // extern ARM_DRIVER_USART Driver_USART1; static ARM_DRIVER_USART *USARTdrv = &Driver_USART1; volatile bool isRecvTimeout = false; volatile bool isRecvComplete = false; //线程声明区 static StaticTask_t gProcess_Uart_Task_t; static UINT8 gProcess_Uart_TaskStack[PROC_UART_TASK_STACK_SIZE]; static osThreadId_t UartTaskId = NULL; static process_Uart gProcess_Uart_Task = PROCESS_UART_STATE_IDLE; #define PROC_UART_STATE_SWITCH(a) (gProcess_Uart_Task = a) //函数声明区 void USART_callback(uint32_t event); UINT8 Uart_DataRecv_func(UINT8* Uart_Read_Msg,UINT8* Uart_Recv_Buffer); static BOOL uartBattInfoDecode(UINT8* dataPtr); UINT8 Uart_WriteCmd_func(Uart_Write_Data_Type UartWriteData); UINT16 crc_chk(UINT8* data, UINT8 length); void battSOCDisplay(void); void battErrorStateDisplay(void); void battWarningStateDisplay(void); void battLockStateDisplay(UINT8 lockState); void relayPWMControl(void); void SP_BMS_Update_Service(void); BOOL BattHeaterSwitch(UINT8* heaterSwitch); UINT16 encryptionAlgorithm (UINT16 plainText); UINT8 decryptionAlgorithm (UINT16 cipherText); UINT8 Uart_Encrypt_Send(void); //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) { USARTdrv->Initialize(USART_callback); USARTdrv->PowerControl(ARM_POWER_FULL); USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS | ARM_USART_DATA_BITS_8 | ARM_USART_PARITY_NONE | ARM_USART_STOP_BITS_1 | ARM_USART_FLOW_CONTROL_NONE, 9600); PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_ENCRYPT); UINT16 Reg_Num = 0; UINT16 Uart_Uds_LEN; UINT16 Uart_Recv_LEN; UINT32 currentTimerCount=0; BOOL uartReadSuccessFlag = false; Uart_Read_Msg_Type Uart_Read_Msg; Uart_Write_Data_Type UartWriteData; //Uart控制命令 UartReadMsgType UartReadMsg; memset(&(UartReadMsg.UartFlag),0x00,sizeof(UartReadMsgType)); if(UartWriteCmdHandle == NULL)//Uart控制命令传输指针 { UartWriteCmdHandle = osMessageQueueNew(3,sizeof(Uart_Write_Data_Type), NULL); } //上电起始控制区域 while (1) { switch (gProcess_Uart_Task) { case PROCESS_UART_STATE_ENCRYPT: { UINT8 EncryptFlag=0x00; UINT8 EncryptCount=0; while(EncryptFlag!=0x01&&EncryptCount<=3) { EncryptFlag = Uart_Encrypt_Send(); EncryptCount++; } PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE); break; } case PROCESS_UART_STATE_IDLE: { osDelay(100); if(Sleep_flag) { PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_SLEEP); } else if(Timer_count%10==0) { #ifdef USING_PRINTF printf("[%d]Uart Timer 5s:%d,Header:%x\n",__LINE__,Timer_count,UartReadMsg.Header[2]); #endif if(osMessageQueueGet(UartWriteCmdHandle,&UartWriteData,0,0)==osOK) { #ifdef USING_PRINTF printf("[%d]UartWriteCmdHandle :%x\n",__LINE__,UartWriteData.WriteCmd); #endif PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_WRITE); } else PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ); } if(UartReadMsg.Header[2]>0) { uartReadSuccessFlag = true; } else { uartReadSuccessFlag = false; } if(Timer_count-currentTimerCount >= 1) { if(AppNVMData.isBattLocked != 0) { battLockStateDisplay(TRUE); } if(uartReadSuccessFlag) { battSOCDisplay(); battErrorStateDisplay(); } // else // { // #ifdef USING_PRINTF // printf("battWarningStateDisplay\n"); // #endif // battWarningStateDisplay(); // } } currentTimerCount = Timer_count; if(BMS_Fota_update_flag) { PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_UPDATE); } if(AppNVMData.isBattLocked==TRUE && ((UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2+1])>>1)&0x03!=0x00) { UartWriteData.WriteCmd = 0x01; UartWriteData.Data[0] = 0x00; UartWriteData.Data[1] = 0x00; osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,1000); PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ); } else if (AppNVMData.isBattLocked==FALSE && ((UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2+1])>>1)&0x03==0x00) { UartWriteData.WriteCmd = 0x01; UartWriteData.Data[0] = 0x00; UartWriteData.Data[1] = 0x03; osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,1000); PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_READ); } break; } case PROCESS_UART_STATE_READ: { Reg_Num = 0x21+BATT_CELL_VOL_NUM+BATT_TEMP_NUM + 2;//按照协议里面的0x21+X+N的结束地址 Uart_Read_Msg.Bms_Address = BMS_ADDRESS_CODE; Uart_Read_Msg.Bms_Funcode = UART_READ_CODE; Uart_Read_Msg.Reg_Begin_H = 0x00; Uart_Read_Msg.Reg_Begin_L= 0x00; Uart_Read_Msg.Reg_Num_H = Reg_Num>>8; Uart_Read_Msg.Reg_Num_L = Reg_Num; Uart_Uds_LEN = Reg_Num*2; memset(UartReadMsg.Header,0x00,Uart_Uds_LEN); Uart_Recv_LEN = Uart_DataRecv_func((UINT8 *)&Uart_Read_Msg,UartReadMsg.Header); //osMutexRelease(UartMutex); if(Uart_Recv_LEN>0) { UartBattInfoRecvFlag = TRUE; uartBattInfoDecode(UartReadMsg.data); } else { UartBattInfoRecvFlag = FALSE; } UartReadMsg.len = Uart_Recv_LEN; PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE); if( battWorkState ==0x02) { BattChrgEndFlag=TRUE; } else { BattChrgEndFlag=FALSE; } #ifdef USING_PRINTF1 printf("\nUart_Recv_buffer: "); for(int i=0;iPowerControl(ARM_POWER_LOW); while(TRUE) { osDelay(60000/portTICK_PERIOD_MS); } osThreadExit(); break; } } } } //Uart 接收的数据解码 static BOOL uartBattInfoDecode(UINT8* dataPtr) { //BattInfoType battInfo; UINT8 i,temp=0; UINT8 TEMP_NUM = BATT_TEMP_NUM + BATT_OTHER_TEMP_NUM; UINT16 Batt_current; for(i=0;i0x8000) { AppDataInfo.BattCurrentNegFlag = 1; } if(battWorkState==0x02&&Batt_current<0x8000) { AppDataInfo.BattCurrentNegFlag = -1; } if (Batt_current>0x8000) //为负,充电数据 { Batt_current = (UINT16)((UINT16)(~(Batt_current))+1); Batt_current = Batt_current/10; Batt_current = -Batt_current*AppDataInfo.BattCurrentNegFlag + 0x2710;//平台数据:充电为负 //Batt_current = Batt_current; } else //为正,数据 { Batt_current = Batt_current/10; Batt_current = Batt_current*AppDataInfo.BattCurrentNegFlag + 0x2710;//平台数据:充电为负 //Batt_current = Batt_current; } battI = Batt_current; #ifdef USING_PRINTF printf("battI = %x\n",battI); #endif //bit0 ~ bit31 represent cell0 ~ cell31 battBalanceoInfo = dataPtr[(0x06+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1] | (dataPtr[(0x06+BATT_CELL_VOL_NUM+TEMP_NUM)*2] <<8) + (dataPtr[(0x07+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]<<16) | (dataPtr[(0x07+BATT_CELL_VOL_NUM+TEMP_NUM)*2] <<24); bmsHwVersion = dataPtr[(0x08+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]; bmsSwVersion = dataPtr[(0x08+BATT_CELL_VOL_NUM+TEMP_NUM)*2]; temp = ((dataPtr[(0x09+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1])>>1)&0x03; battMOSSwitchState = ((temp&0x01)<<1)|((temp&0x02)>>1); if(AppNVMData.isBattLocked==TRUE) { battMOSSwitchState = battMOSSwitchState |(0x01<<2); } else { battMOSSwitchState = battMOSSwitchState |(0x00<<2); } battWarningState = (dataPtr[(0x09+BATT_CELL_VOL_NUM+TEMP_NUM)*2+0]<<16) | (dataPtr[(0x0A+BATT_CELL_VOL_NUM+TEMP_NUM)*2+0] << 8) |(dataPtr[(0x0A+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]); battSOC = dataPtr[(0x0B+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]; battSOH = dataPtr[(0x0C+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]; battPackVol =((dataPtr[(0x18+BATT_CELL_VOL_NUM+TEMP_NUM)*2])<<8|(dataPtr[(0x18+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]))/10; //uint 100mV maxCellVol = (dataPtr[(0x19+BATT_CELL_VOL_NUM+TEMP_NUM)*2] << 8) | dataPtr[(0x19+BATT_CELL_VOL_NUM+TEMP_NUM)*2 + 1]; minCellVol = (dataPtr[(0x1A+BATT_CELL_VOL_NUM+TEMP_NUM)*2] << 8) | dataPtr[(0x1A+BATT_CELL_VOL_NUM+TEMP_NUM)*2 + 1]; battHeatEnableState = dataPtr[(0x1C+BATT_CELL_VOL_NUM+TEMP_NUM)*2+1]&0x01; maxCellTemp = 0x00; minCellTemp = 0xFF; for(i=0;i>1) ^ 0xA001; } else { reg_crc=reg_crc >>1; } } } return reg_crc; } //Uart写命令函数 UINT8 Uart_WriteCmd_func(Uart_Write_Data_Type UartWriteData) { Uart_Write_Msg_Type Uart_Write_Msg; UINT16 RegAddress = 0x0000; UINT16 CRC_chk_buffer; UINT8 timeout = 0x00; UINT8 Uart_Recv_Buffer[8]; switch (UartWriteData.WriteCmd) { case 0x01: { RegAddress = 0x1B + BATT_CELL_VOL_NUM+BATT_TEMP_NUM+BATT_OTHER_TEMP_NUM; Uart_Write_Msg.Bms_Address = BMS_ADDRESS_CODE; Uart_Write_Msg.Bms_Funcode = UART_WRITE_CODE; Uart_Write_Msg.Reg_Begin_H = RegAddress>>8; Uart_Write_Msg.Reg_Begin_L = RegAddress; Uart_Write_Msg.Reg_Num_H = 0x00; Uart_Write_Msg.Reg_Num_L = 0x01; Uart_Write_Msg.Data_Count = 0x02;//要写入的字节数 memcpy(Uart_Write_Msg.Data,UartWriteData.Data,2); CRC_chk_buffer = crc_chk((UINT8 *)&Uart_Write_Msg,sizeof(Uart_Write_Msg)-2); Uart_Write_Msg.CRC_L = CRC_chk_buffer; Uart_Write_Msg.CRC_H = CRC_chk_buffer>>8; break; } default: { UartWriteData.WriteCmd = 0x00; return 0; break; } } USARTdrv->Send((UINT8 *)&Uart_Write_Msg,sizeof(Uart_Write_Msg)); #ifdef USING_PRINTF printf("Uart_Send_buffer: "); for(int i=0;iReceive(Uart_Recv_Buffer,8); while((isRecvTimeout == false) && (isRecvComplete == false)) { timeout++; osDelay(100); if (timeout>=10) { timeout =0; isRecvTimeout = true; break; } } if (isRecvComplete == true) { #ifdef USING_PRINTF printf("Uart_Rece_buffer: "); for(int i=0;i<8;i++) { printf("%x ",Uart_Recv_Buffer[i]); } printf("\n"); #endif isRecvComplete = false; if(Uart_Recv_Buffer[1]==0x10) { return UartWriteData.WriteCmd; } else { return 0x00; } } else { isRecvTimeout = false; return 0x00; } } //Uart发送接收函数 UINT8 Uart_DataRecv_func(UINT8* Uart_Read_Msg,UINT8* Uart_Recv_Buffer) { UINT16 CRC_Rece_buffer; UINT16 CRC_chk_buffer; UINT16 Data_Len ; UINT8 timeout = 0x00; Data_Len = (*(Uart_Read_Msg+4)|*(Uart_Read_Msg+5))*2+5; CRC_chk_buffer = crc_chk(Uart_Read_Msg,6); *(Uart_Read_Msg+6) = CRC_chk_buffer; *(Uart_Read_Msg+7) = CRC_chk_buffer>>8; USARTdrv->Send(Uart_Read_Msg,8); #ifdef USING_PRINTF printf("Uart_Send_buffer: "); for(int i=0;i<8;i++) { printf("%x ",*(Uart_Read_Msg+i)); } printf("\n"); #endif USARTdrv->Receive(Uart_Recv_Buffer,Data_Len); while(true) { timeout++; if((isRecvTimeout == true) || (isRecvComplete == true)) { break; } else { osDelay(100); if (timeout>=50) { timeout =0; isRecvTimeout = true; } } } #ifdef USING_PRINTF1 printf("Uart_Rece_buffer1: "); for(int i=0;iUninitialize(); osDelay(1000); USARTdrv->Initialize(USART_callback); USARTdrv->PowerControl(ARM_POWER_FULL); USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS | ARM_USART_DATA_BITS_8 | ARM_USART_PARITY_NONE | ARM_USART_STOP_BITS_1 | ARM_USART_FLOW_CONTROL_NONE, 9600); memset(Uart_Recv_Buffer,0xff,Data_Len); return 0; } } else { memset(Uart_Recv_Buffer,0x00,Data_Len); isRecvTimeout = false; return 0; } } /** \fn BOOL BattHeaterSwitch(UINT8* heaterSwitch) \param[in] (UINT8*) heaterSwitch: the heater switch state \brief according to the current switch state and all the cell temp, it will turn on/off the switch \return (BOOL) isNeedtoSwitch: true: need to send cmd to turn on/off the switch false: do not need to do anything */ BOOL BattHeaterSwitch(UINT8* heaterSwitch) { BOOL isNeedtoSwitch = FALSE; UINT8 i =0; UINT8 currentSwitchState = 0; //get the current switch state and the cell temp currentSwitchState = battMOSSwitchState & 0x01; if(currentSwitchState==0) //当前状态为关闭,判断是否应该开启 { if(minCellTemp<=5+40 && maxCellTemp<25+40 && battSOC>=12)//温度偏移为40 { *heaterSwitch = 1; isNeedtoSwitch = true; } } else //当前状态为开启,判断是否应该关闭 { if(minCellTemp>10+40 || maxCellTemp>30+40 || battSOC<10) { *heaterSwitch = 0; isNeedtoSwitch= true; } } return isNeedtoSwitch; } void battSOCDisplay() { static UINT8 lightTimer = 0; UINT8 socLowLEDFlashPeriod = 10;//10*100 = 1000ms UINT8 chargeLEDFlashPeriod = 6;//6*100 = 600ms float dutyRatio = 0.4; UINT8 temp; if(AppNVMData.isBattLocked == TRUE) { return; } if(UartBattInfoRecvFlag == true) { lightTimer++; if(battWorkState == 0||battWorkState == 1) //静置或放电状态 { if(battSOC<=10) { if(lightTimer<(UINT8)(socLowLEDFlashPeriod*dutyRatio)) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_OFF); NetSocDisplay(LED_SOC_2,LED_TURN_OFF); NetSocDisplay(LED_SOC_3,LED_TURN_OFF); } else if(lightTimer>=(UINT8)(socLowLEDFlashPeriod*dutyRatio) && lightTimer10&&battSOC<=25) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_OFF); NetSocDisplay(LED_SOC_2,LED_TURN_OFF); NetSocDisplay(LED_SOC_3,LED_TURN_OFF); lightTimer = 0; } else if(battSOC>25&&battSOC<=50) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_ON); NetSocDisplay(LED_SOC_2,LED_TURN_OFF); NetSocDisplay(LED_SOC_3,LED_TURN_OFF); lightTimer = 0; } else if(battSOC>50&&battSOC<=75) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_ON); NetSocDisplay(LED_SOC_2,LED_TURN_ON); NetSocDisplay(LED_SOC_3,LED_TURN_OFF); lightTimer = 0; } else if(battSOC>75&&battSOC<=100) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_ON); NetSocDisplay(LED_SOC_2,LED_TURN_ON); NetSocDisplay(LED_SOC_3,LED_TURN_ON); lightTimer = 0; } } else if(battWorkState == 2) { if(battSOC<=25) { if(lightTimer<(UINT8)(chargeLEDFlashPeriod*dutyRatio)) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_OFF); NetSocDisplay(LED_SOC_2,LED_TURN_OFF); NetSocDisplay(LED_SOC_3,LED_TURN_OFF); } else if(lightTimer>=(UINT8)(chargeLEDFlashPeriod*dutyRatio) && lightTimer25&&battSOC<=50) { if(lightTimer<(UINT8)(chargeLEDFlashPeriod*dutyRatio)) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_ON); NetSocDisplay(LED_SOC_2,LED_TURN_OFF); NetSocDisplay(LED_SOC_3,LED_TURN_OFF); } else if(lightTimer>=(UINT8)(chargeLEDFlashPeriod*dutyRatio) && lightTimer50&&battSOC<=75) { if(lightTimer<(UINT8)(chargeLEDFlashPeriod*dutyRatio)) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_ON); NetSocDisplay(LED_SOC_2,LED_TURN_ON); NetSocDisplay(LED_SOC_3,LED_TURN_OFF); } else if(lightTimer>=(UINT8)(chargeLEDFlashPeriod*dutyRatio) && lightTimer75&&battSOC<=97) { if(lightTimer<(UINT8)(chargeLEDFlashPeriod*dutyRatio)) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_ON); NetSocDisplay(LED_SOC_2,LED_TURN_ON); NetSocDisplay(LED_SOC_3,LED_TURN_ON); } else if(lightTimer>=(UINT8)(chargeLEDFlashPeriod*dutyRatio) && lightTimer97&&battSOC<=100) { NetSocDisplay(LED_SOC_0,LED_TURN_ON); NetSocDisplay(LED_SOC_1,LED_TURN_ON); NetSocDisplay(LED_SOC_2,LED_TURN_ON); NetSocDisplay(LED_SOC_3,LED_TURN_ON); } } } } void battErrorStateDisplay() { static UINT8 errorLightTimer = 0; //static UINT32 currentTimerCount=0; UINT8 errorLEDFlashPeriod = 6;//600ms float errorDutyRatio = 0.4; if(AppNVMData.isBattLocked == TRUE) { return; } if(UartBattInfoRecvFlag == true) { errorLightTimer++; if(battWarningState != 0) { if(errorLightTimer<(UINT8)(errorLEDFlashPeriod*errorDutyRatio)) { FaultDisplay(LED_TURN_ON); } else if(errorLightTimer>=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer=(UINT8)(warningLEDFlashPeriod*warningDutyRatio) && warningLightTimer=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer=2 && timerCount<5) { relayControl(FALSE); timerCount++; } else { relayControl(FALSE); timerCount = 0; } } UINT8 decryptionAlgorithm (UINT16 cipherText) { UINT16 plainText = 1; UINT16 publicKeyD = 43; UINT16 publicKeyN = 10961; cipherText = cipherText % publicKeyN; while(publicKeyD >0) { if(publicKeyD % 2 ==1) { plainText = plainText * cipherText % publicKeyN; } publicKeyD = publicKeyD/2; cipherText = (cipherText * cipherText) % publicKeyN; } return (UINT8)plainText; } UINT16 encryptionAlgorithm (UINT16 plainText) { UINT16 cipherText = 1; UINT16 privateKeyE = 37507; UINT16 privateKeyN = 10961; plainText = plainText % privateKeyN; while(privateKeyE >0) { if(privateKeyE % 2 ==1) { cipherText = ( cipherText * plainText) % privateKeyN; } privateKeyE = privateKeyE/2; plainText = (plainText * plainText) % privateKeyN; } return cipherText; } UINT8 Uart_Encrypt_Send() { UINT8 SeedNumberArrray[4]={0x38,0x56,0xfe,0xac}; UINT16 EncodeNumberArray[4]; UINT8 UartEncryptBuffer[17]; UINT8 UartDecryptBuffer[5]; UINT16 CRC_chk_buffer; UINT8 timeCount = 0; UartEncryptBuffer[0] = BMS_ADDRESS_CODE; UartEncryptBuffer[1] = UART_ENCRYPT_CODE; UartEncryptBuffer[2] = 0x0c; for(int i=0;i<4;i++) { SeedNumberArrray[i]=rand(); EncodeNumberArray[i] = encryptionAlgorithm(SeedNumberArrray[i]); UartEncryptBuffer[i+3] = SeedNumberArrray[i]; UartEncryptBuffer[i*2+7] = EncodeNumberArray[i]>>8; UartEncryptBuffer[i*2+8] = EncodeNumberArray[i]; } CRC_chk_buffer = crc_chk(UartEncryptBuffer,17-2); UartEncryptBuffer[15] = CRC_chk_buffer; UartEncryptBuffer[16] = CRC_chk_buffer>>8; USARTdrv->Send(UartEncryptBuffer,17); USARTdrv->Receive(UartDecryptBuffer,5); while((isRecvTimeout == false) && (isRecvComplete == false)) { timeCount++; osDelay(100); if (timeCount>=10) { timeCount =0; isRecvTimeout = true; break; } } #ifdef USING_PRINTF printf("Uart_Rece_buffer: "); for(int i=0;i<5;i++) { printf("%x ",UartDecryptBuffer[i]); } #endif if (isRecvComplete == true) { isRecvComplete = false; return UartDecryptBuffer[2]; } else { isRecvTimeout = false; return 0x03; } } /*-----------------------------------------------------------------------------*/ 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; UINT8 Cycle_conut = 0; while(bmsUpdateFlag && Cycle_conut<2) { 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_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j10) { updateStep = UPDATE_STEP_RESET; 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_RESET; errorCount = 0; } #ifdef USING_PRINTF1 printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } 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 #ifdef USING_PRINTF1 printf("query:"); for(j=0;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j>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_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j>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_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j10) { updateStep = UPDATE_STEP_RESET; errorCount = 0; } #ifdef USING_PRINTF1 //printf("update step:%d\n",updateStep); printf("query:"); for(j=0;j=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_CHECK_VERSION; Cycle_conut++; 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); #ifdef USING_PRINTF printf("query in:"); for(j=0;j0) { USARTdrv->Receive(pRead,readLen); while((isRecvTimeout == false) && (isRecvComplete == false)) { timeCount++; osDelay(100); if (timeCount>=timeout/100) { timeCount =0; isRecvTimeout = true; break; } } #ifdef USING_PRINTF printf("\nanswer in:"); for(j=0;jUninitialize(); osDelay(100); USARTdrv->Initialize(USART_callback); USARTdrv->PowerControl(ARM_POWER_FULL); USARTdrv->Control(ARM_USART_MODE_ASYNCHRONOUS | ARM_USART_DATA_BITS_8 | ARM_USART_PARITY_NONE | ARM_USART_STOP_BITS_1 | ARM_USART_FLOW_CONTROL_NONE, 9600); #ifdef USING_PRINTF printf("\nuart reset in \n"); #endif return 0; } 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