/* * @Author : ChenJie * @Date : 2022-01-21 09:28:20 * @Version : V3.0 * @LastEditors : ChenJie * @LastEditTime : 2022-02-14 15:23:30 * @Description : file content * @FilePath : \S32K146_4G\src\AppFuncLib.c */ /* * AppFuncLib.c *应用层函数库 * Created on: 2022年1月21日 * Author: QiXiang_CHENJIE */ #include "AppFuncLib.h" #include "AppGlobalVar.h" #include "Hal_Fls.h" #include "AppTaskUart1.h" /** * @brief : 获取故障码函数,从故障数组中获取故障码,并将之前的故障码向前移动 * @param {UINT16} *ErrorArray * @param {UINT8} Errorlen * @return {*} */ static uint8 bcc_chk_fota(uint8 *data, uint8 length); static uint8 Fota_crc_chk(uint8 *data, uint8 length); uint16 GetErrorNum(uint16 *ErrorArray, uint8 Errorlen) { uint16 OutNum; OutNum = *(ErrorArray); for (uint8 i = 0; i < Errorlen - 1; i++) { *(ErrorArray + i) = *(ErrorArray + i + 1); if (*(ErrorArray + i + 1) == 0) break; } return OutNum; } uint8 PutErrorNum(uint16 *ErrorArray, uint8 Errorlen, uint16 ErrorNum) { for (uint8 i = 0; i < Errorlen; i++) { if (*(ErrorArray + i) == 0) { *(ErrorArray + i) = ErrorNum; return 0; } else { if (*(ErrorArray + i) == ErrorNum) { return 1; } else { continue; } } } return 2; } uint16 ATstrdel(char *str) { char *p = str; bool flag = false; while (*str) { if (*str > 0x20) { *(p) = *str; p = p + 1; flag = false; } else { if (!flag) { *(p) = ','; p = p + 1; flag = true; } } str++; } *p = '\0'; return 0; } uint16 mstrlen(const char *s) { uint16 out = 0; const char *ss = s; while (*ss) ss++; out = (ss - s); return out; } int mstrncmp(const char *s1, const char *s2, int n) { const unsigned char *c1 = (const unsigned char *)s1; const unsigned char *c2 = (const unsigned char *)s2; unsigned char ch; int d = 0; while (n--) { d = (int)(ch = *c1++) - (int)*c2++; if (d || !ch) break; } return d; } unsigned char HexToChar(unsigned char bHex) { if ((bHex >= 0) && (bHex <= 9)) bHex += 0x30; else if ((bHex >= 10) && (bHex <= 15)) //大写字母 bHex += 0x37; else bHex = 0xff; return bHex; } unsigned char CharToHex(unsigned char bChar) { if ((bChar >= 0x30) && (bChar <= 0x39)) bChar -= 0x30; else if ((bChar >= 0x41) && (bChar <= 0x46)) //大写字母 bChar -= 0x37; else if ((bChar >= 0x61) && (bChar <= 0x66)) //小写字母 bChar -= 0x57; else bChar = 0xff; return bChar; } uint8 AtStrCompare(const char *a, const char *b) { uint8 out = 1; while (1) { if (*a == '\0' || *b == '\0') //判断其中是否有字符串结束 { if (strlen(a) == strlen(b)) { out = 1; break; } else { out = 0; break; } } else { if (*a != *b) { out = 0; break; } else if (*a == '=' && *b == '=') { out = 1; break; } } a++; b++; } return out; } unsigned short CRC16_Modbus(unsigned char *pdata, int len) { unsigned short crc = 0xFFFF; int i, j; for (j = 0; j < len; j++) { crc = crc ^ pdata[j]; for (i = 0; i < 8; i++) { if ((crc & 0x0001) > 0) { crc = crc >> 1; crc = crc ^ 0xa001; } else crc = crc >> 1; } } return crc; } char *Myitoa(int value, char *result, int base) { // check that the base if valid if (base < 2 || base > 36) { *result = '\0'; return result; } char *ptr = result, *ptr1 = result, tmp_char; int tmp_value; do { tmp_value = value; value /= base; *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; } while (value); // Apply negative sign if (tmp_value < 0) *ptr++ = '-'; *ptr-- = '\0'; while (ptr1 < ptr) { tmp_char = *ptr; *ptr-- = *ptr1; *ptr1++ = tmp_char; } return result; } /************************************************************************ * @brief 整数转字符串 * @param[in] num 整数 * @param[out] buf 字符串 * @return 返回字符串长度 ************************************************************************/ inline int _itoa(int num, char buf[32]) { return _i2a(num, buf, 10); } /************************************************************************ * @brief 整数转字符串 * @param[in] num 整数 * @param[out] buf 字符串 * @param[in] radix 进位制整数 * @return 返回字符串长度 ************************************************************************/ int _i2a(int num, char buf[32], int radix) { static const char s[] = "0123456789abcdef"; int n = num, R = radix; char *dst = buf; if (n < 0) { *dst++ = '-'; n = -n; } if (n < 10) { *dst++ = s[n]; *dst = 0; } else { char tmp[32], *p = tmp; while (n) { *p++ = s[n % R]; n /= R; } while (--p != tmp) *dst++ = *p; *dst++ = *tmp; *dst = 0; } return dst - buf; } /************************************************************************ * @brief 浮点数转字符串 * @param[in] val 浮点数 * @param[out] buf 字符串 * @param[in] eps 精度(小数位) * @return 返回字符串长度 ************************************************************************/ int _ftoa(double val, char buf[32], int eps) { double f = val; char *p = buf; if (val < 0) { *p++ = '-'; f = -f; } int n = f; int len = _itoa(n, p); return len + __ftoa(f - n, p + len, eps); } /************************************************************************ * @brief 浮点数转字符串:范围(-1, 1) * @param[in] val 浮点数 * @param[out] buf 字符串 * @param[in] eps 精度(小数位) * @return 返回字符串长度 ************************************************************************/ int __ftoa(double val, char buf[32], int eps) { double f = val; char *p = buf; static const char s[] = "0123456789"; if (f < 0) { *p++ = '-'; f = -f; } *p++ = '.'; for (int i = eps + 1, n; --i; ++p, f -= n) *p = s[n = f *= 10.0]; *p = 0; return p - buf; } /************************************************************************ * @brief 替换sprintf * @ref 可变长参数列表误区与陷阱——va_arg不可接受的类型 * http://www.cppblog.com/ownwaterloo/archive/2009/04/21/80655.aspx ************************************************************************/ int _sprintf(char *dst, const char *format, ...) { char *s = dst; const char *f = format; va_list ap, another; va_start(ap, format); va_copy(another, ap); while (*f) { int n = 1; if ('%' != *f) { *s = *f; } else { ++f; switch (*f) { case 's': // 字符串 { const char *p = va_arg(ap, char *); n = strlen(p); memcpy(s, p, n); } break; case 'd': case 'u': // 整数 { char buf[32]; n = _itoa(va_arg(ap, int), buf); memcpy(s, buf, n); } break; case 'f': // 浮点数 { char buf[32]; n = _ftoa(va_arg(ap, double), buf, 6); memcpy(s, buf, n); } break; case 'x': // 16进制数 { char buf[32]; n = _i2a(va_arg(ap, int), buf, 16); memcpy(s, buf, n); } break; case 'c': // 字符 { *s = va_arg(ap, int); } break; case '%': // 百分号 { *s = '%'; } break; default: { va_end(ap); int x = vsprintf(dst, format, another); va_end(another); return x; } break; } } ++f; s += n; } *s = 0; va_end(ap); return s - dst; } uint8 bcc_chk(uint8 *data, uint16 length) { uint8 bcc_chk_return = 0x00; uint16 count = 0; while (count < length) { bcc_chk_return ^= data[count]; count++; } return bcc_chk_return; } uint16 crc_chk(uint8 *data, uint8 length) { uint8 j; uint16 reg_crc = 0xFFFF; while (length--) { reg_crc ^= *data++; for (j = 0; j < 8; j++) { if (reg_crc & 0x01) { reg_crc = (reg_crc >> 1) ^ 0xA001; } else { reg_crc = reg_crc >> 1; } } } return reg_crc; } /** * @brief : Fota升级处理函数,将接收的数据进行校验,搬运至升级区域,并进行应答 * @param {UINT8} *DataPtr * @param {INT32} connectId * @return {*} */ void Fota_Func(uint8 *DataPtr, sint32 connectId) { Fota_Type Fota_S; uint8 Fota_Answer[43]; uint8 Fota_Cmd; sint8 ret; uint8 *Data_Read_Buffer = NULL; uint8 Data_Read_Crc; if (*(DataPtr + 30) == 0x01) { uint32 FlashAddStart = 0; uint32 appReceviedCRC; Hal_FlsGetAppVectorTableStartAddr(&FlashAddStart); Fota_S.Fota_Flash_Addres = FlashAddStart; Fota_Cmd = *(DataPtr + 31); Fota_Answer[0] = TCP_START_SYM1; Fota_Answer[1] = TCP_START_SYM2; Fota_Answer[2] = TCP_CONCMD_SYM; switch (Fota_Cmd) { case 0x01: { Fota_S.Fota_All_Data_Len = *(DataPtr + 33) << 24 | *(DataPtr + 34) << 16 | *(DataPtr + 35) << 8 | *(DataPtr + 36); Fota_S.Fota_Current_Addres = *(DataPtr + 37) << 24 | *(DataPtr + 38) << 16 | *(DataPtr + 39) << 8 | *(DataPtr + 40); if (Fota_S.Fota_All_Data_Len >= 0x7FE00) { Fota_Answer[3] = 0x02; } else { Fota_Answer[3] = 0x01; appReceviedCRC = (uint32)(*(DataPtr + 42)<<8 | *(DataPtr + 43)); Hal_FlsErase(Fota_S.Fota_Flash_Addres,Fota_S.Fota_All_Data_Len,5); Hal_SetAppInfo(Fota_S.Fota_All_Data_Len,appReceviedCRC,CONTROLLER_SELF); } memcpy(&Fota_Answer[4], (DataPtr + 4), BATT_SN_LEN); Fota_Answer[21] = TCP_ENCPT_DISABLE; Fota_Answer[22] = 0x00; Fota_Answer[23] = 0x12; memcpy(&Fota_Answer[24], (DataPtr + 24), 18); Fota_Answer[42] = bcc_chk_fota(Fota_Answer, 42); tcpipConnectionSend(connectId, Fota_Answer, 43); break; } case 0x02: { Fota_S.Fota_All_Data_Len = *(DataPtr + 33) << 24 | *(DataPtr + 34) << 16 | *(DataPtr + 35) << 8 | *(DataPtr + 36); Fota_S.Fota_Current_Addres = *(DataPtr + 37) << 24 | *(DataPtr + 38) << 16 | *(DataPtr + 39) << 8 | *(DataPtr + 40); Fota_S.Fota_Recv_Data_Len = *(DataPtr + 41); memset(Fota_S.Fota_Recv_Data, 0x00, 100); memcpy(Fota_S.Fota_Recv_Data, (DataPtr + 42), *(DataPtr + 41)); Fota_S.Fota_CRC = Fota_crc_chk(Fota_S.Fota_Recv_Data, Fota_S.Fota_Recv_Data_Len); if (Fota_S.Fota_CRC == *(DataPtr + Fota_S.Fota_Recv_Data_Len + 42)) { uint8 Fota_Recv_Data_Len_4 = 0; if (Fota_S.Fota_Recv_Data_Len % 4 != 0) { Fota_Recv_Data_Len_4 = Fota_S.Fota_Recv_Data_Len + 4 - (Fota_S.Fota_Recv_Data_Len % 4); } else { Fota_Recv_Data_Len_4 = Fota_S.Fota_Recv_Data_Len; } Data_Read_Buffer = malloc(Fota_S.Fota_Recv_Data_Len); Hal_FlsWrite(Fota_S.Fota_Flash_Addres + Fota_S.Fota_Current_Addres,Fota_S.Fota_Recv_Data,Fota_Recv_Data_Len_4, 10); memset(Data_Read_Buffer, 0x00, Fota_S.Fota_Recv_Data_Len); Hal_FlsRead(Fota_S.Fota_Flash_Addres + Fota_S.Fota_Current_Addres, Data_Read_Buffer, Fota_S.Fota_Recv_Data_Len, 10); Data_Read_Crc = Fota_crc_chk(Data_Read_Buffer, Fota_S.Fota_Recv_Data_Len); if (Data_Read_Crc == Fota_S.Fota_CRC) { Fota_Answer[3] = 0x01; } else { Fota_Answer[3] = 0x02; Hal_FlsErase(Fota_S.Fota_Flash_Addres + Fota_S.Fota_Current_Addres,Fota_Recv_Data_Len_4,5); } } else //数据校验失败 { Fota_Answer[3] = 0x02; } if (Data_Read_Buffer != NULL) free(Data_Read_Buffer); Data_Read_Buffer = NULL; memcpy(&Fota_Answer[4], (DataPtr + 4), BATT_SN_LEN); Fota_Answer[21] = TCP_ENCPT_DISABLE; Fota_Answer[22] = 0x00; Fota_Answer[23] = 0x12; memcpy(&Fota_Answer[24], (DataPtr + 24), 18); Fota_Answer[42] = bcc_chk_fota(Fota_Answer, 42); tcpipConnectionSend(connectId, Fota_Answer, 43); break; } case 0x03: { Fota_S.Fota_All_Data_Len = *(DataPtr + 33) << 24 | *(DataPtr + 34) << 16 | *(DataPtr + 35) << 8 | *(DataPtr + 36); Fota_S.Fota_Current_Addres = *(DataPtr + 37) << 24 | *(DataPtr + 38) << 16 | *(DataPtr + 39) << 8 | *(DataPtr + 40); Fota_Answer[3] = 0x01; memcpy(&Fota_Answer[4], (DataPtr + 4), BATT_SN_LEN); Fota_Answer[21] = TCP_ENCPT_DISABLE; Fota_Answer[22] = 0x00; Fota_Answer[23] = 0x12; memcpy(&Fota_Answer[24], (DataPtr + 24), 18); Fota_Answer[42] = bcc_chk_fota(Fota_Answer, 42); tcpipConnectionSend(connectId, Fota_Answer, 43); if (Fota_S.Fota_All_Data_Len == Fota_S.Fota_Current_Addres) { Hal_FlsCheckIsTransferSucceed(); Fota_update_flag = TRUE; } else { Fota_update_flag = FALSE; } break; } default: { Fota_Answer[3] = 0x02; memcpy(&Fota_Answer[4], (DataPtr + 4), BATT_SN_LEN); Fota_Answer[21] = TCP_ENCPT_DISABLE; Fota_Answer[22] = 0x00; Fota_Answer[23] = 0x12; memcpy(&Fota_Answer[24], (DataPtr + 24), 18); Fota_Answer[42] = bcc_chk_fota(Fota_Answer, 42); tcpipConnectionSend(connectId, Fota_Answer, 43); break; } } } } /** * @brief : fota网络校验函数 * @param {UINT8} *data * @param {UINT8} length * @return {*} */ static uint8 bcc_chk_fota(uint8 *data, uint8 length) { uint8 bcc_chk_return = 0x00; uint8 count = 0; while (count < length) { bcc_chk_return ^= data[count]; count++; } return bcc_chk_return; } /** * @brief : Fota校验函数 * @param {UINT8} *data * @param {UINT8} length * @return {*} */ static uint8 Fota_crc_chk(uint8 *data, uint8 length) { uint8 reg_crc = 0x00; while (length--) { reg_crc ^= *data++; } return reg_crc; }