/* * @Author: chenjie * @Date: 2022-06-06 * @LastEditTime: 2022-10-27 * @LastEditors: chenjie * @Description: * @FilePath: \S32K146_4G\code\app\AppTaskUart1.c * Copyright (c) 2022 by chenjie, All Rights Reserved. */ #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=0,\"TCP\",\"120.26.68.165\",14319\r\n", 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_IDLE; #define PROC_TCP_STATE_SWITCH(a) (gProcess_Tcp_Task = a) void InitFunc(void); sint8 TcpConnectFunc(sint8 *ConnectId); sint8 TcpDataSendFunc(sint8 ConnectId); sint8 TcpRegisterChkFunc(void); void TcpDataEncode(uint32 *PtrSendAddr, uint16 *SendLen); void GetUtc8Time(UTC8TimeType *UTC8TimeTcp); 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); void tcpUdsFunc(uint8 *Ptr,uint8 *AnsPtr); static void vTimer1000msCallback(TimerHandle_t pxTimer); bool SendTimerFlg = false; static uint32 TcpSendTimeCounter = 0; void Uart_4G_Task(void *pvParameters) { (void)pvParameters; uint32 RecvTimerDelay = 0; uint8 UartRecvPtr[512]; volatile uint16 tcpErrorCounter = 0; uint16 pReadLen = 0; // 4G开机 Dio_LevelType _4G_Status = 0; // 0-关机,1-开机 Dio_WriteChannel(DioConf_DioChannel_PTA6_GPIO_OUT_MCU_4G_POW_EN, STD_ON); vTaskDelay(pdMS_TO_TICKS(50)); Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_ON); vTaskDelay(pdMS_TO_TICKS(50)); AtcmdDelayRecvFunc(UART_LPUART1,(char *)("SMS DONE"),30000); Dio_WriteChannel(DioConf_DioChannel_PTA7_GPIO_OUT_MCU_4G_PWRKEY, STD_OFF); _4G_Status = Dio_ReadChannel(DioConf_DioChannel_PTB1_GPIO_IN_MCU_4G_STATUS); InitFunc(); // 4G模块初始化,注:AT同步不通过,没有进行次数判定及跳转 TimerHandle_t monitorTimer1000ms; monitorTimer1000ms = xTimerCreate("monitor1000ms",1000,pdTRUE,(void *)0,vTimer1000msCallback); xTimerStart(monitorTimer1000ms,0); for (;;) { switch (gProcess_Tcp_Task) { case PROCESS_TCP_IDLE: //空闲状态 { UART_Receive_Data(UART_LPUART1, 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 && SendTimerFlg==true) { SendTimerFlg = false; PROC_TCP_STATE_SWITCH(PROCESS_TCP_SEND); } if((TimerCounter-RecvTimerDelay)>=30000 && TcpWorkState==1)//10s内没有命令下发,进行正常发送任务 { TcpWorkState = 0; } break; } case PROCESS_TCP_ATSYS: { sint8 ATRet = -1; AtcmdTransmit(AT_CMD_TEST, NULL, 0, &ATRet,100); if (ATRet == 0) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE); } else { PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR); } 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; SendRet = TcpDataSendFunc(SocketId); if (SendRet == 0) { PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE); tcpErrorCounter = 0; } else { SocketId = -1; PROC_TCP_STATE_SWITCH(PROCESS_TCP_ERROR); } break; } case PROCESS_TCP_RECV: //网络数据接收,100ms空闲状态下即可接收 { Dio_FlipChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1); 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: //网络休眠状态 { break; } case PROCESS_TCP_ERROR: //错误状态 { vTaskDelay(pdMS_TO_TICKS(1000)); tcpErrorCounter++; if(tcpErrorCounter>60&&TcpSysReboot == 1)//无法驻网或者联网 { 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; } PROC_TCP_STATE_SWITCH(PROCESS_TCP_IDLE); break; } } } } static void vTimer1000msCallback(TimerHandle_t pxTimer) { uint32 ulTimerID; ulTimerID = (uint32)pvTimerGetTimerID(pxTimer); if(ulTimerID==0) { SendTimerFlg = true; TcpSendTimeCounter++; } } sint8 TcpDataSendFunc(sint8 ConnectId) { sint8 outValue = -1; uint32 pSendDataAddr = 0; uint16 DataSendLen = 0; TcpDataEncode(&pSendDataAddr, &DataSendLen); //数据组包,malloc申请在里面,pSendData指向申请的地址 if (DataSendLen == 0) { return 0; //暂时无数据可以发 } 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, 1000); sint8 ret = AtcmdDelayRecvFunc(UART_LPUART1,(char *)("+CIPSEND"),2000); if (ret==0) { outValue = 0; } else { outValue = -2; sendErrConuter++; } } else { outValue = -1; sendErrConuter++; } } return outValue; } sint8 TcpConnectFunc(sint8 *ConnectId) { uint8 ConnectStep = 0; sint8 ChkState = 0; sint8 ATRet = -1; uint8 UartRecvPtr[100]; while (1) { switch (ConnectStep) { case 0: // 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 1: // Netopen { AtcmdTransmit(AT_NETOPEN, NULL, 0, &ATRet,100); if (ATRet == 0) { ConnectStep++; } else { ChkState = -ConnectStep; return ChkState; } break; } case 2: //连接检查 { AtcmdTransmit(AT_CONNECTCHK, NULL, 0, &ATRet,1000); // ATret返回的值是连接id,如果未连接返回-1 if (ATRet >= 0) { *ConnectId = ATRet; return 2; } else { ConnectStep++; } break; } case 3: //域名转换 { 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 4: //创建连接 { 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 = 14401; /**/ 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; } } } void 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; 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) { SystemSoftwareReset(); } } 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; break; } } } } 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(uint32 *PtrSendAddr, uint16 *SendLen) { static UTC8TimeType UTC8TimeTcp; uint8 *SendBuffer = NULL; uint8 DataIdx = 0; if (TcpSendTimeCounter == 5) { DataIdx = VerMsg; //版本信息发送 } else if (TcpSendTimeCounter % 10 == 1) { DataIdx = BattMsg; //电池信息发送 } else if ((TcpSendTimeCounter) % 10 == 2) { DataIdx = 0x83; //储能开关信息发送 } else if ((TcpSendTimeCounter) % 240 == 3) { DataIdx = GpsMsg; //定位信息发送 } else if ((TcpSendTimeCounter) % 240 == 4) { DataIdx = 0x93; //储能电量信息发送 } else if ((TcpSendTimeCounter) % 60 == 5) { DataIdx = 0x8A; //累计信息发送 } // else if ((TcpSendTimeCounter) % (60*60*2) == 6) // { // DataIdx = 0x01; //时间校准 // } //暂时不进行时间校准,测试时间准确 else { *SendLen = 0; DataIdx = 0; //不发送,返回 return; } memcpy(TcpbattSN, AppConfigInfo.deviceSn, 17); GetUtc8Time(&UTC8TimeTcp); //时间获取 vTaskDelay(pdMS_TO_TICKS(100)); 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)); *SendLen = 0;//不发送,长度为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] = bmsHwVersion>>8; VerMsgToTcpInfo.VerInfo.BMSHwVersion[1] = bmsHwVersion; VerMsgToTcpInfo.VerInfo.BMSSwVersion[0] = bmsSwVersion>>24; VerMsgToTcpInfo.VerInfo.BMSSwVersion[1] = bmsSwVersion>>16; VerMsgToTcpInfo.VerInfo.BMSSwVersion[2] = bmsSwVersion>>8; VerMsgToTcpInfo.VerInfo.BMSSwVersion[3] = bmsSwVersion; 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 0x80: { uint16 ErrorTemp; ErrorTemp = GetErrorNum(ErrorArray,sizeof(ErrorArray)/2); uint8 ProtocolHeaderLen = 25; //电池信息协议头部加校验码长度,此长度不更改 uint8 ProtocolFixedLen = 60; //电池信息协议固定总长度 如协议新增,需要更改此长度 uint16 ProtocolFluctedLen = AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount + BmsOtherTemp + OtherTemp; //电池信息协议变动长度 uint16 DataLen; *SendLen = ProtocolFixedLen + ProtocolFluctedLen; SendBuffer = pvPortMalloc(*SendLen); GetCSQValue(&CSQValue); *(SendBuffer + 0) = TCP_START_SYM1; //起始码-1 *(SendBuffer + 1) = TCP_START_SYM2; //起始码-2 *(SendBuffer + 2) = TCP_CMD_SYM; //命令标识-3 *(SendBuffer + 3) = TCP_ANS_SYM; //应答标识-4 memcpy(SendBuffer + 4, TcpbattSN, BATT_SN_LEN); // SN码 5-21 *(SendBuffer + 21) = TCP_ENCPT_DISABLE; //加密方式-22 DataLen = ProtocolFixedLen + ProtocolFluctedLen - ProtocolHeaderLen; //电池信息单元协议固定长度 *(SendBuffer + 22) = (DataLen >> 8) & 0xFF; //数据长度H-23 *(SendBuffer + 23) = DataLen & 0xFF; //数据长度L-24 *(SendBuffer + 24) = (UTC8TimeTcp.year) & 0xFF; // year-25 *(SendBuffer + 25) = UTC8TimeTcp.month & 0xFF; // month-26 *(SendBuffer + 26) = UTC8TimeTcp.day & 0xFF; // day-27 *(SendBuffer + 27) = UTC8TimeTcp.hour & 0xFF; // hour-28 *(SendBuffer + 28) = UTC8TimeTcp.minute & 0xFF; // mins-29 *(SendBuffer + 29) = UTC8TimeTcp.second & 0xFF; // sec-30 *(SendBuffer + 30) = DataIdx; //电池信息发送-31 *(SendBuffer + 31) = (UTC8TimeTcp.year) & 0xFF; // year-32 *(SendBuffer + 32) = UTC8TimeTcp.month & 0xFF; // month-33 *(SendBuffer + 33) = UTC8TimeTcp.day & 0xFF; // day-34 *(SendBuffer + 34) = UTC8TimeTcp.hour & 0xFF; // hour-35 *(SendBuffer + 35) = UTC8TimeTcp.minute & 0xFF; // mins-36 *(SendBuffer + 36) = UTC8TimeTcp.second & 0xFF; // sec-37 *(SendBuffer + 37) = CSQValue; //信号强度-38 *(SendBuffer + 38) = 0; //故障等级-39 *(SendBuffer + 39) = ErrorTemp >> 8; //故障代码H-40 *(SendBuffer + 40) = ErrorTemp & 0xFF; //故障代码L-41 *(SendBuffer + 41) = battI >> 8; //电流-42 *(SendBuffer + 42) = battI & 0xFF; //电流-43 *(SendBuffer + 43) = battPackVol >> 8; //电压-44 *(SendBuffer + 44) = battPackVol & 0xFF; //电压-45 *(SendBuffer + 45) = battPackVol >> 8; //电压-46 *(SendBuffer + 46) = battPackVol & 0xFF; //电压-47 *(SendBuffer + 47) = battMOSSwitchState; // mos状态-48 *(SendBuffer + 48) = (uint8)(battSOC); // soc-49 *(SendBuffer + 49) = (uint8)(battSOH); // soh-50 *(SendBuffer + 50) = (battBalanceoInfo >> 24) & 0xFF; *(SendBuffer + 51) = (battBalanceoInfo >> 16) & 0xFF; *(SendBuffer + 52) = (battBalanceoInfo >> 8) & 0xFF; *(SendBuffer + 53) = battBalanceoInfo & 0xFF; //均衡状态-51-54 *(SendBuffer + 54) = AppDataInfo.BattCellCount; //电压个数-55 for (uint8 i = 0; i < AppDataInfo.BattCellCount; i++) //单体电压 { *(SendBuffer + 54 + i * 2 + 1) = (battCellU[i] >> 8) & 0xFF; *(SendBuffer + 54 + i * 2 + 2) = battCellU[i] & 0xFF; } *(SendBuffer + 55 + AppDataInfo.BattCellCount * 2) = AppDataInfo.BattTempCount; //模组温度个数 memcpy((SendBuffer + 55 + AppDataInfo.BattCellCount * 2 + 1), &battCellTemp, AppDataInfo.BattTempCount); //模组温度 *(SendBuffer + 56 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount) = battWorkState; //电池工作状态 *(SendBuffer + 57 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount) = battHeatEnableState; //电池加热使能状态 *(SendBuffer + 58 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount) = BmsOtherTemp + OtherTemp; //其他温度个数 // *(SendBuffer + 58 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount + 1) = MOSTemp; // mos温度 // *(SendBuffer + 58 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount + 2) = packTemp; //环境温度 // *(SendBuffer + 58 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount + 3) = fastChargeTemp; //快充温度 // *(SendBuffer + 58 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount + 4) = normalChargeTemp; //慢充温度 // *(SendBuffer + 58 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount + 5) = heatTemp1; //加热温度1 // *(SendBuffer + 58 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount + 6) = heatTemp2; //加热温度2 *(SendBuffer + 59 + AppDataInfo.BattCellCount * 2 + AppDataInfo.BattTempCount + BmsOtherTemp + OtherTemp) = bcc_chk(SendBuffer, ProtocolFixedLen + ProtocolFluctedLen - 1); //校验码 *PtrSendAddr = (uint32)SendBuffer; break; } case 0x83://储能场景的开关信息 { StorageInfoToTcp StorageInfo; *SendLen = sizeof(StorageInfo); SendBuffer = pvPortMalloc(*SendLen); uint16 DataLen = 0; DataLen = (uint16)sizeof(StorageInfo.StorageMsg); StorageInfo.startSymbol[0] = TCP_START_SYM1; StorageInfo.startSymbol[1] = TCP_START_SYM2; StorageInfo.cmdSymbol = TCP_CMD_SYM; StorageInfo.ansSymbol = TCP_ANS_SYM; memcpy(StorageInfo.SN, TcpbattSN, BATT_SN_LEN); StorageInfo.encryptMethod = TCP_ENCPT_DISABLE; // not encrypt StorageInfo.dataLength[0] = (DataLen >> 8) & 0xFF; StorageInfo.dataLength[1] = DataLen & 0xFF; StorageInfo.StorageMsg.sendTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year StorageInfo.StorageMsg.sendTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month StorageInfo.StorageMsg.sendTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day StorageInfo.StorageMsg.sendTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour StorageInfo.StorageMsg.sendTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins StorageInfo.StorageMsg.sendTimeUTC[5] = UTC8TimeTcp.second & 0xFF; // sec StorageInfo.StorageMsg.msgMark = DataIdx; StorageInfo.StorageMsg.msgCollectionTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year StorageInfo.StorageMsg.msgCollectionTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month StorageInfo.StorageMsg.msgCollectionTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day StorageInfo.StorageMsg.msgCollectionTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour StorageInfo.StorageMsg.msgCollectionTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins StorageInfo.StorageMsg.msgCollectionTimeUTC[5] = UTC8TimeTcp.second & 0xFF; StorageInfo.StorageMsg.RelayState = battRelayState; StorageInfo.StorageMsg.FanState = battFanState; StorageInfo.StorageMsg.HeatState = battHeatState; StorageInfo.StorageMsg.ConvertState = battConverState; StorageInfo.CRC = bcc_chk((uint8 *)&StorageInfo, sizeof(StorageInfo) - 1); memcpy(SendBuffer, &StorageInfo, sizeof(StorageInfo)); *PtrSendAddr = (uint32)SendBuffer; break; } case 0x93://储能场景的电量信息 { StorageInfoToTcp2 StorageInfo2; *SendLen = sizeof(StorageInfo2); SendBuffer = pvPortMalloc(*SendLen); uint16 DataLen = 0; DataLen = (uint16)sizeof(StorageInfo2.StorageMsg2); StorageInfo2.startSymbol[0] = TCP_START_SYM1; StorageInfo2.startSymbol[1] = TCP_START_SYM2; StorageInfo2.cmdSymbol = TCP_CMD_SYM; StorageInfo2.ansSymbol = TCP_ANS_SYM; memcpy(StorageInfo2.SN, TcpbattSN, BATT_SN_LEN); StorageInfo2.encryptMethod = TCP_ENCPT_DISABLE; // not encrypt StorageInfo2.dataLength[0] = (DataLen >> 8) & 0xFF; StorageInfo2.dataLength[1] = DataLen & 0xFF; StorageInfo2.StorageMsg2.sendTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year StorageInfo2.StorageMsg2.sendTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month StorageInfo2.StorageMsg2.sendTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day StorageInfo2.StorageMsg2.sendTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour StorageInfo2.StorageMsg2.sendTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins StorageInfo2.StorageMsg2.sendTimeUTC[5] = UTC8TimeTcp.second & 0xFF; // sec StorageInfo2.StorageMsg2.msgMark = DataIdx; StorageInfo2.StorageMsg2.msgCollectionTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year StorageInfo2.StorageMsg2.msgCollectionTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month StorageInfo2.StorageMsg2.msgCollectionTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day StorageInfo2.StorageMsg2.msgCollectionTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour StorageInfo2.StorageMsg2.msgCollectionTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins StorageInfo2.StorageMsg2.msgCollectionTimeUTC[5] = UTC8TimeTcp.second & 0xFF; StorageInfo2.StorageMsg2.meter1AllPwr[0] = meterAllPwr[0]>>24; StorageInfo2.StorageMsg2.meter1AllPwr[1] = meterAllPwr[0]>>16; StorageInfo2.StorageMsg2.meter1AllPwr[2] = meterAllPwr[0]>>8; StorageInfo2.StorageMsg2.meter1AllPwr[3] = meterAllPwr[0]>>0; StorageInfo2.StorageMsg2.meter1PosPwr[0] = meterPosPwr[0]>>24; StorageInfo2.StorageMsg2.meter1PosPwr[1] = meterPosPwr[0]>>16; StorageInfo2.StorageMsg2.meter1PosPwr[2] = meterPosPwr[0]>>8; StorageInfo2.StorageMsg2.meter1PosPwr[3] = meterPosPwr[0]>>0; StorageInfo2.StorageMsg2.meter1NegPwr[0] = meterNegPwr[0]>>24; StorageInfo2.StorageMsg2.meter1NegPwr[1] = meterNegPwr[0]>>16; StorageInfo2.StorageMsg2.meter1NegPwr[2] = meterNegPwr[0]>>8; StorageInfo2.StorageMsg2.meter1NegPwr[3] = meterNegPwr[0]>>0; StorageInfo2.StorageMsg2.meter2AllPwr[0] = meterAllPwr[1]>>24; StorageInfo2.StorageMsg2.meter2AllPwr[1] = meterAllPwr[1]>>16; StorageInfo2.StorageMsg2.meter2AllPwr[2] = meterAllPwr[1]>>8; StorageInfo2.StorageMsg2.meter2AllPwr[3] = meterAllPwr[1]>>0; StorageInfo2.StorageMsg2.meter2PosPwr[0] = meterPosPwr[1]>>24; StorageInfo2.StorageMsg2.meter2PosPwr[1] = meterPosPwr[1]>>16; StorageInfo2.StorageMsg2.meter2PosPwr[2] = meterPosPwr[1]>>8; StorageInfo2.StorageMsg2.meter2PosPwr[3] = meterPosPwr[1]>>0; StorageInfo2.StorageMsg2.meter2NegPwr[0] = meterNegPwr[1]>>24; StorageInfo2.StorageMsg2.meter2NegPwr[1] = meterNegPwr[1]>>16; StorageInfo2.StorageMsg2.meter2NegPwr[2] = meterNegPwr[1]>>8; StorageInfo2.StorageMsg2.meter2NegPwr[3] = meterNegPwr[1]>>0; StorageInfo2.CRC = bcc_chk((uint8 *)&StorageInfo2, sizeof(StorageInfo2) - 1); memcpy(SendBuffer, &StorageInfo2, sizeof(StorageInfo2)); *PtrSendAddr = (uint32)SendBuffer; break; } case 0x8A: { uint32 temp = 0; AccInfoToTcp AccInfoToTcpMsg; *SendLen = sizeof(AccInfoToTcpMsg); SendBuffer = pvPortMalloc(*SendLen); uint16 DataLen = 0; DataLen = (uint16)sizeof(AccInfoToTcpMsg.AccMsg); AccInfoToTcpMsg.startSymbol[0] = TCP_START_SYM1; AccInfoToTcpMsg.startSymbol[1] = TCP_START_SYM2; AccInfoToTcpMsg.cmdSymbol = TCP_CMD_SYM; AccInfoToTcpMsg.ansSymbol = TCP_ANS_SYM; memcpy(AccInfoToTcpMsg.SN, TcpbattSN, BATT_SN_LEN); AccInfoToTcpMsg.encryptMethod = TCP_ENCPT_DISABLE; // not encrypt AccInfoToTcpMsg.dataLength[0] = (DataLen >> 8) & 0xFF; AccInfoToTcpMsg.dataLength[1] = DataLen & 0xFF; AccInfoToTcpMsg.AccMsg.sendTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year AccInfoToTcpMsg.AccMsg.sendTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month AccInfoToTcpMsg.AccMsg.sendTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day AccInfoToTcpMsg.AccMsg.sendTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour AccInfoToTcpMsg.AccMsg.sendTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins AccInfoToTcpMsg.AccMsg.sendTimeUTC[5] = UTC8TimeTcp.second & 0xFF; // sec AccInfoToTcpMsg.AccMsg.msgMark = DataIdx; AccInfoToTcpMsg.AccMsg.msgCollectionTimeUTC[0] = (UTC8TimeTcp.year) & 0xFF; // year AccInfoToTcpMsg.AccMsg.msgCollectionTimeUTC[1] = UTC8TimeTcp.month & 0xFF; // month AccInfoToTcpMsg.AccMsg.msgCollectionTimeUTC[2] = UTC8TimeTcp.day & 0xFF; // day AccInfoToTcpMsg.AccMsg.msgCollectionTimeUTC[3] = UTC8TimeTcp.hour & 0xFF; // hour AccInfoToTcpMsg.AccMsg.msgCollectionTimeUTC[4] = UTC8TimeTcp.minute & 0xFF; // mins AccInfoToTcpMsg.AccMsg.msgCollectionTimeUTC[5] = UTC8TimeTcp.second & 0xFF; AccInfoToTcpMsg.AccMsg.accOnlineDays[0] = 0; AccInfoToTcpMsg.AccMsg.accOnlineDays[1] = 0; AccInfoToTcpMsg.AccMsg.accDrvMiles[0] = 0; AccInfoToTcpMsg.AccMsg.accDrvMiles[1] = 0; AccInfoToTcpMsg.AccMsg.sohNoCalibrTime[0] = 0; AccInfoToTcpMsg.AccMsg.sohNoCalibrTime[1] = 0; temp = AppConfigInfo.AppDataInfo.battChrgAccEnrg/1000; AccInfoToTcpMsg.AccMsg.accChrgEng[0] = temp>>24; AccInfoToTcpMsg.AccMsg.accChrgEng[1] = temp>>16; AccInfoToTcpMsg.AccMsg.accChrgEng[2] = temp>>8; AccInfoToTcpMsg.AccMsg.accChrgEng[3] = temp; temp = AppConfigInfo.AppDataInfo.battDischrgAccEnrg/1000; AccInfoToTcpMsg.AccMsg.accDischrgEng[0] = temp>>24; AccInfoToTcpMsg.AccMsg.accDischrgEng[1] = temp>>16; AccInfoToTcpMsg.AccMsg.accDischrgEng[2] = temp>>8; AccInfoToTcpMsg.AccMsg.accDischrgEng[3] = temp>>0; AccInfoToTcpMsg.AccMsg.accChrgCap[0] = 0; AccInfoToTcpMsg.AccMsg.accChrgCap[1] = 0; AccInfoToTcpMsg.AccMsg.accChrgCap[2] = 0; AccInfoToTcpMsg.AccMsg.accChrgCap[3] = 0; temp = AppConfigInfo.AppDataInfo.battDischrgAccCap/1000; AccInfoToTcpMsg.AccMsg.accDischrgCap[0] = temp>>24; AccInfoToTcpMsg.AccMsg.accDischrgCap[1] = temp>>16; AccInfoToTcpMsg.AccMsg.accDischrgCap[2] = temp>>8; AccInfoToTcpMsg.AccMsg.accDischrgCap[3] = temp; AccInfoToTcpMsg.AccMsg.accOverChrgTimes= 0; AccInfoToTcpMsg.AccMsg.accOverDischrgTimes = 0; AccInfoToTcpMsg.AccMsg.accCycleTimes[0] = AppConfigInfo.AppDataInfo.battCycleTimes>>8; AccInfoToTcpMsg.AccMsg.accCycleTimes[1] = AppConfigInfo.AppDataInfo.battCycleTimes; AccInfoToTcpMsg.CRC = bcc_chk((uint8 *)&AccInfoToTcpMsg, sizeof(AccInfoToTcpMsg) - 1); memcpy(SendBuffer, &AccInfoToTcpMsg, sizeof(AccInfoToTcpMsg)); *PtrSendAddr = (uint32)SendBuffer; break; } default: break; } } void GetUtc8Time(UTC8TimeType *UTC8TimeTcp) { char *AtCmdAsk = (char *)("AT+CCLK?\r\n"); uint8 AtCmdLen = mstrlen(AtCmdAsk); uint16 ReadLen = 0; uint8 *retptr = NULL; uint8 UartRecvPtr[128]; 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 *)("+CCLK:")); if(retptr) { UTC8TimeTcp->year = CharToHex(*(retptr + 8)) * 10 + CharToHex(*(retptr + 9)); UTC8TimeTcp->month = CharToHex(*(retptr + 11)) * 10 + CharToHex(*(retptr + 12)); UTC8TimeTcp->day = CharToHex(*(retptr + 14)) * 10 + CharToHex(*(retptr + 15)); UTC8TimeTcp->hour = CharToHex(*(retptr + 17)) * 10 + CharToHex(*(retptr + 18)); UTC8TimeTcp->minute = CharToHex(*(retptr + 20)) * 10 + CharToHex(*(retptr + 21)); UTC8TimeTcp->second = CharToHex(*(retptr + 23)) * 10 + CharToHex(*(retptr + 24)); } } } } 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]; UART_Query_Data(UART_LPUART1, UART_LPUART1, (uint8 *)AtCmdAsk, AtCmdLen, UartRecvPtr, &ReadLen, pdMS_TO_TICKS(100)); *out = 99; if (ReadLen > 0) { if ((uint8 *)strstr((char *)UartRecvPtr, (char *)("OK"))) { *out = 0; 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); } *out = atoi(CsqStr); } } 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); vTaskDelay(pdMS_TO_TICKS(5000)); Fota_Ftp(Ptr + 32); } 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; tcpUdsFunc(Ptr,TcpCmdAnswer); // tcpipConnectionSend(SocketId, TcpCmdAnswer, 30); break; } default: { break; } } } } } void tcpUdsFunc(uint8 *Ptr,uint8 *AnsPtr) { uint8 contrlType = 0; uint16 udsDataLen = 0; uint16 DIDBuffer = 0; uint8 udsType_SID = 0; uint8 DataBuffer[10]; contrlType = *(Ptr + 30); udsDataLen = *(Ptr + 31); udsType_SID = *(Ptr + 32); DIDBuffer = *(Ptr + 33)<<8|*(Ptr + 34); memcpy(DataBuffer,Ptr + 35,udsDataLen); switch(contrlType) { case 0x00: { 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; break; } default: 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); } /***************************************************************************************/ 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; uint8 ftp_EndFlg = 0; 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 { ftp_EndFlg=1; } break; } case 1://login { 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 { ftp_EndFlg=1; } break; } case 2://transmit bin file from server to module { uint8 *UartData = NULL; 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 { 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 { 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 (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; } } if(getDataLenErrCount<50&&Hal_FlsCheckIsTransferSucceed()==TRUE) { ftp_process++; } else { ftp_EndFlg = 1; } } } else { ftp_EndFlg = 1; } 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++; Fota_update_flag = TRUE; break; } default: ftp_EndFlg = 1; break; } } if(ftp_process<6) { Fota_error_flag = 1; } }