/**************************************************************************** * * Copy right: Qx. * File name: UartTask.c * Description: 串口任务 * History: 2021-03-05 * ****************************************************************************/ #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 "app.h" #include "numeric.h" //全局变量输入区 extern UINT32 Timer_count; extern volatile bool Sleep_flag; extern AppNVMDataType AppNVMData; //全局变量输出区 UartReadMsgType UartReadMsg; osMutexId_t UartMutex = NULL;//Uart数据锁 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_Transmit_func(UINT8* Uart_Read_Msg,UINT8* Uart_Recv_Buffer); UINT8 Uart_WriteCmd_func(Uart_Write_Data_Type UartWriteData); UINT16 crc_chk(UINT8* data, UINT8 length); void battSOCDisplay(void); void battErrorStateDisplay(void); void battLockStateDisplay(UINT8 lockState); void SP_BMS_Update_Service(void); BOOL BattHeaterSwitch(UINT8* heaterSwitch); //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_IDLE); 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控制命令 if(UartWriteCmdHandle == NULL)//Uart控制命令传输指针 { UartWriteCmdHandle = osMessageQueueNew(3,sizeof(Uart_Write_Data_Type), NULL); } if(UartMutex == NULL) { UartMutex = osMutexNew(NULL); } //上电起始控制区域 UartWriteData.WriteCmd = 0x01; if(AppNVMData.isBattLocked) { UartWriteData.Data[0] = 0x00; UartWriteData.Data[1] = 0x00; } else { UartWriteData.Data[0] = 0x00; UartWriteData.Data[1] = 0x03; } osMessageQueuePut(UartWriteCmdHandle,&UartWriteData,0,1000); while (1) { switch (gProcess_Uart_Task) { 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\n",__LINE__,Timer_count); #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; } if(Timer_count-currentTimerCount >= 1) { if(AppNVMData.isBattLocked != 0) { battLockStateDisplay(TRUE); } if(uartReadSuccessFlag) { battSOCDisplay(); battErrorStateDisplay(); } } currentTimerCount = Timer_count; break; } case PROCESS_UART_STATE_READ: { osStatus_t result = osMutexAcquire(UartMutex, osWaitForever); 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_Transmit_func((UINT8 *)&Uart_Read_Msg,UartReadMsg.Header); UartReadMsg.len = Uart_Recv_LEN; PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE); if((UartReadMsg.data[(0x03+BATT_CELL_VOL_NUM)*2+1]&0x03)==0x02) { BattChrgEndFlag=TRUE; } else { BattChrgEndFlag=FALSE; } osMutexRelease(UartMutex); break; } case PROCESS_UART_STATE_WRITE: { Uart_WriteCmd_func(UartWriteData); PROC_UART_STATE_SWITCH(PROCESS_UART_STATE_IDLE); break; } case PROCESS_UART_STATE_SLEEP: { USARTdrv->PowerControl(ARM_POWER_LOW); while(TRUE) { osDelay(60000/portTICK_PERIOD_MS); } break; } } } } //Uart线程初始化 void UartTaskInit(void *arg) { osThreadAttr_t task_attr; memset(&task_attr,0,sizeof(task_attr)); memset(gProcess_Uart_TaskStack, 0xA5, PROC_UART_TASK_STACK_SIZE); task_attr.name = "Uart_Task"; task_attr.stack_mem = gProcess_Uart_TaskStack; task_attr.stack_size = PROC_UART_TASK_STACK_SIZE; task_attr.priority = osPriorityBelowNormal7; task_attr.cb_mem = &gProcess_Uart_Task_t; task_attr.cb_size = sizeof(StaticTask_t); UartTaskId = osThreadNew(UartTask, NULL, &task_attr); } void UartTaskDeInit(void *arg) { osThreadTerminate(UartTaskId); UartTaskId = NULL; } //函数区 //Uart回调程序 void USART_callback(uint32_t event) { if(event & ARM_USART_EVENT_RX_TIMEOUT) { isRecvTimeout = true; } if(event & ARM_USART_EVENT_RECEIVE_COMPLETE) { isRecvComplete = true; } } //Uart校验程序 UINT16 crc_chk(UINT8* data, UINT8 length) { UINT8 j; UINT16 reg_crc=0xFFFF; while(length--) { reg_crc ^= *data++; for(j=0;j<8;j++) { if(reg_crc & 0x01) { reg_crc=(reg_crc>>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_Transmit_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((isRecvTimeout == false) && (isRecvComplete == false)) { timeout++; osDelay(100); if (timeout>=50) { timeout =0; isRecvTimeout = true; break; } } // #ifdef USING_PRINTF // 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 battCellTemp[BATT_TEMP_NUM]; UINT8 maxCellTemp,minCellTemp; UINT8 i =0; UINT8 currentSwitchState = 0; //get the current switch state and the cell temp currentSwitchState = UartReadMsg.data[(0x1C+BATT_CELL_VOL_NUM+(BATT_TEMP_NUM+2))*2+1]&0x01; for(int i=0; i10+40||maxCellTemp>30+40) { *heaterSwitch = 0; isNeedtoSwitch= true; } } return isNeedtoSwitch; } void battSOCDisplay() { static UINT8 workState; static UINT8 currentSoc; 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(UartReadMsg.Header[2]>0) { temp = UartReadMsg.data[(0x03+BATT_CELL_VOL_NUM)*2+1]&0x03; workState = ((temp&0x01)<<01)|(temp>>0x01); currentSoc = UartReadMsg.data[(0x0B+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2+1]; } #ifdef USING_PRINTF printf("current SOC = %d\n",currentSoc); printf("work state = %d\n",workState); #endif lightTimer++; if(workState == 0||workState == 2) //静置或放电状态 { if(currentSoc<=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&¤tSoc<=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(currentSoc>25&¤tSoc<=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(currentSoc>50&¤tSoc<=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(currentSoc>75&¤tSoc<=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(workState == 1) { if(currentSoc<=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&¤tSoc<=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&¤tSoc<=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&¤tSoc<=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&¤tSoc<=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 UINT32 errorState; static UINT8 errorLightTimer = 0; //static UINT32 currentTimerCount=0; UINT8 errorLEDFlashPeriod = 6;//600ms float errorDutyRatio = 0.4; if(AppNVMData.isBattLocked == TRUE) { return; } if(UartReadMsg.Header[2]>0) { MEMCPY(&errorState,&(UartReadMsg.data[(0x09+BATT_CELL_VOL_NUM+BATT_TEMP_NUM+2)*2]),4); } errorLightTimer++; //errorState = testErrorState; #ifdef USING_PRINTF printf("error state = %d\n",errorState); #endif if(errorState != 0) { if(errorLightTimer<(UINT8)(errorLEDFlashPeriod*errorDutyRatio)) { FaultDisplay(LED_TURN_ON); } else if(errorLightTimer>=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer=(UINT8)(errorLEDFlashPeriod*errorDutyRatio) && errorLightTimer0) { if(publicKeyD % 2 ==1) { plainText = plainText * cipherText % publicKeyN; } publicKeyD = publicKeyD/2; cipherText = (cipherText * cipherText) % publicKeyN; } return (UINT8)plainText; } UINT16 encryptionAlgorithm (UINT8 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; cipherText = (plainText * plainText) % privateKeyN; } return cipherText; } UINT8 SP_BMS_Update_CheckSUM(UINT8* pSendData,UINT8 len) { UINT8 ret = 0; UINT8 i=0; for(i=0;i