/* * @Author : ChenJie * @Date : 2022-02-10 11:43:56 * @Version : V3.0 * @LastEditors: chenjie * @LastEditTime: 2022-11-10 * @Description : file content * @FilePath: \S32K146_4G\code\app\AppTaskUart1.c */ /* * AppTaskUart2.c * 4G的串口函数 * Created on: 2022年2月10日 * Author: QiXiang_CHENJIE */ #include "AppTaskUart1.h" #include "hal_fls.h" const ATCmdFunc Atcmdfunc[] = { {AT_CMD_TEST, "AT\r\n", at_callbackFunc}, {AT_ATE0, "ATE0\r\n", at_callbackFunc}, {AT_SIMREADY, "AT+CPIN?\r\n", at_callbackFunc}, {AT_GETICCID, "AT+CICCID\r\n", at_callbackFunc}, {AT_CGREG, "AT+CGREG?\r\n", at_callbackFunc}, {AT_CSQ, "AT+CSQ\r\n", at_callbackFunc}, {AT_NETOPEN, "AT+NETOPEN\r\n", at_callbackFunc}, {AT_CGIP, "AT+CDNSGIP=", at_callbackFunc}, {AT_CONNECT, "AT+CIPOPEN=", at_callbackFunc}, {AT_CONNECTCHK, "AT+CIPOPEN?\r\n", at_callbackFunc}, {AT_SEND, "AT+CIPSEND=", at_callbackFunc}, {AT_DISCON, "AT+CIPCLOSE=0\r\n", at_callbackFunc}, {AT_NETCLOSE, "AT+NETCLOSE\r\n", at_callbackFunc}, {AT_CGNSSPWR, "AT+CGNSSPWR=1\r\n", at_callbackFunc}}; static process_Tcp gProcess_Tcp_Task = PROCESS_TCP_INIT; #define PROC_TCP_STATE_SWITCH(a) (gProcess_Tcp_Task = a) sint8 InitFunc(void); sint8 TcpConnectFunc(sint8 *ConnectId); sint8 TcpDataSendFunc(sint8 ConnectId,uint8 DataSendIdxIn); sint8 TcpRegisterChkFunc(void); void TcpDataEncode(uint8 DataIdx,uint32 *PtrSendAddr, uint16 *SendLen); void GetUtc8Time(UTC8TimeType *UTC8TimeTcpPtr); void TimeUpdate(UTC8TimeType *UTC8TimeTcpPtr); static void TcpDataSendFeqHandFunc(uint8 *DataIdx); static void AtcmdTransmit(sint8 CmdIdx, uint8 *SetValuePtr, uint16 SetValueLen, sint8 *retFunc, uint16 timeout); static void TcpDataInfoRecvHandle(uint8 *DataRecv, uint16 DataRecvLen); static void GetCSQValue(uint8 *out); void Fota_Ftp(uint8 *dataPtrIn); uint16 tcpUdsFunc(uint8 *Ptr, uint8 *AnsPtr); static void vTimer1000msCallback(TimerHandle_t pxTimer); volatile TcpFeq_type TcpDataFeq={ {0x01,60*60*2,0}, //time calib {0x86,60*60,0}, //Version feq {0x91,10,0}, //trunk batt msg feq {0x82,10,0}, //gps msg feq {0x90,10,0}, //trunk vehichle msg feq {0x92,60,0}, //trunk acc msg feq {0x8C,10,0}, //debug msg feq {0x95,10,0}, //trunk mes high feq {0x96,10,0}, //batt algorithm msg feq };//默认发送频率 static UTC8TimeType UTC8TimeTcp;//全局真实时间存储 extern boolean waitForSleepFlag; boolean Uart_4G_Task_Sleep_FLag = false; TimerHandle_t monitorTimer1000ms; void Uart_4G_Task(void *pvParameters) { (void)pvParameters; uint32 RecvTimerDelay = 0; uint8 UartRecvPtr[512]; volatile uint16 tcpErrorCounter = 0; uint16 pReadLen = 0; monitorTimer1000ms = xTimerCreate("monitor1000ms", 1000, pdTRUE, (void *)0, vTimer1000msCallback); xTimerStart(monitorTimer1000ms, 0); for (;;) { if (waitForSleepFlag == true) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_SLEEP); } switch (gProcess_Tcp_Task) { case PROCESS_TCP_INIT: { sint8 InitFlg = -1; InitFlg = InitFunc(); if(InitFlg==0) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE); } else { TcpSysReboot = 1; PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR); } break; } case PROCESS_TCP_IDLE: // 空闲状态 { Tcp_Receive_Data (UartRecvPtr, &pReadLen, 100); // 100ms检测 if (SocketId < 0) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_REGCHK); } else if (pReadLen > 0) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_RECV); RecvTimerDelay = TimerCounter; } else if (AppConfigInfo.eolFlg == 1 && TcpWorkState == 0) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_SEND); } if ((TimerCounter - RecvTimerDelay) >= 30000 && TcpWorkState == 1) // 30s内没有命令下发,进行正常发送任务 { TcpWorkState = 0; } break; } case PROCESS_TCP_REGCHK: // 驻网检查,包括SIM,CPIN检查,ICCID获取 { RegChkRet = TcpRegisterChkFunc(); if (RegChkRet > 0) // 检查通过,SIM卡已就绪,已进行驻网 { PROC_TCP_STATE_SWITCH(PROCESS_TCP_CONNECT); } else { PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR); } break; } case PROCESS_TCP_CONNECT: // 网络连接,包括域名转换 { if (SocketId < 0) { sint8 ConnectRet = 0; ConnectRet = TcpConnectFunc(&SocketId); if (ConnectRet > 0) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE); } else { PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR); } } break; } case PROCESS_TCP_SEND: // 网络数据发送 { sint8 SendRet = -1; uint8 DataSendIdx = 0; //发送判定 TcpDataSendFeqHandFunc(&DataSendIdx); if(DataSendIdx!=0)//有数据处理 { SendRet = TcpDataSendFunc(SocketId,DataSendIdx);//发送函数 if (SendRet == 0) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE); tcpErrorCounter = 0; } else { SocketId = -1; PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR); } } if(Fota_error_flag==1) { SocketId = -1; PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR); } break; } case PROCESS_TCP_RECV: // 网络数据接收,100ms空闲状态下即可接收 { if (pReadLen > 0 && SocketId >= 0) { TcpDataInfoRecvHandle(UartRecvPtr, pReadLen); } PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE); break; } case PROCESS_TCP_HEART: // 心跳包发送 { break; } case PROCESS_TCP_SLEEP: // 网络休眠状态 { while (waitForSleepFlag == true) { Uart_4G_Task_Sleep_FLag = true; vTaskDelay(pdMS_TO_TICKS(1000)); } PROC_TCP_STATE_SWITCH(PROCESS_TCP_INIT); break; } case PROCESS_TCP_ERROR: // 错误状态 { vTaskDelay(pdMS_TO_TICKS(1000)); tcpErrorCounter++; if (tcpErrorCounter > 60 || TcpSysReboot == 1||Fota_error_flag == 1) // 无法驻网或者联网或者FTP失败 { Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_ON); vTaskDelay(pdMS_TO_TICKS(2500)); Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_OFF); vTaskDelay(pdMS_TO_TICKS(2500)); tcpErrorCounter = 0; Fota_error_flag = 0; PROC_TCP_STATE_SWITCH(PROCESS_TCP_INIT); } else { PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE); } break; } } } } static void vTimer1000msCallback(TimerHandle_t pxTimer) { uint32 ulTimerID; ulTimerID = (uint32)pvTimerGetTimerID(pxTimer); sint16 *TcpDataFeqPtr =NULL; TcpDataFeqPtr = (sint16 *)&TcpDataFeq; if (ulTimerID == 0) { if(SocketId>=0) { for(uint8 i=2;i 0 && (BMS_PackCurr>=10000-50 && BMS_PackCurr <=10000+50)) //pack soc(0.4,0) ≤ 25% and the abs value of pack current(0.1,-10000) ≤ 5A { if(timerDelayFlag == 0) { timerDelayCounter = TimerCounter; TcpDataFeq.BattHighFeqCnt[1] = 1; //pirod changes to 1 second timerDelayFlag = 1; } } if(TimerCounter-timerDelayCounter >=60000) // time out is 60 seconds { timerDelayFlag = 0; } //读取硬线唤醒源状态,若没有硬线唤醒,则降低调试信息发送频率 Dio_LevelType wakeup1,wakeup2 = STD_HIGH; wakeup1 = Dio_ReadChannel(DioConf_DioChannel_PTB0_GPIO_IN_MCU_WAKEUP1); wakeup2 = Dio_ReadChannel(DioConf_DioChannel_PTE2_GPIO_IN_MCU_WAKEUP2); if(wakeup1==STD_LOW && wakeup2==STD_LOW) { TcpDataFeq.DebugMsgFeqCnt[1] = 10*60; TcpDataFeq.TrkVehichleFeqCnt[1] = 10*60; TcpDataFeq.GpsFeqCnt[1] = 3*60; TcpDataFeq.BattHighFeqCnt[1] = 10*60; TcpDataFeq.BattAlgmMsgFeqCnt[1] = 10*60; } return; } sint8 TcpDataSendFunc(sint8 ConnectId,uint8 DataSendIdxIn) { sint8 outValue = -1; uint32 pSendDataAddr = 0; uint16 DataSendLen = 0; TcpDataEncode(DataSendIdxIn,&pSendDataAddr, &DataSendLen); // 数据组包,malloc申请在里面,pSendData指向申请的地址 if(DataSendLen==0)//长度为0 不调用发送数据函数 { outValue = 0; } else { outValue = tcpipConnectionSend(ConnectId, (uint8 *)pSendDataAddr, DataSendLen); // 发送函数 } if (pSendDataAddr != 0) { vPortFree((uint8 *)(pSendDataAddr)); } pSendDataAddr = 0; return outValue; } sint8 tcpipConnectionSend(uint8 TcpConnectId, uint8 *SendDataPtr, uint16 SendDataLen) { sint8 outValue = -1; uint8 sendErrConuter = 0; uint16 ReadLen = 0; char AtCmdSend[30] = {0}; uint8 AtCmdSendTotalLen = 0; uint8 UartRecvPtr[128]; // 暂存buffer改大 uint8 ret = 0; sprintf(AtCmdSend, "AT+CIPSEND=%d,%d\r\n", TcpConnectId, SendDataLen); AtCmdSendTotalLen = mstrlen(AtCmdSend); while (outValue != 0 && sendErrConuter < 3) { ret = UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)AtCmdSend, AtCmdSendTotalLen, UartRecvPtr, &ReadLen, 1000); if (((ret == 0) && (ReadLen > 0) && ((uint8 *)strstr((char *)UartRecvPtr, (char *)(">")))) || 1) // 此IF条件默认通过 { UART_Send_Data(UART_LPUART1, (uint8 *)SendDataPtr, SendDataLen, 100); sint8 ret = AtcmdDelayRecvFunc(UART_LPUART1, (char *)("+CIPSEND"), 3000); if (ret == 0) { outValue = 0; } else { outValue = -2; sendErrConuter++; } } else { outValue = -1; sendErrConuter++; } } return outValue; } sint8 TcpConnectFunc(sint8 *ConnectId) { uint8 ConnectStep = 1; sint8 ChkState = 0; sint8 ATRet = -1; uint8 UartRecvPtr[100]; while (1) { switch (ConnectStep) { case 1: // AT指令同步 { char *ATCmdSend = (char *)("ATE0\r\n"); uint8 ATCmdSendLen = mstrlen(ATCmdSend); uint8 ReadLen = 0; UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)ATCmdSend, ATCmdSendLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(1000)); uint8 *retptr = NULL; if (ReadLen > 0) { retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("OK")); if (retptr) { ConnectStep++; } else { ChkState = -ConnectStep; return ChkState; } } else { ChkState = -ConnectStep; return ChkState; } break; } case 2: // Netopen { AtcmdTransmit(AT_NETOPEN, NULL, 0, &ATRet, 100); if (ATRet == 0) { ConnectStep++; } else { ChkState = -ConnectStep; return ChkState; } break; } case 3: // 连接检查 { AtcmdTransmit(AT_CONNECTCHK, NULL, 0, &ATRet, 1000); // ATret返回的值是连接id,如果未连接返回-1 if (ATRet >= 0) { *ConnectId = ATRet; return 2; } else { ConnectStep++; } break; } case 4: // 域名转换 { char AtCmdSend[30] = {0}; uint8 AtCmdSendLen = 0; AtCmdSendLen = mstrlen(WebSiteName); memcpy(AtCmdSend, WebSiteName, AtCmdSendLen); memcpy(AtCmdSend + AtCmdSendLen, (char *)CRLF, sizeof(CRLF)); AtCmdSendLen = AtCmdSendLen + 2; AtcmdTransmit(AT_CGIP, (uint8 *)AtCmdSend, AtCmdSendLen, &ATRet, 5000); if (ATRet == 0) { ConnectStep++; } else { ChkState = -ConnectStep; return ChkState; } break; } case 5: // 创建连接 { char AtCmdSend[50] = {0}; uint8 AtCmdSendTotalLen = 0; *ConnectId = 0; /*IP测试更改*/ // char *ATCmdSend = (char *)("\"120.26.68.165\""); // memset(WebSiteIp,0x00,sizeof(WebSiteIp)); // memcpy(WebSiteIp ,ATCmdSend,strlen(ATCmdSend)); // WebSitePort = 15964; /**/ sprintf(AtCmdSend, "AT+CIPOPEN=%d,\"TCP\",%s,%d\r\n", *ConnectId, WebSiteIp, WebSitePort); // 此处需要优化 AtCmdSendTotalLen = mstrlen(AtCmdSend); UART_Send_Data(UART_LPUART1, AtCmdSend, AtCmdSendTotalLen, pdMS_TO_TICKS(100)); ATRet = AtcmdDelayRecvFunc(UART_LPUART1, (char *)("+CIPOPEN: 0,0"), 20000); if (ATRet == 0) { ConnectStep++; } else { ChkState = -ConnectStep; *ConnectId = -1; return ChkState; } break; } default: ChkState = ConnectStep; return ChkState; } } } sint8 TcpRegisterChkFunc(void) { uint8 RegChkStep = 0; sint8 ChkState = 0; // 默认为0 sint8 ATRet = -1; while (1) { switch (RegChkStep) { case 0: // AT指令同步 { AtcmdTransmit(AT_CMD_TEST, NULL, 0, &ATRet, 100); if (ATRet == 0) { RegChkStep++; } else { ChkState = -RegChkStep; return ChkState; } break; } case 1: // CPIN检查 { AtcmdTransmit(AT_SIMREADY, NULL, 0, &ATRet, 100); if (ATRet == 0) { RegChkStep++; } else { ChkState = -RegChkStep; return ChkState; } break; } case 2: { AtcmdTransmit(AT_CGREG, NULL, 0, &ATRet, 1000); // 驻网检查,返回值1和5是驻网成功 if (ATRet == 1 || ATRet == 5) { RegChkStep++; } else { ChkState = -RegChkStep; return ChkState; } break; } default: ChkState = RegChkStep; return ChkState; break; } } } sint8 InitFunc(void) { // 4G模块初始化 uint8 _4G_InitStep = 0; sint8 ATRet = -1; uint16 ReadLen = 0; char *ATCmdSend = NULL; uint8 ATCmdSendLen = 0; uint8 UartRecvPtr[50]; uint16 ATerrorCnt = 0; uint8 *retptr = NULL; Dio_LevelType _4G_Status = 0; // 0-关机,1-开机 Dio_WriteChannel(DioConf_DioChannel_PTA6_GPIO_OUT_MCU_4G_POW_EN, STD_ON); vTaskDelay(pdMS_TO_TICKS(500)); Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_ON); vTaskDelay(pdMS_TO_TICKS(50)); Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_OFF); AtcmdDelayRecvFunc(UART_LPUART1, (char *)("SMS DONE"), 10000); _4G_Status = Dio_ReadChannel(DioConf_DioChannel_PTB1_GPIO_IN_MCU_4G_STATUS); while (1) { switch (_4G_InitStep) { case 0: // AT指令同步 { AtcmdTransmit(AT_CMD_TEST, NULL, 0, &ATRet, 100); if (ATRet == 0) { ATerrorCnt = 0; _4G_InitStep++; } else { vTaskDelay(pdMS_TO_TICKS(1000)); ATerrorCnt++; if (ATerrorCnt > 60 * 5) { return -1; } } break; } case 1: // 关闭回显 { ATCmdSend = (char *)("ATE0\r\n"); ATCmdSendLen = mstrlen(ATCmdSend); UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)ATCmdSend, ATCmdSendLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(10000)); if (ReadLen > 0) { retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("OK")); if (retptr) { _4G_InitStep++; } else { _4G_InitStep = 0; } } else { _4G_InitStep = 0; } break; } case 2: // IMEI获取 { ATCmdSend = (char *)("AT+SIMEI?\r\n"); ATCmdSendLen = mstrlen(ATCmdSend); UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)ATCmdSend, ATCmdSendLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(1000)); if (ReadLen > 0) { retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("+SIMEI")); if (retptr) { memcpy(ImeiNum, retptr + 8, 15); _4G_InitStep++; } else { _4G_InitStep = 0; } } else { _4G_InitStep = 0; } break; } case 3: // 打开时间自动更新 { ATCmdSend = (char *)("AT+CTZU=1\r\n"); ATCmdSendLen = mstrlen(ATCmdSend); UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)ATCmdSend, ATCmdSendLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(1000)); if (ReadLen > 0) { retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("OK")); if (retptr) { _4G_InitStep++; } } else { _4G_InitStep = 0; } break; } case 4: // ICCID获取 { AtcmdTransmit(AT_GETICCID, NULL, 0, &ATRet, 1000); if (ATRet == 0) { _4G_InitStep++; } else { _4G_InitStep = 0; } break; } case 5: { ATCmdSend = (char *)("AT+CIPSENDMODE=0\r\n"); ATCmdSendLen = mstrlen(ATCmdSend); UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)ATCmdSend, ATCmdSendLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100)); if (ReadLen > 0) { retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("OK")); if (retptr) { _4G_InitStep++; } } else { _4G_InitStep = 0; } } default: { return 0; } } } } static void AtcmdTransmit(sint8 CmdIdx, uint8 *SetValuePtr, uint16 SetValueLen, sint8 *retFunc, uint16 timeout) { uint16 ReadLen = 0; uint8 PtrATCmdSend[64]; uint8 ATCmdFixedLen = 0; uint16 ATCmdTotalLen = 0; uint8 UartRecvPtr[256]; ATCmdFixedLen = mstrlen(Atcmdfunc[CmdIdx].str); ATCmdTotalLen = ATCmdFixedLen + SetValueLen; memset(PtrATCmdSend, 0x00, ATCmdTotalLen + 1); memcpy(PtrATCmdSend, Atcmdfunc[CmdIdx].str, ATCmdFixedLen); if (SetValuePtr != NULL) { memcpy(&PtrATCmdSend[ATCmdFixedLen], SetValuePtr, SetValueLen); } UART_Query_Data(UART_LPUART1, UART_LPUART1, PtrATCmdSend, ATCmdTotalLen, UartRecvPtr, &ReadLen, timeout); if (ReadLen > 0) { *retFunc = Atcmdfunc[CmdIdx].cb((char *)PtrATCmdSend, UartRecvPtr, CmdIdx, ReadLen); } else { *retFunc = -1; } return; } sint8 at_callbackFunc(char *PSendStr, char *pReadStr, uint8 CmdIdx, uint16 pReadLen) { sint8 OutValue = -1; uint8 *retptr = NULL; char *OkAns = "OK"; retptr = (uint8 *)strstr((char *)pReadStr, OkAns); switch (CmdIdx) { case AT_CMD_TEST: { if (retptr) { OutValue = 0; } break; } case AT_SIMREADY: { if (retptr) { retptr = (uint8 *)strstr((char *)pReadStr, (char *)("READY")); if (retptr) { OutValue = 0; } } break; } case AT_GETICCID: { if (retptr) { retptr = (uint8 *)strstr((char *)pReadStr, (char *)("ICCID:")); if (retptr) { memcpy(IccidNum, retptr + 7, 20); OutValue = 0; } } break; } case AT_CGREG: { if (retptr) { retptr = (uint8 *)strstr((char *)pReadStr, (char *)("CGREG:")); if (retptr) { uint8 RegN = 0; uint8 RegState = 0; RegN = CharToHex(*(retptr + 7)); RegState = CharToHex(*(retptr + 9)); OutValue = (RegState + RegN); return OutValue; } } break; } case AT_NETOPEN: { if (retptr) { OutValue = 0; } retptr = (uint8 *)strstr((char *)pReadStr, (char *)("opened")); // 重复打开 if (retptr) { OutValue = 0; } break; } case AT_CONNECTCHK: { if (retptr) { retptr = (uint8 *)strstr((char *)pReadStr, (char *)("TCP")); if (retptr) { OutValue = CharToHex(*(retptr - 3)); return OutValue; } } break; } case AT_CGIP: { if (retptr) { memset(WebSiteIp, 0x00, sizeof(WebSiteIp)); for (uint8 i = 0; i < 30; i++) { if (*(retptr - i) == ',') { memcpy(WebSiteIp, retptr - i + 1, i - 5); OutValue = 0; break; } } } break; } case AT_CONNECT: { if (retptr) { retptr = (uint8 *)strstr((char *)pReadStr, (char *)("CIPOPEN:")); if (retptr && pReadLen > 9) { SocketId = CharToHex(*(retptr + 9)); } OutValue = 0; } break; } case AT_SEND: { retptr = (uint8 *)strstr((char *)pReadStr, (char *)(">")); if (retptr) { OutValue = 0; } else { OutValue = -1; } break; } default: break; } return OutValue; } void TcpDataEncode(uint8 DataIdx,uint32 *PtrSendAddr, uint16 *SendLen) { uint8 *SendBuffer = NULL; memcpy(TcpbattSN, AppConfigInfo.deviceSn, 17); if(UTC8TimeTcp.month==0) { DataIdx = 0x01; } switch (DataIdx) { case 0x01: // 时间校准 { char *ATCmdSend = (char *)("AT+CNTP\r\n"); uint8 ATCmdSendLen = mstrlen(ATCmdSend); uint8 ReadLen = 0; uint8 UartRecvPtr[20]; UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)ATCmdSend, ATCmdSendLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(500)); GetUtc8Time(&UTC8TimeTcp); // 时间获取 *SendLen = 0; // 不发送,长度为0 xTimerReset(monitorTimer1000ms,0); return; } case 0x82: { GPSInfo GpsRecvData; GPSMsgtoTcpType GpsToTcpInfo; *SendLen = sizeof(GpsToTcpInfo); SendBuffer = pvPortMalloc(*SendLen); uint16 tac = 0; uint32 cellId = 0; uint8 DataLen = (uint16)sizeof(GpsToTcpInfo.gpsInfo); GpsToTcpInfo.startSymbol[0] = TCP_START_SYM1; GpsToTcpInfo.startSymbol[1] = TCP_START_SYM2; GpsToTcpInfo.cmdSymbol = TCP_CMD_SYM; GpsToTcpInfo.ansSymbol = TCP_ANS_SYM; memcpy(GpsToTcpInfo.SN, TcpbattSN, BATT_SN_LEN); GpsToTcpInfo.encryptMethod = TCP_ENCPT_DISABLE; // not encrypt GpsToTcpInfo.dataLength[0] = (DataLen >> 8) & 0xFF; GpsToTcpInfo.dataLength[1] = DataLen & 0xFF; GpsToTcpInfo.gpsInfo.sendTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year GpsToTcpInfo.gpsInfo.sendTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month GpsToTcpInfo.gpsInfo.sendTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day GpsToTcpInfo.gpsInfo.sendTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour GpsToTcpInfo.gpsInfo.sendTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins GpsToTcpInfo.gpsInfo.sendTimeUTC[5] = UTC8TimeTcp.second & 0xFF; // sec GpsToTcpInfo.gpsInfo.msgMark = DataIdx; GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins GpsToTcpInfo.gpsInfo.msgCollectionTimeUTC[5] = UTC8TimeTcp.second & 0xFF; if (xQueueReceive(GpsDataQueueHandle, &GpsRecvData, 0) == pdPASS) { memcpy((uint8 *)&GpsToTcpInfo.gpsInfo.GpsInfoData, (uint8 *)&GpsRecvData, sizeof(GPSInfo)); } else { memset((uint8 *)&GpsToTcpInfo.gpsInfo.GpsInfoData, 0x00, sizeof(GPSInfo)); } GpsToTcpInfo.gpsInfo.Tac[0] = tac >> 8; GpsToTcpInfo.gpsInfo.Tac[1] = tac & 0xFF; GpsToTcpInfo.gpsInfo.CellID[0] = cellId >> 24; GpsToTcpInfo.gpsInfo.CellID[0] = cellId >> 16; GpsToTcpInfo.gpsInfo.CellID[0] = cellId >> 8; GpsToTcpInfo.gpsInfo.CellID[0] = cellId; uint16 xyzDatacache[3] = {0}; memcpy(xyzDatacache, xyzData, 3 * sizeof(uint16)); for (uint8 i = 0; i < 3; i++) { if (xyzDatacache[i] > 0x8000) // 数据为负 { xyzDatacache[i] = 20000U + (sint16)xyzDatacache[i]; } else { xyzDatacache[i] = xyzDatacache[i] + 20000U; } } GpsToTcpInfo.gpsInfo.xData[0] = xyzDatacache[0] >> 8; GpsToTcpInfo.gpsInfo.xData[1] = xyzDatacache[0]; GpsToTcpInfo.gpsInfo.yData[0] = xyzDatacache[1] >> 8; GpsToTcpInfo.gpsInfo.yData[1] = xyzDatacache[1]; GpsToTcpInfo.gpsInfo.zData[0] = xyzDatacache[2] >> 8; GpsToTcpInfo.gpsInfo.zData[1] = xyzDatacache[2]; GpsToTcpInfo.CRC = bcc_chk((uint8 *)&GpsToTcpInfo, sizeof(GPSMsgtoTcpType) - 1); memcpy(SendBuffer, &GpsToTcpInfo, sizeof(GpsToTcpInfo)); *PtrSendAddr = (uint32)SendBuffer; break; } case 0x86: { VersionMsgtoTcpType VerMsgToTcpInfo; *SendLen = sizeof(VersionMsgtoTcpType); SendBuffer = pvPortMalloc(*SendLen); uint16 DataLen = 0; DataLen = (uint16)sizeof(VerMsgToTcpInfo.VerInfo); VerMsgToTcpInfo.startSymbol[0] = TCP_START_SYM1; VerMsgToTcpInfo.startSymbol[1] = TCP_START_SYM2; VerMsgToTcpInfo.cmdSymbol = TCP_CMD_SYM; VerMsgToTcpInfo.ansSymbol = TCP_ANS_SYM; memcpy(VerMsgToTcpInfo.SN, TcpbattSN, BATT_SN_LEN); VerMsgToTcpInfo.encryptMethod = TCP_ENCPT_DISABLE; // not encrypt VerMsgToTcpInfo.dataLength[0] = (DataLen >> 8) & 0xFF; VerMsgToTcpInfo.dataLength[1] = DataLen & 0xFF; VerMsgToTcpInfo.VerInfo.sendTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year VerMsgToTcpInfo.VerInfo.sendTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month VerMsgToTcpInfo.VerInfo.sendTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day VerMsgToTcpInfo.VerInfo.sendTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour VerMsgToTcpInfo.VerInfo.sendTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins VerMsgToTcpInfo.VerInfo.sendTimeUTC[5] = UTC8TimeTcp.second & 0xFF; // sec VerMsgToTcpInfo.VerInfo.msgMark = DataIdx; VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins VerMsgToTcpInfo.VerInfo.msgCollectionTimeUTC[5] = UTC8TimeTcp.second & 0xFF; memcpy(VerMsgToTcpInfo.VerInfo.ICCID, IccidNum, 20); memcpy(VerMsgToTcpInfo.VerInfo.IMEI, ImeiNum, 15); VerMsgToTcpInfo.VerInfo.BMSHwVersion[0] = BMS_HardwareVersion >> 8; VerMsgToTcpInfo.VerInfo.BMSHwVersion[1] = BMS_HardwareVersion; VerMsgToTcpInfo.VerInfo.BMSSwVersion[0] = BMS_SoftwareVersion >> 24; VerMsgToTcpInfo.VerInfo.BMSSwVersion[1] = BMS_SoftwareVersion >> 16; VerMsgToTcpInfo.VerInfo.BMSSwVersion[2] = BMS_SoftwareVersion >> 8; VerMsgToTcpInfo.VerInfo.BMSSwVersion[3] = BMS_SoftwareVersion; VerMsgToTcpInfo.VerInfo.HwVersion[0] = (HwVersion >> 8) & 0xFF; VerMsgToTcpInfo.VerInfo.HwVersion[1] = (HwVersion)&0xFF; VerMsgToTcpInfo.VerInfo.BLVersion[0] = (BlSwVersion >> 24) & 0xFF; VerMsgToTcpInfo.VerInfo.BLVersion[1] = (BlSwVersion >> 16) & 0xFF; VerMsgToTcpInfo.VerInfo.BLVersion[2] = (BlSwVersion >> 8) & 0xFF; VerMsgToTcpInfo.VerInfo.BLVersion[3] = (BlSwVersion)&0xFF; VerMsgToTcpInfo.VerInfo.DRVVersion[0] = (DrvSwVersion >> 24) & 0xFF; VerMsgToTcpInfo.VerInfo.DRVVersion[1] = (DrvSwVersion >> 16) & 0xFF; VerMsgToTcpInfo.VerInfo.DRVVersion[2] = (DrvSwVersion >> 8) & 0xFF; VerMsgToTcpInfo.VerInfo.DRVVersion[3] = (DrvSwVersion)&0xFF; VerMsgToTcpInfo.VerInfo.APPVersion[0] = (AppSwVersion >> 24) & 0xFF; VerMsgToTcpInfo.VerInfo.APPVersion[1] = (AppSwVersion >> 16) & 0xFF; VerMsgToTcpInfo.VerInfo.APPVersion[2] = (AppSwVersion >> 8) & 0xFF; VerMsgToTcpInfo.VerInfo.APPVersion[3] = (AppSwVersion)&0xFF; VerMsgToTcpInfo.VerInfo.BmsType = BmsManuFacture; VerMsgToTcpInfo.VerInfo.BmsInfo = BmsInfo; VerMsgToTcpInfo.VerInfo.DataModuleType = DataModuleType; VerMsgToTcpInfo.CRC = bcc_chk((uint8 *)&VerMsgToTcpInfo, sizeof(VerMsgToTcpInfo) - 1); memcpy(SendBuffer, &VerMsgToTcpInfo, sizeof(VersionMsgtoTcpType)); *PtrSendAddr = (uint32)SendBuffer; break; } case DebugMsg: { // extern char gpsTestBuffer[20]; char rbuf[512]={0}; char tmp[13] = {0}; memcpy(tmp,BMS_SN,12); DebugMsgtoTcpType DebugMsgInfo; UINT16 DataLen = 0; UINT16 BufferLen = 0; // sprintf((char *)rbuf, "{%.2f,%.2f,%.2f,%.2f,%.2f;\ // %.2f,%.2f,%.2f,%.2f,%.2f,}\ // {%.2f,%.2f,%.2f,%.2f,%.2f;\ // %.2f,%.2f,%.2f,%.2f,%.2f,}\ // {%.2f,%.2f,%.2f,%.2f,%.2f;\ // %.2f,%.2f,%.2f,%.2f,%.2f,},%s,%d,\ // {%.2f,%.2f,%.2f,%.2f,\ // %d,%d,%d,%d,%d,%d}", // returnFreq[0][0], returnFreq[0][1], returnFreq[0][2], returnFreq[0][3], returnFreq[0][4], // returnP[0][0], returnP[0][1], returnP[0][2], returnP[0][3], returnP[0][4], // // returnFreq[1][0], returnFreq[1][1], returnFreq[1][2], returnFreq[1][3], returnFreq[1][4], // returnP[1][0], returnP[1][1], returnP[1][2], returnP[1][3], returnP[1][4], // // returnFreq[2][0], returnFreq[2][1], returnFreq[2][2], returnFreq[2][3], returnFreq[2][4], // returnP[2][0], returnP[2][1], returnP[2][2], returnP[2][3], returnP[2][4],tmp,DeviceErrNum, // socd_pct_ahSoc,socd_pct_battSoc,socd_pct_bcuSoc,socd_pct_ekfSoc, // BBox_TotalCharEngy,BBox_TotalDischarEngy,BBox_TotalBackCharEngy,BBox_TotalCharCapy,BBox_TotalDischarCapy,BBox_TotalBackCharCapy); sprintf((char *)rbuf, "%s,%d,\ {%.2f,%.2f,%.2f,%.2f},\ {%d,%d,%d,%d,%d,%d},\ {%.3f,%.3f,%.3f,%.1f,%d,%d}", tmp,DeviceErrNum, socd_pct_ahSoc,socd_pct_battSoc,socd_pct_bcuSoc,socd_pct_ekfSoc, BBox_TotalCharEngy,BBox_TotalDischarEngy,BBox_TotalBackCharEngy,BBox_TotalCharCapy,BBox_TotalDischarCapy,BBox_TotalBackCharCapy, ihd_V_cellUMax,ihd_V_cellUMin,ihd_V_cellUAvrg,ihd_I_battCurr_T2,BMS_PackSOC,rtev_flg_EESt[3]); BufferLen = strlen((const char *)rbuf); *SendLen = BufferLen + sizeof(DebugMsgInfo); SendBuffer = pvPortMalloc(*SendLen); memcpy(SendBuffer + sizeof(DebugMsgInfo) - 1, rbuf, BufferLen); DataLen = sizeof(DebugMsgInfo.DebugInfo) + BufferLen; DebugMsgInfo.startSymbol[0] = TCP_START_SYM1; DebugMsgInfo.startSymbol[1] = TCP_START_SYM2; DebugMsgInfo.cmdSymbol = TCP_CMD_SYM; DebugMsgInfo.ansSymbol = TCP_ANS_SYM; memcpy(DebugMsgInfo.SN, TcpbattSN, BATT_SN_LEN); DebugMsgInfo.encryptMethod = TCP_ENCPT_DISABLE; // not encrypt DebugMsgInfo.dataLength[0] = (DataLen >> 8) & 0xFF; DebugMsgInfo.dataLength[1] = DataLen & 0xFF; DebugMsgInfo.DebugInfo.sendTimeUTC[0] = UTC8TimeTcp.year & 0xFF; // year DebugMsgInfo.DebugInfo.sendTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month DebugMsgInfo.DebugInfo.sendTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day DebugMsgInfo.DebugInfo.sendTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour DebugMsgInfo.DebugInfo.sendTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins DebugMsgInfo.DebugInfo.sendTimeUTC[5] = UTC8TimeTcp.second & 0xFF; // sec DebugMsgInfo.DebugInfo.msgMark = DebugMsg; DebugMsgInfo.DebugInfo.DebugLen[0] = BufferLen >> 8; DebugMsgInfo.DebugInfo.DebugLen[1] = BufferLen; memcpy(SendBuffer, (UINT8 *)&DebugMsgInfo, sizeof(DebugMsgInfo) - 1); DebugMsgInfo._CRC = bcc_chk(SendBuffer, BufferLen + sizeof(DebugMsgInfo) - 1); memcpy(SendBuffer + BufferLen + sizeof(DebugMsgInfo) - 1, &DebugMsgInfo._CRC, 1); *PtrSendAddr = (uint32)SendBuffer; break; } case 0x90: { *SendLen = 0x52; SendBuffer = pvPortMalloc(*SendLen); *(SendBuffer + 0) = TCP_START_SYM1; *(SendBuffer + 1) = TCP_START_SYM2; *(SendBuffer + 2) = TCP_CMD_SYM; *(SendBuffer + 3) = TCP_ANS_SYM; memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN); *(SendBuffer + 0x15) = (TCP_ENCPT_DISABLE & 0xFF); // uint8 TCP_ENCPT_DISABLE uint16 DataLen = 0x39; // 57 *(SendBuffer + 0x16) = ((DataLen >> 8) & 0xFF); // uint16 DataLen *(SendBuffer + 0x17) = (DataLen & 0xFF); *(SendBuffer + 0x18) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x19) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x1A) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x1B) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x1C) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x1D) = (UTC8TimeTcp.second & 0xFF); // uint8 second *(SendBuffer + 0x1E) = (DataIdx & 0xFF); // uint8 BATTMSG *(SendBuffer + 0x1F) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x20) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x21) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x22) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x23) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x24) = (UTC8TimeTcp.second & 0xFF); // uint8 second memcpy(SendBuffer + 0x25, VIN, 17); *(SendBuffer + 0x36) = (vehicleStatus & 0xFF); // uint8 整车状态 if (BMS_Mode == 2) { bmsHVOn = 1; } else { bmsHVOn = 2; } *(SendBuffer + 0x37) = (bmsHVOn & 0xFF); // uint8 bms上高压指令 *(SendBuffer + 0x38) = (currentGearPosition & 0xFF); // uint8 当前档位 *(SendBuffer + 0x39) = (parkingBreakStatus & 0xFF); // uint8 手刹信号 *(SendBuffer + 0x3A) = (breakingStatus & 0xFF); // uint8 制动开关 *(SendBuffer + 0x3B) = ((ODO >> 24) & 0xFF); // uint32 总里程 *(SendBuffer + 0x3C) = ((ODO >> 16) & 0xFF); *(SendBuffer + 0x3D) = ((ODO >> 8) & 0xFF); *(SendBuffer + 0x3E) = (ODO & 0xFF); *(SendBuffer + 0x3F) = (dcdcWorkStatus & 0xFF); // uint8 DCDC状态 *(SendBuffer + 0x40) = (numOfChrgableSubsys & 0xFF); // uint8 可充电子系统数 *(SendBuffer + 0x41) = (chrgableSubsysCode & 0xFF); // uint8 可充电储能子系统号 *(SendBuffer + 0x42) = (BMS_MaxCellTempCSC & 0xFF); // uint8 最高温度子系统号 精度_1,偏移量_0,单位_ *(SendBuffer + 0x43) = (BMS_MaxCellTempNum & 0xFF); // uint8 最高温度探针单体代号 精度_1,偏移量_0,单位_ *(SendBuffer + 0x44) = (BMS_MinCellTempCSC & 0xFF); // uint8 最低温度子系统号 精度_1,偏移量_0,单位_ *(SendBuffer + 0x45) = (BMS_MinCellTempNum & 0xFF); // uint8 最低温度探针子系统代号 精度_1,偏移量_0,单位_ *(SendBuffer + 0x46) = (BMS_MaxCellVoltCSC & 0xFF); // uint8 最高电压电池子系统号 精度_1,偏移量_0,单位_ *(SendBuffer + 0x47) = ((BMS_MaxCellVoltNum >> 8) & 0xFF); // uint16 最高电压电池单体代号 精度_1,偏移量_0,单位_ *(SendBuffer + 0x48) = (BMS_MaxCellVoltNum & 0xFF); *(SendBuffer + 0x49) = (BMS_MinCellVoltCSC & 0xFF); // uint8 最低电压电池子系统号 精度_1,偏移量_0,单位_ *(SendBuffer + 0x4A) = ((BMS_MinCellVoltNum >> 8) & 0xFF); // uint16 最低电压电池单体代号 精度_1,偏移量_0,单位_ *(SendBuffer + 0x4B) = (BMS_MinCellVoltNum & 0xFF); *(SendBuffer + 0x4C) = (ebcStatus & 0xFF); // uint8 换电控制器状态 *(SendBuffer + 0x4D) = (uint8)((ebcAskHVOn & 0x01) | ((ebcAskHVOff & 0x01) << 1) | ((retainLockSignal & 0x01) << 3) | ((dischargeLockSignal & 0x01) << 5) | ((chargeLockSignal & 0x01) << 6)); *(SendBuffer + 0x4E) = (chargeFlag & 0xFF); // uint8 充电标志位 *(SendBuffer + 0x4F) = ((vcuDCVol >> 8) & 0xFF); // uint16 电机直流母线电压 *(SendBuffer + 0x50) = (vcuDCVol & 0xFF); *(SendBuffer + 0x51) = bcc_chk(SendBuffer, 0x51); *PtrSendAddr = (uint32)SendBuffer; break; } case 0x91: { if(BMS_CellRecvFlg==false)//CAN上电压数据未接收完成 { *SendLen = 0; // 不发送,长度为0 return; } GetCSQValue(&CSQValue); *SendLen = 0x54 + min(BMS_CellTotal, BMS_CELL_MAX_NUM) * 2 + min(BMS_TempTotal, BMS_TEMP_MAX_NUM); SendBuffer = pvPortMalloc(*SendLen); *(SendBuffer + 0) = TCP_START_SYM1; *(SendBuffer + 1) = TCP_START_SYM2; *(SendBuffer + 2) = TCP_CMD_SYM; *(SendBuffer + 3) = TCP_ANS_SYM; memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN); *(SendBuffer + 0x15) = (TCP_ENCPT_DISABLE & 0xFF); // uint8 TCP_ENCPT_DISABLE uint16 DataLen = 0x3B + min(BMS_CellTotal, BMS_CELL_MAX_NUM) * 2 + min(BMS_TempTotal, BMS_TEMP_MAX_NUM); *(SendBuffer + 0x16) = ((DataLen >> 8) & 0xFF); // uint16 DataLen *(SendBuffer + 0x17) = (DataLen & 0xFF); *(SendBuffer + 0x18) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x19) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x1A) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x1B) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x1C) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x1D) = (UTC8TimeTcp.second & 0xFF); // uint8 second *(SendBuffer + 0x1E) = (DataIdx & 0xFF); // uint8 BATTMSG *(SendBuffer + 0x1F) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x20) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x21) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x22) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x23) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x24) = (UTC8TimeTcp.second & 0xFF); // uint8 second *(SendBuffer + 0x25) = (CSQValue & 0xFF); // uint8 csq if (BMS_Mode == 2) { bmsHVOn = 1; } else { bmsHVOn = 2; } *(SendBuffer + 0x26) = (bmsHVOn & 0xFF); // uint8 BMS当前状态,0:预留;1:高压上电;2:高压下电;3:无效;,Re-1,Off-0, *(SendBuffer + 0x27) = (BMS_CharGunSt & 0xFF); // uint8 直流充电枪连接状态,0:未连接1 : 连接, Re - 1, Off - 0, *(SendBuffer + 0x28) = (BMS_FtLvl & 0xFF); // uint8 当前最高故障等级,0-正常 1-1级 轻微故障 2-2级 较严重故障 3-3级 最严重故障,精度_1,偏移量_0,单位_ *(SendBuffer + 0x29) = (BMS_FtCode & 0xFF); // uint8 故障码,见BMS_ErrCode,精度_1,偏移量_0,单位_ *(SendBuffer + 0x2A) = (BMS_ReqHVOff & 0xFF); // uint8 BMS下高压请求,0-无效 1-请求下高压 2-不请求下高压 3-无效,精度_1,偏移量_0,单位_ *(SendBuffer + 0x2B) = (BMS_CharSt & 0xFF); // uint8 充电状态,0-未充电 1-充电中 2-充电已完成 3-充电错误故障,精度_1,偏移量_0,单位_ *(SendBuffer + 0x2C) = (BMS_PackSOC & 0xFF); // uint8 电池包SOC 精度_0.4,偏移量_0,单位_ *(SendBuffer + 0x2D) = (BMS_PackSOH / 25 * 10) & 0xFF; // SOH 精度1% *(SendBuffer + 0x2E) = (BMS_BattVolt >> 8) & 0xFF; // 电池包总电压 *(SendBuffer + 0x2F) = (BMS_BattVolt & 0xFF); *(SendBuffer + 0x30) = ((BMS_PackCurr >> 8) & 0xFF); // uint16 电池包总电流,充电为负值,放电为正值 精度_0.1,偏移量_-1000,单位_A *(SendBuffer + 0x31) = (BMS_PackCurr & 0xFF); *(SendBuffer + 0x32) = ((BMS_SysInsRes >> 8) & 0xFF); // uint16 系统绝缘电阻 精度_1,偏移量_0,单位_KΩ *(SendBuffer + 0x33) = (BMS_SysInsRes & 0xFF); /*28 Byte 继电器状态*/ *(SendBuffer + 0x34) = (BMS_StPosRly & 0xFF); // uint8 主正继电器状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x35) = (BMS_StPreCharRly & 0xFF); // uint8 预充继电器状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x36) = (BMS_StNegRly & 0xFF); // uint8 主负继电器状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x37) = 0; // 三合一 *(SendBuffer + 0x38) = 0; // PTC *(SendBuffer + 0x39) = 0; // 空调 *(SendBuffer + 0x3A) = (BMS_StPosCharRly1 & 0xFF); // uint8 直流充正继电器1状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x3B) = (BMS_StNegCharRly1 & 0xFF); // uint8 直流充负继电器1状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x3C) = (BMS_StPosCharRly2 & 0xFF); // uint8 直流充正继电器2状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x3D) = (BMS_StNegCharRly2 & 0xFF); // uint8 直流充负继电器2状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x3E) = (BMS_StPosHeatRly & 0xFF); // uint8 加热正继电器状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x3F) = (BMS_StNegHeatRly & 0xFF); // uint8 加热负继电器状态,0-预留 1-断开 2-吸合 ,精度_1,偏移量_0,单位_ *(SendBuffer + 0x40) = 0; /*28-Byte继电器状态结束*/ *(SendBuffer + 0x50) = ((BMS_CellTotal >> 8) & 0xFF); // uint16 PACK中单体电芯的总数目 *(SendBuffer + 0x51) = (BMS_CellTotal & 0xFF); for (uint16 index = 0; index < min(BMS_CellTotal, BMS_CELL_MAX_NUM); index++) { *(SendBuffer + 0x52 + index * 2) = ((BMS_CellVolt[index] >> 8) & 0xFF); *(SendBuffer + 0x52 + index * 2 + 1) = ((BMS_CellVolt[index]) & 0xFF); } *(SendBuffer + 0x52 + min(BMS_CellTotal, BMS_CELL_MAX_NUM) * 2) = (BMS_TempTotal & 0xFF); // uint8 PACK中电芯温度点(探针)的总数目 memcpy(SendBuffer + 0x53 + min(BMS_CellTotal, BMS_CELL_MAX_NUM) * 2, BMS_CellTemp, min(BMS_TempTotal, BMS_TEMP_MAX_NUM)); *(SendBuffer + 0x53 + min(BMS_CellTotal, BMS_CELL_MAX_NUM) * 2 + min(BMS_TempTotal, BMS_TEMP_MAX_NUM)) = bcc_chk(SendBuffer, 0x53 + min(BMS_CellTotal, BMS_CELL_MAX_NUM) * 2 + min(BMS_TempTotal, BMS_TEMP_MAX_NUM)); *PtrSendAddr = (uint32)SendBuffer; break; } case 0x92: { *SendLen = 0x4E; SendBuffer = pvPortMalloc(*SendLen); *(SendBuffer + 0) = TCP_START_SYM1; *(SendBuffer + 1) = TCP_START_SYM2; *(SendBuffer + 2) = TCP_CMD_SYM; *(SendBuffer + 3) = TCP_ANS_SYM; memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN); *(SendBuffer + 0x15) = (TCP_ENCPT_DISABLE & 0xFF); // uint8 TCP_ENCPT_DISABLE uint16 DataLen = 0x35; *(SendBuffer + 0x16) = ((DataLen >> 8) & 0xFF); // uint16 DataLen *(SendBuffer + 0x17) = (DataLen & 0xFF); *(SendBuffer + 0x18) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x19) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x1A) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x1B) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x1C) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x1D) = (UTC8TimeTcp.second & 0xFF); // uint8 second *(SendBuffer + 0x1E) = (DataIdx & 0xFF); // uint8 *(SendBuffer + 0x1F) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x20) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x21) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x22) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x23) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x24) = (UTC8TimeTcp.second & 0xFF); // uint8 second *(SendBuffer + 0x25) = ((BBox_TotalCharCapy >> 24) & 0xFF); // uint32 累积充入Ah 数 精度_0.1,偏移量_0,单位_Ah *(SendBuffer + 0x26) = ((BBox_TotalCharCapy >> 16) & 0xFF); *(SendBuffer + 0x27) = ((BBox_TotalCharCapy >> 8) & 0xFF); *(SendBuffer + 0x28) = (BBox_TotalCharCapy & 0xFF); *(SendBuffer + 0x29) = ((BBox_TotalDischarCapy >> 24) & 0xFF); // uint32 累积放出Ah 数 精度_0.1,偏移量_0,单位_Ah *(SendBuffer + 0x2A) = ((BBox_TotalDischarCapy >> 16) & 0xFF); *(SendBuffer + 0x2B) = ((BBox_TotalDischarCapy >> 8) & 0xFF); *(SendBuffer + 0x2C) = (BBox_TotalDischarCapy & 0xFF); *(SendBuffer + 0x2D) = ((BMS_TotalCharEngy >> 24) & 0xFF); // uint32 累计充入kWh 数 精度_0.1,偏移量_0,单位_KWh *(SendBuffer + 0x2E) = ((BMS_TotalCharEngy >> 16) & 0xFF); *(SendBuffer + 0x2F) = ((BMS_TotalCharEngy >> 8) & 0xFF); *(SendBuffer + 0x30) = (BMS_TotalCharEngy & 0xFF); *(SendBuffer + 0x31) = ((BMS_TotalDischarEngy >> 24) & 0xFF); // uint32 累计放出kWh 数 精度_0.1,偏移量_0,单位_KWh *(SendBuffer + 0x32) = ((BMS_TotalDischarEngy >> 16) & 0xFF); *(SendBuffer + 0x33) = ((BMS_TotalDischarEngy >> 8) & 0xFF); *(SendBuffer + 0x34) = (BMS_TotalDischarEngy & 0xFF); *(SendBuffer + 0x35) = ((BBox_TotalBackCharCapy >> 24) & 0xFF); // uint32 累计动能回馈充入Ah 数 精度_0.1,偏移量_0,单位_Ah *(SendBuffer + 0x36) = ((BBox_TotalBackCharCapy >> 16) & 0xFF); *(SendBuffer + 0x37) = ((BBox_TotalBackCharCapy >> 8) & 0xFF); *(SendBuffer + 0x38) = (BBox_TotalBackCharCapy & 0xFF); *(SendBuffer + 0x39) = ((BMS_TotalBackCharEngy >> 24) & 0xFF); // uint32 累计动能回馈充入kWh 数 精度_0.1,偏移量_0,单位_KWh *(SendBuffer + 0x3A) = ((BMS_TotalBackCharEngy >> 16) & 0xFF); *(SendBuffer + 0x3B) = ((BMS_TotalBackCharEngy >> 8) & 0xFF); *(SendBuffer + 0x3C) = (BMS_TotalBackCharEngy & 0xFF); *(SendBuffer + 0x3D) = ((BBox_TotalStaCharCapy >> 24) & 0xFF); // uint32 累计换电站充入Ah 数 精度_0.1,偏移量_0,单位_Ah *(SendBuffer + 0x3E) = ((BBox_TotalStaCharCapy >> 16) & 0xFF); *(SendBuffer + 0x3F) = ((BBox_TotalStaCharCapy >> 8) & 0xFF); *(SendBuffer + 0x40) = (BBox_TotalStaCharCapy & 0xFF); *(SendBuffer + 0x41) = ((BMS_TotalStaCharEngy >> 24) & 0xFF); // uint32 累计换电站充入kWh 数 精度_0.1,偏移量_0,单位_KWh *(SendBuffer + 0x42) = ((BMS_TotalStaCharEngy >> 16) & 0xFF); *(SendBuffer + 0x43) = ((BMS_TotalStaCharEngy >> 8) & 0xFF); *(SendBuffer + 0x44) = (BMS_TotalStaCharEngy & 0xFF); *(SendBuffer + 0x45) = ((BBox_TotalGunCharCapy >> 24) & 0xFF); // uint32 累计插枪充电充入Ah 数 精度_0.1,偏移量_0,单位_Ah *(SendBuffer + 0x46) = ((BBox_TotalGunCharCapy >> 16) & 0xFF); *(SendBuffer + 0x47) = ((BBox_TotalGunCharCapy >> 8) & 0xFF); *(SendBuffer + 0x48) = (BBox_TotalGunCharCapy & 0xFF); *(SendBuffer + 0x49) = ((BMS_TotalGunCharEngy >> 24) & 0xFF); // uint32 累计插枪充电充入kWh 数 精度_0.1,偏移量_0,单位_KWh *(SendBuffer + 0x4A) = ((BMS_TotalGunCharEngy >> 16) & 0xFF); *(SendBuffer + 0x4B) = ((BMS_TotalGunCharEngy >> 8) & 0xFF); *(SendBuffer + 0x4C) = (BMS_TotalGunCharEngy & 0xFF); *(SendBuffer + 0x4D) = bcc_chk(SendBuffer, 0x4D); *PtrSendAddr = (uint32)SendBuffer; break; } case 0x95: { *SendLen = 0x30; SendBuffer = pvPortMalloc(*SendLen); *(SendBuffer + 0) = TCP_START_SYM1; *(SendBuffer + 1) = TCP_START_SYM2; *(SendBuffer + 2) = TCP_CMD_SYM; *(SendBuffer + 3) = TCP_ANS_SYM; memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN); *(SendBuffer + 0x15) = (TCP_ENCPT_DISABLE & 0xFF); // uint8 TCP_ENCPT_DISABLE uint16 DataLen = 0x17; *(SendBuffer + 0x16) = ((DataLen >> 8) & 0xFF); // uint16 DataLen *(SendBuffer + 0x17) = (DataLen & 0xFF); *(SendBuffer + 0x18) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x19) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x1A) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x1B) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x1C) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x1D) = (UTC8TimeTcp.second & 0xFF); // uint8 second *(SendBuffer + 0x1E) = (DataIdx & 0xFF); // uint8 *(SendBuffer + 0x1F) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x20) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x21) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x22) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x23) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x24) = (UTC8TimeTcp.second & 0xFF); // uint8 second // test data // BMS_BattVolt = 5678; // BMS_PackCurr = 35+10000; // BMS_MaxCellVolt = 4235; // BMS_MinCellVolt = 4123; // BMS_MaxCellTemp = 25+50; // BMS_MinCellTemp = 20+50; *(SendBuffer + 0x25) = (BMS_BattVolt >> 8) & 0xFF; // 电池包总电压 *(SendBuffer + 0x26) = (BMS_BattVolt & 0xFF); *(SendBuffer + 0x27) = ((BMS_PackCurr >> 8) & 0xFF); // uint16 电池包总电流,充电为负值,放电为正值 精度_0.1,偏移量_-1000,单位_A *(SendBuffer + 0x28) = (BMS_PackCurr & 0xFF); *(SendBuffer + 0x29) = ((BMS_MaxCellVolt >> 8) & 0xFF); // uint16 电池最高单体电压,1mV *(SendBuffer + 0x2A) = (BMS_MaxCellVolt & 0xFF); *(SendBuffer + 0x2B) = ((BMS_MinCellVolt >> 8) & 0xFF); // uint16 电池最高单体电压,1mV *(SendBuffer + 0x2C) = (BMS_MinCellVolt & 0xFF); *(SendBuffer + 0x2D) = ((BMS_MaxCellTemp-10) & 0xFF); // uint16 电池最高单体电压,1mV *(SendBuffer + 0x2E) = ((BMS_MinCellTemp-10) & 0xFF); *(SendBuffer + 0x2F) = bcc_chk(SendBuffer, 0x2F); *PtrSendAddr = (uint32)SendBuffer; break; } case 0x96: { *SendLen = 0x4A; SendBuffer = pvPortMalloc(*SendLen); *(SendBuffer + 0) = TCP_START_SYM1; *(SendBuffer + 1) = TCP_START_SYM2; *(SendBuffer + 2) = TCP_CMD_SYM; *(SendBuffer + 3) = TCP_ANS_SYM; memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN); *(SendBuffer + 0x15) = (TCP_ENCPT_DISABLE & 0xFF); // uint8 TCP_ENCPT_DISABLE uint16 DataLen = 0x31; *(SendBuffer + 0x16) = ((DataLen >> 8) & 0xFF); // uint16 DataLen *(SendBuffer + 0x17) = (DataLen & 0xFF); *(SendBuffer + 0x18) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x19) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x1A) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x1B) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x1C) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x1D) = (UTC8TimeTcp.second & 0xFF); // uint8 second *(SendBuffer + 0x1E) = (DataIdx & 0xFF); // uint8 *(SendBuffer + 0x1F) = ((UTC8TimeTcp.year) & 0xFF); // uint8 year *(SendBuffer + 0x20) = (UTC8TimeTcp.month & 0xFF); // uint8 month *(SendBuffer + 0x21) = (UTC8TimeTcp.day & 0xFF); // uint8 day *(SendBuffer + 0x22) = (UTC8TimeTcp.hour & 0xFF); // uint8 hour *(SendBuffer + 0x23) = (UTC8TimeTcp.minute & 0xFF); // uint8 minute *(SendBuffer + 0x24) = (UTC8TimeTcp.second & 0xFF); // uint8 second // test data // BMS_PackSOC = 20/0.4; // BMS_PackSOH = 95/0.4; // BBox_PackSOC = 91/0.4; // BBox_PackSOH = 96; // BBox_TotalDischarCapy = 12345; // BBox_TotalCharCapy = 23456; // BBox_TotalBackCharCapy = 34567; // BBox_TotalDischarEngy = 45678; // BBox_TotalCharEngy = 56789; // BBox_TotalBackCharEngy= 67890; // BBox_Dq_Dv_MAX = 123456; // BBox_Dq_Dv_MIN = 111112; *(SendBuffer + 0x25) = (BMS_PackSOC) & 0xFF; // BMS计算SOC *(SendBuffer + 0x26) = (BMS_PackSOH / 25 * 10) & 0xFF; // SOH 精度1% *(SendBuffer + 0x27) = (BBox_PackSOC & 0xFF); // 终端计算SOC *(SendBuffer + 0x28) = (BBox_PackSOH & 0xFF); *(SendBuffer + 0x29) = ((BBox_TotalDischarCapy >> 24) & 0xFF); // uint32 BBox计算累计放电安时数 Ah 精度 0.1Ah *(SendBuffer + 0x2A) = ((BBox_TotalDischarCapy >> 16) & 0xFF); *(SendBuffer + 0x2B) = ((BBox_TotalDischarCapy >> 8) & 0xFF); *(SendBuffer + 0x2C) = ((BBox_TotalDischarCapy) & 0xFF); *(SendBuffer + 0x2D) = ((BBox_TotalCharCapy >> 24) & 0xFF); // uint32 BBox计算累计充电安时数 Ah 精度 0.1Ah *(SendBuffer + 0x2E) = ((BBox_TotalCharCapy >> 16) & 0xFF); *(SendBuffer + 0x2F) = ((BBox_TotalCharCapy >> 8) & 0xFF); *(SendBuffer + 0x30) = ((BBox_TotalCharCapy) & 0xFF); *(SendBuffer + 0x31) = ((BBox_TotalBackCharCapy >> 24) & 0xFF); // uint32 BBox计算累计动能回收安时数 Ah 精度 0.1Ah *(SendBuffer + 0x32) = ((BBox_TotalBackCharCapy >> 16) & 0xFF); *(SendBuffer + 0x33) = ((BBox_TotalBackCharCapy >> 8) & 0xFF); *(SendBuffer + 0x34) = ((BBox_TotalBackCharCapy) & 0xFF); *(SendBuffer + 0x35) = ((BBox_TotalDischarEngy >> 24) & 0xFF); // uint32 BBox计算累计放电能量 Kwh *(SendBuffer + 0x36) = ((BBox_TotalDischarEngy >> 16) & 0xFF); *(SendBuffer + 0x37) = ((BBox_TotalDischarEngy >> 8) & 0xFF); *(SendBuffer + 0x38) = ((BBox_TotalDischarEngy) & 0xFF); *(SendBuffer + 0x39) = ((BBox_TotalCharEngy >> 24) & 0xFF); // uint32 BBox计算累计充电能量 Kwh *(SendBuffer + 0x3A) = ((BBox_TotalCharEngy >> 16) & 0xFF); *(SendBuffer + 0x3B) = ((BBox_TotalCharEngy >> 8) & 0xFF); *(SendBuffer + 0x3C) = ((BBox_TotalCharEngy) & 0xFF); *(SendBuffer + 0x3D) = ((BBox_TotalBackCharEngy >> 24) & 0xFF); // uint32 BBox计算累计动能回收能量 Kwh *(SendBuffer + 0x3E) = ((BBox_TotalBackCharEngy >> 16) & 0xFF); *(SendBuffer + 0x3F) = ((BBox_TotalBackCharEngy >> 8) & 0xFF); *(SendBuffer + 0x40) = ((BBox_TotalBackCharEngy) & 0xFF); *(SendBuffer + 0x41) = ((BBox_Dq_Dv_MAX >> 24) & 0xFF); // uint32 BBox计算Dq/Dv_MAX *(SendBuffer + 0x42) = ((BBox_Dq_Dv_MAX >> 16) & 0xFF); *(SendBuffer + 0x43) = ((BBox_Dq_Dv_MAX >> 8) & 0xFF); *(SendBuffer + 0x44) = ((BBox_Dq_Dv_MAX) & 0xFF); *(SendBuffer + 0x45) = ((BBox_Dq_Dv_MIN >> 24) & 0xFF); // uint32 BBox计算Dq/Dv_MAX *(SendBuffer + 0x46) = ((BBox_Dq_Dv_MIN >> 16) & 0xFF); *(SendBuffer + 0x47) = ((BBox_Dq_Dv_MIN >> 8) & 0xFF); *(SendBuffer + 0x48) = ((BBox_Dq_Dv_MIN) & 0xFF); *(SendBuffer + 0x49) = bcc_chk(SendBuffer, 0x49); *PtrSendAddr = (uint32)SendBuffer; break; } default: break; } } void TimeUpdate(UTC8TimeType *UTC8TimeTcpPtr) { int year = 0, month = 0, day = 0, hour = 0,minute = 0,second = 0; int lastday = 0; year = UTC8TimeTcpPtr->year + 2000; month = UTC8TimeTcpPtr->month; day = UTC8TimeTcpPtr->day; hour = UTC8TimeTcpPtr->hour; minute = UTC8TimeTcpPtr->minute; second = UTC8TimeTcpPtr->second; second+=1; if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { lastday = 31; } else if (month == 4 || month == 6 || month == 9 || month == 11) { lastday = 30; } else { if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) lastday = 29; else lastday = 28; } if(second >=60) { second -=60; minute +=1; if(minute >=60) { minute -=60; hour +=1; } } if (hour >= 24) { hour -= 24; day += 1; if (day > lastday) { day -= lastday; month += 1; if (month > 12) { month -= 12; year += 1; } } } UTC8TimeTcpPtr->year = year - 2000; UTC8TimeTcpPtr->month = month; UTC8TimeTcpPtr->day = day; UTC8TimeTcpPtr->hour = hour; UTC8TimeTcpPtr->minute = minute; UTC8TimeTcpPtr->second = second; } void GetUtc8Time(UTC8TimeType *UTC8TimeTcpPtr) { char *AtCmdAsk = (char *)("AT+CCLK?\r\n"); uint8 AtCmdLen = mstrlen(AtCmdAsk); uint16 ReadLen = 0; uint8 *retptr = NULL; uint8 UartRecvPtr[128]; uint8 ErrCnt = 0; while(ErrCnt<3) { UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)AtCmdAsk, AtCmdLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100)); if (ReadLen ==39 ) { if ((uint8 *)strstr((char *)UartRecvPtr, (char *)("OK"))) { retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("+CCLK:")); if (retptr) { UTC8TimeTcpPtr->year = CharToHex(*(retptr + 8)) * 10 + CharToHex(*(retptr + 9)); UTC8TimeTcpPtr->month = CharToHex(*(retptr + 11)) * 10 + CharToHex(*(retptr + 12)); UTC8TimeTcpPtr->day = CharToHex(*(retptr + 14)) * 10 + CharToHex(*(retptr + 15)); UTC8TimeTcpPtr->hour = CharToHex(*(retptr + 17)) * 10 + CharToHex(*(retptr + 18)); UTC8TimeTcpPtr->minute = CharToHex(*(retptr + 20)) * 10 + CharToHex(*(retptr + 21)); UTC8TimeTcpPtr->second = CharToHex(*(retptr + 23)) * 10 + CharToHex(*(retptr + 24)); break; } } } else { ErrCnt++; } } } static void GetCSQValue(uint8 *out) { char *AtCmdAsk = (char *)("AT+CSQ\r\n"); uint8 AtCmdLen = mstrlen(AtCmdAsk); uint16 ReadLen = 0; uint8 *retptr = NULL; uint8 UartRecvPtr[30]; static uint8 CSQValue = 0; UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)AtCmdAsk, AtCmdLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100)); if (ReadLen > 0) { if ((uint8 *)strstr((char *)UartRecvPtr, (char *)("OK"))) { retptr = (uint8 *)strstr((char *)UartRecvPtr, (char *)("+CSQ:")); char CsqStr[5]; for (uint8 i = 0; i < 5; i++) { if (*(retptr + i + 6) == ',') { break; } memcpy((CsqStr + i), (retptr + i + 6), 1); } CSQValue = atoi(CsqStr); } } *out = CSQValue; return; } static void TcpDataInfoRecvHandle(uint8 *DataRecv, uint16 DataRecvLen) { uint8 Tcp_Cmd; uint8 *Ptr = NULL, *retptr = NULL; uint8 TcpCmdAnswer[50] = {0}; uint16 TcpDataLen = 0; uint16 NumCalTemp = 1; retptr = (uint8 *)strstr((char *)DataRecv, (char *)("\r\n##")); if (retptr == NULL || DataRecvLen < 5) return; for (uint8 i = 0; i < 5; i++) { if (*(retptr - i - 1) == 'D') { break; } TcpDataLen = TcpDataLen + CharToHex(*(retptr - i - 1)) * NumCalTemp; NumCalTemp = NumCalTemp * 10; } if (TcpDataLen > 0) { Ptr = retptr + 2; if ((*(Ptr + 0) == TCP_START_SYM1) && (*(Ptr + 1) == TCP_START_SYM2)) // 服务器起始信息 { Tcp_Cmd = *(Ptr + 2); // 命令标志 if (*(Ptr + 3) == 0xFE) { TcpWorkState = 0x01; // 需要暂停发送,进行命令应答的标志 } else { return; } switch (Tcp_Cmd) { case TCP_QUERY_SYM: break; case TCP_SETCMD_SYM: break; case TCP_CONCMD_SYM: { TcpCmdAnswer[0] = TCP_START_SYM1; TcpCmdAnswer[1] = TCP_START_SYM1; TcpCmdAnswer[2] = TCP_CONCMD_SYM; if (*(Ptr + 30) == 0x83) // 远程升级指令 { TcpCmdAnswer[3] = 0x01; memcpy(&TcpCmdAnswer[4], (Ptr + 4), BATT_SN_LEN); TcpCmdAnswer[21] = TCP_ENCPT_DISABLE; TcpCmdAnswer[22] = 0x00; TcpCmdAnswer[23] = 0x06; memcpy(&TcpCmdAnswer[24], (Ptr + 24), 6); TcpCmdAnswer[30] = bcc_chk(TcpCmdAnswer, 30); tcpipConnectionSend(SocketId, TcpCmdAnswer, 31); Fota_Process_Going = true; vTaskDelay(pdMS_TO_TICKS(5000)); Fota_Ftp(Ptr + 32); Fota_Process_Going = false; } else if (*(Ptr + 30) == 0x80) // 远程锁定命令 { TcpCmdAnswer[3] = 0x01; memcpy(&TcpCmdAnswer[4], (Ptr + 4), BATT_SN_LEN); TcpCmdAnswer[21] = TCP_ENCPT_DISABLE; TcpCmdAnswer[22] = 0x00; TcpCmdAnswer[23] = 0x06; memcpy(&TcpCmdAnswer[24], (Ptr + 24), 6); TcpCmdAnswer[30] = bcc_chk(TcpCmdAnswer, 30); if (*(Ptr + 31) == 0x01) // 0x01代表锁定 { // battSeparateEnable = 1; // battSeparateCtlState = 1; tcpipConnectionSend(SocketId, TcpCmdAnswer, 31); } else if (*(Ptr + 31) == 0x02) // 0x02代表解锁 { // battSeparateEnable = 1; // battSeparateCtlState = 0; tcpipConnectionSend(SocketId, TcpCmdAnswer, 31); } } else { TcpCmdAnswer[3] = 0x0f; memcpy(&TcpCmdAnswer[4], (Ptr + 4), BATT_SN_LEN); TcpCmdAnswer[21] = TCP_ENCPT_DISABLE; TcpCmdAnswer[22] = 0x00; TcpCmdAnswer[23] = 0x06; memcpy(&TcpCmdAnswer[24], (Ptr + 24), 6); TcpCmdAnswer[30] = bcc_chk(TcpCmdAnswer, 30); tcpipConnectionSend(SocketId, TcpCmdAnswer, 31); } break; } case TCP_UDSCMD_SYM: { TcpCmdAnswer[0] = TCP_START_SYM1; TcpCmdAnswer[1] = TCP_START_SYM1; TcpCmdAnswer[2] = TCP_UDSCMD_SYM; uint16 sendLen = tcpUdsFunc(Ptr, TcpCmdAnswer); tcpipConnectionSend(SocketId, TcpCmdAnswer, sendLen); break; } default: { break; } } } } } static uint8 tcpUdsAnsMsgEncode(bool posOrNeg,uint8 udsType_SID, uint16 udsType_DID, uint8 negCode,uint8 *AnsPtr) { uint8 length = 0; if(posOrNeg == false) //neg ans { length = 5; *(AnsPtr + 0) = 0x7F; *(AnsPtr + 1) = udsType_SID; *(AnsPtr + 2) = (udsType_DID>>8)&0xFF; *(AnsPtr + 3) = udsType_DID&0xFF; *(AnsPtr + 4) = negCode; } else { length = 3; *(AnsPtr + 0) = (udsType_SID + 0x40)&0xFF; *(AnsPtr + 1) = (udsType_DID>>8)&0xFF; *(AnsPtr + 2) = udsType_DID&0xFF; } return length; } uint16 tcpUdsFunc(uint8 *Ptr, uint8 *AnsPtr) { uint16 AnsLength = 0; uint8 contrlType = 0; uint16 udsDataLen = 0; uint16 DIDBuffer = 0; uint8 udsType_SID = 0; uint8 udsAnsBuffer[10]; uint8 retLength = 0; uint8 DataBuffer[10]; contrlType = *(Ptr + 30); udsDataLen = *(Ptr + 31) - 3; udsType_SID = *(Ptr + 32); DIDBuffer = *(Ptr + 33) << 8 | *(Ptr + 34); memcpy(DataBuffer, Ptr + 35, udsDataLen); switch (contrlType) { case 0x00: { switch (udsType_SID) { case 0x2E: { switch (DIDBuffer) { case 0x0201: //soc correction did { if(udsDataLen == 2) { float socCorrectionValue = (float)((float)((DataBuffer[0]<<8 | DataBuffer[1])&0xFFFF)*0.1-100); if(socCorrectionValue != 0 && socCorrectionValue<100 && socCorrectionValue>-100) //有效修正 { BBox_SocCorrectionValue = socCorrectionValue; socCorrectionValue = 0; retLength = tcpUdsAnsMsgEncode(true,udsType_SID,DIDBuffer,0x00,udsAnsBuffer); } else { socCorrectionValue = 0; retLength = tcpUdsAnsMsgEncode(false,udsType_SID,DIDBuffer,0x13,udsAnsBuffer); } } else { retLength = tcpUdsAnsMsgEncode(false,udsType_SID,DIDBuffer,0x13,udsAnsBuffer); } *(AnsPtr + 3) = 0x01; memcpy((AnsPtr + 4), (Ptr + 4), BATT_SN_LEN); *(AnsPtr + 21) = TCP_ENCPT_DISABLE; *(AnsPtr + 22) = 0x00; *(AnsPtr + 23) = 0x06 + retLength + 1; memcpy((AnsPtr + 24), (Ptr + 24), 6); *(AnsPtr + 30) = retLength; memcpy((AnsPtr + 31),udsAnsBuffer,retLength); *(AnsPtr + 31 + retLength) = bcc_chk(AnsPtr, 31 + retLength); AnsLength = 32 + retLength; return AnsLength; break; } case 0x0202: //soh correction did { if(udsDataLen == 1) { float sohCorrectionValue = (float)((float)((DataBuffer[0]<<8 | DataBuffer[1])&0xFFFF)*0.1); if(sohCorrectionValue > 0 && sohCorrectionValue<100) //有效修正 { BBox_SohCorrectionValue = sohCorrectionValue; sohCorrectionValue = 0; retLength = tcpUdsAnsMsgEncode(true,udsType_SID,DIDBuffer,0x00,udsAnsBuffer); } else { sohCorrectionValue = 0; retLength = tcpUdsAnsMsgEncode(false,udsType_SID,DIDBuffer,0x13,udsAnsBuffer); } } else { retLength = tcpUdsAnsMsgEncode(false,udsType_SID,DIDBuffer,0x13,udsAnsBuffer); } *(AnsPtr + 3) = 0x01; memcpy((AnsPtr + 4), (Ptr + 4), BATT_SN_LEN); *(AnsPtr + 21) = TCP_ENCPT_DISABLE; *(AnsPtr + 22) = 0x00; *(AnsPtr + 23) = 0x06 + retLength + 1; memcpy((AnsPtr + 24), (Ptr + 24), 6); *(AnsPtr + 30) = retLength; memcpy((AnsPtr + 31),udsAnsBuffer,retLength); *(AnsPtr + 31 + retLength) = bcc_chk(AnsPtr, 31 + retLength); AnsLength = 32 + retLength; return AnsLength; break; } default: retLength = tcpUdsAnsMsgEncode(false,udsType_SID,DIDBuffer,0x31,udsAnsBuffer); *(AnsPtr + 3) = 0x01; memcpy((AnsPtr + 4), (Ptr + 4), BATT_SN_LEN); *(AnsPtr + 21) = TCP_ENCPT_DISABLE; *(AnsPtr + 22) = 0x00; *(AnsPtr + 23) = 0x06 + retLength + 1; memcpy((AnsPtr + 24), (Ptr + 24), 6); *(AnsPtr + 30) = retLength; memcpy((AnsPtr + 31),udsAnsBuffer,retLength); *(AnsPtr + 31 + retLength) = bcc_chk(AnsPtr, 31 + retLength); AnsLength = 32 + retLength; return AnsLength; break; } } default: break; } break; } case 0x01: { switch (udsType_SID) { case 0x2E: { switch (DIDBuffer) { case 0x01: { // battSeparateEnable = 1; if (DataBuffer[0] == 0x01) { // battSeparateCtlState = 1; } else if (DataBuffer[0] == 0x00) { // battSeparateCtlState = 0; } *(AnsPtr + 3) = 0x0f; memcpy((AnsPtr + 4), (Ptr + 4), BATT_SN_LEN); *(AnsPtr + 21) = TCP_ENCPT_DISABLE; *(AnsPtr + 22) = 0x00; *(AnsPtr + 23) = 0x06; memcpy((AnsPtr + 24), (Ptr + 24), 6); *(AnsPtr + 30) = contrlType; *(AnsPtr + 31) = udsDataLen; *(AnsPtr + 32) = udsType_SID; *(AnsPtr + 33) = DIDBuffer >> 8; *(AnsPtr + 34) = DIDBuffer; *(AnsPtr + 36) = DataBuffer[0]; *(AnsPtr + 37) = bcc_chk(AnsPtr, 37); return AnsLength; break; } default: return AnsLength; break; } break; } case 0x22: { break; } default: break; } break; } default: break; } *(AnsPtr + 3) = 0x0f; memcpy((AnsPtr + 4), (Ptr + 4), BATT_SN_LEN); *(AnsPtr + 21) = TCP_ENCPT_DISABLE; *(AnsPtr + 22) = 0x00; *(AnsPtr + 23) = 0x06; memcpy((AnsPtr + 24), (Ptr + 24), 6); *(AnsPtr + 30) = contrlType; *(AnsPtr + 31) = udsDataLen; *(AnsPtr + 32) = 0x7F; *(AnsPtr + 33) = DIDBuffer >> 8; *(AnsPtr + 34) = DIDBuffer; *(AnsPtr + 36) = 0x31; *(AnsPtr + 37) = bcc_chk(AnsPtr, 37); return AnsLength; } void Fota_Ftp(uint8 *dataPtrIn) { static uint8 ftp_process = 0; char *ATCmdSend = NULL; sint8 recvRet = -1; char ATSendDataBuffer[100] = {0}; uint8 UartRecvBuffer[50]; uint16 ReadLen = 0; uint8 *retptr = NULL; // char temp[70]=",qx,qx900,120.27.243.131,21,0,0.0.1.5,0.0.1.5,/Debug/V0.0.1.5.bin,"; /*URL信息解析*/ char *databuffer[20]; char *accountPtr; char *passwordPtr; char *ftpServerIpPtr; char *ftpServerPort; char *filePathPtr; char *filenamePtr; char keyFilename[20] = {0}; char *p = NULL; p = strtok((char *)dataPtrIn, ","); uint8 index = 0; boolean ftp_EndFlg = false; while (p && index < 20) { databuffer[index] = p; p = strtok(NULL, ","); index++; } accountPtr = databuffer[0]; passwordPtr = databuffer[1]; ftpServerIpPtr = databuffer[2]; ftpServerPort = databuffer[3]; filePathPtr = databuffer[7]; for (sint8 i = strlen(filePathPtr); i--; i < 0) { if (*(filePathPtr + i) == '/') { *(filePathPtr + i) = 0; filenamePtr = filePathPtr + i + 1; break; } } memcpy(keyFilename, filenamePtr, mstrlen(filenamePtr) - 3); memcpy(&keyFilename[mstrlen(filenamePtr) - 3], "zl", strlen("zl")); while (!ftp_EndFlg) { vTaskDelay(pdMS_TO_TICKS(100)); switch (ftp_process) { case 0: // start { ATCmdSend = (char *)("AT+CFTPSSTART\r\n"); UART_Send_Data(UART_LPUART1, ATCmdSend, mstrlen(ATCmdSend), pdMS_TO_TICKS(100)); recvRet = AtcmdDelayRecvFunc(UART_LPUART1, (char *)("+CFTPSSTART: 0"), 2000); if (recvRet == 0) { ftp_process++; } else { DeviceErrNum = 10; ftp_EndFlg = 1; } break; } case 1: // login { memset(ATSendDataBuffer, 0x00, sizeof(ATSendDataBuffer)); sprintf(ATSendDataBuffer, "AT+FSDEL=*.*\r\n"); recvRet = UART_Query_Data(UART_LPUART1, UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), UartRecvBuffer, &ReadLen, pdMS_TO_TICKS(5000)); if(recvRet == E_OK) { memset(ATSendDataBuffer, 0x00, sizeof(ATSendDataBuffer)); sprintf(ATSendDataBuffer, "AT+CFTPSLOGIN=\"%s\",%s,\"%s\",\"%s\",0\r\n", ftpServerIpPtr, ftpServerPort, accountPtr, passwordPtr); UART_Send_Data(UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), pdMS_TO_TICKS(100)); recvRet = AtcmdDelayRecvFunc(UART_LPUART1, (char *)("+CFTPSLOGIN: 0"), 30000); if (recvRet == 0) { ftp_process++; } else { DeviceErrNum = 11; ftp_EndFlg = 1; } } else { DeviceErrNum = 9; ftp_EndFlg = 1; } break; } case 2: // transmit bin file from server to module { memset(ATSendDataBuffer, 0x00, sizeof(ATSendDataBuffer)); sprintf(ATSendDataBuffer, "AT+CFTPSGETFILE=\"%s/%s\"\r\n", filePathPtr, filenamePtr); UART_Send_Data(UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), pdMS_TO_TICKS(100)); recvRet = AtcmdDelayRecvFunc(UART_LPUART1, (char *)("+CFTPSGETFILE: 0"), 10000); if (recvRet == 0) { ftp_process++; } else { DeviceErrNum = 12; ftp_EndFlg = 1; } break; } case 3: // transmit zl file from server to module { memset(ATSendDataBuffer, 0x00, sizeof(ATSendDataBuffer)); sprintf(ATSendDataBuffer, "AT+CFTPSGETFILE=\"%s/%s\"\r\n", filePathPtr, keyFilename); UART_Send_Data(UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), pdMS_TO_TICKS(100)); recvRet = AtcmdDelayRecvFunc(UART_LPUART1, (char *)("+CFTPSGETFILE: 0"), 10000); if (recvRet == 0) { ftp_process++; } else { DeviceErrNum = 13; ftp_EndFlg = 1; } break; } case 4: // logout { ATCmdSend = (char *)("AT+CFTPSLOGOUT\r\n"); UART_Send_Data(UART_LPUART1, ATCmdSend, mstrlen(ATCmdSend), pdMS_TO_TICKS(100)); recvRet = AtcmdDelayRecvFunc(UART_LPUART1, (char *)("+CFTPSLOGOUT: 0"), 2000); if (recvRet == 0) { ftp_process++; } else { ftp_process++; } break; } case 5: // stop { ATCmdSend = (char *)("AT+CFTPSSTOP\r\n"); UART_Send_Data(UART_LPUART1, ATCmdSend, mstrlen(ATCmdSend), pdMS_TO_TICKS(100)); recvRet = AtcmdDelayRecvFunc(UART_LPUART1, (char *)("CFTPSSTOP: 0"), 2000); if (recvRet == 0) { ftp_process++; } else { ftp_process++; } break; } case 6: // get data from module { char findDataBuffer[25] = {0}; uint32 currentAddr = 0; uint16 readLenAsk = 256; uint16 FotaRecvDataLen_8 = 0; uint32 fileLen = 65535; uint32 FlashAddStart = 0; uint32 appReceviedCRC; uint16 getDataLenErrCount = 0; uint8 UartData[512] = {0}; uint8 FlashData[512] = {0}; uint8 *fileDataPtr = NULL; memset(ATSendDataBuffer, 0x00, sizeof(ATSendDataBuffer)); sprintf(ATSendDataBuffer, "AT+CFTRANTX=\"c:/%s\"\r\n", keyFilename); UART_Query_Data(UART_LPUART1, UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), UartRecvBuffer, &ReadLen, pdMS_TO_TICKS(5000)); if (ReadLen == (4 + 45)) { retptr = (uint8 *)strstr((char *)UartRecvBuffer, (char *)("+CFTRANTX: DATA")); if (retptr) { fileLen = (*(retptr + 21) << 24) | (*(retptr + 22) << 16) | (*(retptr + 23) << 8) | (*(retptr + 24) << 0); appReceviedCRC = (*(retptr + 19) << 8) | (*(retptr + 20) << 0); Hal_FlsGetAppVectorTableStartAddr(&FlashAddStart); Hal_OTAFlashAppInfoInit(); Hal_FlsErase(0, FlashAddStart + fileLen + FLS_INTERNAL_WRITE_SIZE, 100); Hal_SetAppInfo(fileLen, appReceviedCRC, CONTROLLER_SELF); while (readLenAsk != 0) { memset(UartData, 0x00, 512); memset(FlashData, 0x00, 512); memset(ATSendDataBuffer, 0x00, sizeof(ATSendDataBuffer)); sprintf(ATSendDataBuffer, "AT+CFTRANTX=\"c:/%s\",%d,%d\r\n", filenamePtr, currentAddr, readLenAsk); UART_Query_Data(UART_LPUART1, UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), UartData, &ReadLen, pdMS_TO_TICKS(5000)); sprintf(findDataBuffer, "+CFTRANTX: DATA,%d", readLenAsk); if (currentAddr % 0x100 == 0) { Dio_FlipChannel(LED_INDEX3); } if (ReadLen == (readLenAsk + strlen(findDataBuffer) + 26)) { retptr = (uint8 *)strstr((char *)UartData, findDataBuffer); if (retptr) { uint16 uartcrc = 0x00; uint16 flashcrc = 0xff; fileDataPtr = retptr + 2 + mstrlen(findDataBuffer); FotaRecvDataLen_8 = ((readLenAsk + 7) / 8) * 8; Hal_FlsWrite(FlashAddStart + currentAddr, fileDataPtr, FotaRecvDataLen_8, 100); Hal_FlsRead(FlashAddStart + currentAddr, FlashData, FotaRecvDataLen_8, 100); uartcrc = CRC16_Modbus(fileDataPtr, FotaRecvDataLen_8); flashcrc = CRC16_Modbus(FlashData, FotaRecvDataLen_8); if (flashcrc == uartcrc) { currentAddr = currentAddr + readLenAsk; getDataLenErrCount = 0; } else { uint32 secflash = (FlashAddStart + currentAddr) & 0xFFFFF000; if (secflash > 0) { currentAddr = secflash - FlashAddStart; } else { currentAddr = 0; } MemIf_JobResultType ret = Hal_FlsErase(secflash, 4096, 100); getDataLenErrCount++; } readLenAsk = min(fileLen - currentAddr, readLenAsk); } else { getDataLenErrCount++; } } else { getDataLenErrCount++; } if (getDataLenErrCount >= 100) { break; } } Dio_WriteChannel(LED_INDEX3, STD_ON); // switch off the led if (getDataLenErrCount < 50 && Hal_FlsCheckIsTransferSucceed() == TRUE) { ftp_process++; Fota_update_flag = 1; } else { ftp_process++; DeviceErrNum = 15; } } } else { ftp_process++; DeviceErrNum = 14; } break; } case 7: // delete the bin and zl files { memset(ATSendDataBuffer, 0x00, sizeof(ATSendDataBuffer)); sprintf(ATSendDataBuffer, "AT+FSDEL=*.*\r\n"); UART_Query_Data(UART_LPUART1, UART_LPUART1, ATSendDataBuffer, mstrlen(ATSendDataBuffer), UartRecvBuffer, &ReadLen, pdMS_TO_TICKS(5000)); ftp_process++; break; } default: ftp_EndFlg = 1; break; } } if (Fota_update_flag==0) { Fota_error_flag = 1; } }