/** * @brief 保存一个BIN文件 * @param file 文件名 * @param magic 文件标识字 * @param buffer 缓存区指针 * @param len 缓存区长度 * @return 成功返回0, 否则失败 */ int SaveBinFile(const char *file, unsigned long magic, const unsigned char *buffer, int len) { bin_filehead_t head; FILE *pf; unsigned char *headp; //printf("open %s\n", file); if((len <= 0) || (len > MAX_FILELEN)) { ErrorLog("invalid len(%d)\n", len); return 1; } AssertLogReturn(NULL==file, 1, "null file\n"); head.magic = magic; head.len = len; head.datacrc = CalculateCRC(buffer, len); headp = (unsigned char *)&(head.datacrc); head.headcrc = CalculateCRC(headp, sizeof(head)-2); remove(file); pf = fopen(file, "wb"); if(NULL == pf) { ErrorLog("can not open %s for write\n", file); return 1; } fwrite(&head, sizeof(head), 1, pf); fwrite(buffer, len, 1, pf); fclose(pf); return 0; }
int CSyncer::ProcessUnits(bool checksum) { if (!populated) { //Populate the list of unit files to consider files = CFileHandler::FindFiles("units/*.fbi"); populated = true; } if (files.size() == 0) { return 0; } string curFile = files.back(); files.pop_back(); size_t len = curFile.find_last_of("/")+1; string unitName = curFile.substr(len, curFile.size() - 4 - len); transform(unitName.begin(), unitName.end(), unitName.begin(), (int (*)(int))tolower); string perror(""); TdfParser *parser = new TdfParser(); try { parser->LoadFile("units/" + unitName + ".fbi"); } catch (TdfParser::parse_error& pe) { perror = unitName + " (" + string(pe.what()) + ")"; } Unit u; if (checksum) { u.fbi = CalculateCRC("units/" + unitName + ".fbi"); u.cob = CalculateCRC("scripts/" + unitName + ".cob"); //The model filenames has to be figured out from the fbi file string modelName = parser->SGetValueDef(unitName, "unitinfo\\Objectname"); string deadName = parser->SGetValueDef(unitName + "_dead", "unitinfo\\Corpse"); u.model = CalculateCRC("objects3d/" + modelName + ".3do"); u.model += CalculateCRC("objects3d/" + deadName + ".3do"); } u.fullName = parser->SGetValueDef("unknown", "unitinfo\\Name"); if (perror.length() > 0) u.fullName = perror; units[unitName] = u; delete parser; //If we are done, map id numbers to names if (files.size() == 0) { MapUnitIds(); } return (int)files.size(); }
/** * @brief 读取一个BIN文件 * 与ReadBinFile不同的是,buffer内容在读取失败的情况下也有可能修改 * 因此需要应用程序分配专门的buffer * 一般用来读取数据文件 * 操作比ReadBinFile少了内存分配操作, 但增加了数据不安全性, 使用时要小心 * @param file 文件名 * @param magic 文件标识字 * @param buffer Cache缓存区指针 * @param len 缓存区长度 * @return 成功返回实际读取长度,失败返回-1 */ int ReadBinFileCache(const char *file, unsigned long magic, unsigned char *buffer, int len) { bin_filehead_t head; FILE *pf; unsigned short crc; if((len <= 0) || (len > MAX_FILELEN)) { ErrorLog("invalid len(%d)\n", len); return -1; } AssertLogReturn(NULL==file, -1, "null file\n"); pf = fopen(file, "rb"); if(NULL == pf) return -1; if(fread(&head, sizeof(head), 1, pf) <= 0) { ErrorLog("%s file head too short\n", file); goto mark_fail; } if(head.magic != magic) { ErrorLog("%s magic invalid(0x%08X)\n", file, head.magic); goto mark_fail; } if(head.len <= 0 || head.len > len) { ErrorLog("%s len invalid(%d)\n", file, head.len); goto mark_fail; } crc = CalculateCRC((unsigned char *)&(head.datacrc), sizeof(head)-2); if(head.headcrc != crc) { ErrorLog("%s head crc erorr(0x%04X, should be 0x%04X)\n", file, head.headcrc, crc); goto mark_fail; } if(fread(buffer, head.len, 1, pf) <= 0) { ErrorLog("%s len too long(%d)\n", file, head.len); goto mark_fail; } crc = CalculateCRC(buffer, head.len); if(head.datacrc != crc) { ErrorLog("%s data crc erorr(0x%04X, should be 0x%04X)\n", file, head.datacrc, crc); goto mark_fail; } if(len > head.len) len = head.len; fclose(pf); return len; mark_fail: fclose(pf); return -1; }
/** * @brief 检查记录的合法性 * @param buf 缓存区指针 * @param len 缓存区长度 * @return 合法记录返回1, 非法记录返回0, 空记录返回-1 */ static inline int ValidRecord(const unsigned char *buf, int len) { unsigned short crc; rec_head_t *phead = (rec_head_t *)buf; int i; if(phead->magic != FLAT_MAGIC) { if(phead->magic == 0xffff && phead->crc == 0xffff) goto mark_empty; else return 0; } crc = CalculateCRC(buf+sizeof(rec_head_t), len-sizeof(rec_head_t)); if(crc != phead->crc) return 0; return 1; mark_empty: buf += sizeof(rec_head_t); len -= sizeof(rec_head_t); for(i=0; i<len; i++) { if(0xff != *buf++) return 0; } return -1; }
/** * @brief 写入FLAT文件数据 * @param sector 文件扇区号 * @param buf 缓存区指针 * @param len 缓存区长度 * @return 成功返回实际写入长度, 失败返回-1 */ int WriteFlatFile(unsigned int sector, const unsigned char *buf, int len) { rec_head_t head; int rtn = 0; unsigned char memcache[BUFFER_SIZE]; unsigned char* pmem = memcache; AssertLogReturn(FlatFid<0, -1, "invalid flat id(%d)\n", sector); AssertLogReturn(sector >= MAX_SECTOR, -1, "invalid sector(%d)\n", sector); AssertLogReturn(len <= 0, -1, "invalid len(%d:%d)\n", sector, len); AssertLogReturn(len > REC_DATASIZE(sector), -1, "invalid record size(%d:%d)\n", sector, REC_DATASIZE(sector)); head.magic = FLAT_MAGIC; head.crc = CalculateCRC(buf, len); memset(pmem, 0x0, sizeof(memcache)); memcpy(pmem, (void*)&head, sizeof(head)); pmem += sizeof(head); memcpy(pmem, buf, len); FLAT_LOCK; ioctl(FlatFid, 0, §or); //选择写入的扇区 rtn = write(FlatFid, memcache, sizeof(head)+len); FLAT_UNLOCK; //DebugPrint(0, "writeflat id is %d, rtn is %d\n", sector, rtn); return rtn; }
void parser(int type, unsigned char addr, unsigned char *data, int len){ if(CalculateCRC(data,len-2) != data[len-2] + data[len-1]*256){ printf("ERROR checking CRC!!\n"); int delay = 10000000 + rand()%10000000; sleep(1); while(delay > 0) delay -= 1; return; } }
//-------------------------------------------------------------------------- // Module: // VerifyCRCAtStart // /// This function executes the entire CRC test and verifies that /// contents of the ROM are valid. /// /// returns BOOLEAN - TRUE if test passed /// //-------------------------------------------------------------------------- BOOLEAN VerifyCRCAtStart (void) { HexLEDUpdate (0xCB); if (CalculateCRC (ROM_START, ROM_END, 0)) { return FALSE; } else { return TRUE; } }
FLARM::FrameHeader FLARM::PrepareFrameHeader(unsigned sequence_number, MessageType message_type, const void *data, size_t length) { assert((data != NULL && length > 0) || (data == NULL && length == 0)); FrameHeader header; header.SetLength(8 + length); header.version = 0; header.SetSequenceNumber(sequence_number++); header.type = (uint8_t)message_type; header.SetCRC(CalculateCRC(header, data, length)); return header; }
/* 组包,包格式: 同步域 包计数域 数据长度域 数据域 校验域 4字节 1字节 2字节 n字节 2字节 输入参数: data: 上层传递下来的数据 len: 数据的长度 输出参数: outLen:返回值的长度 返回值: 按照以上格式组好的包 */ BYTE* PackField(char* data,int len,int *outLen) { int bufLen = len + 9; short crc; BYTE *buf = NULL; int offset = 0; int dataLen = 0; buf = (BYTE*)malloc(bufLen); //buf = new BYTE[bufLen]; offset += PackSYNC(buf + offset); offset += PackCount(buf + offset); offset += PackLength(len,buf+offset); dataLen = PackData(data,len,buf+offset); // crc校验只需要校验数据域就行 crc = CalculateCRC(buf+offset,dataLen); offset += dataLen; offset += PackCRC(crc,buf+offset); *outLen = offset; return buf; }
void SendFrame(uint8_t fr_nr) { // init frame to send memcpy_P(&frame[0], &ec_frames[fr_nr], sizeof(modbus_head_t)); CalculateCRC(6); // add crc bytes to the end of frame starting form byte position 6 #if _DEBUG_>1 Serial.print(F("Sending EnergyCam frame:")); for (byte i=0; i<8; i++) { Serial.print(' '); byte tmp = frame[i]; if ( tmp<16 ) Serial.print(0); Serial.print(tmp, HEX); } Serial.println(); #endif while ( (millis()-startDelay)<2 ) WDG_RST; // wait for frame delay // prepare to send #ifdef USE_RS485 RS485_ENABLE_TX; delayMicroseconds(100); // write RS485 header Serial1.write(EC_ID); Serial1.write(0xFF^EC_ID); Serial1.write(frame, 8); // prepare to receive the answer Serial1.flush(); // wait till all data was sent delayMicroseconds(300); RS485_ENABLE_RX; #else ec_client.write((byte)0); // wake-up from sleep mode delay(2); // frame delay //frameSize = 8; ec_client.write(frame, 8); // wait till last byte was sent // delayMicroseconds(frameDelay); delay(2); // frame delay #endif Modbus_WaitForReply(); // wait one second long till complete reply frame is received // return error_code; }
//=============================================================================================== // FUNCTION: ValidateCRC // PURPOSE: Validates the CRC in the FileInfo matches the CRC of the file. // BOOL CABF2ProtocolReader::ValidateCRC() { MEMBERASSERT(); if( m_pFH->nCRCEnable != ABF_CRC_ENABLED ) return TRUE; // CRC checking required. Read( 0 ); #if _DEBUG // Get the total length of the file. #ifdef _DEBUG LONGLONG llFileLength = m_pFI->GetFileSize(); UINT uHeaderSize = sizeof( m_FileInfo ); ASSERT( llFileLength > uHeaderSize ); #endif // _DEBUG #endif // Keep expected CRC value from header and Zero the lFileCRC. UINT uExpectedCRC = m_FileInfo.uFileCRC; m_FileInfo.uFileCRC = 0; UINT uFileCRC = CalculateCRC( &m_FileInfo, sizeof( m_FileInfo ) ); // Restore the original CRC. m_FileInfo.uFileCRC = uExpectedCRC; // Compare expected CRC with file CRC. if ( uFileCRC != uExpectedCRC ) { TRACE2( "File CRC Validation Failed: Expected %X, Calculated %X\n", uExpectedCRC, uFileCRC ); return FALSE; } TRACE1( "File CRC Validation OK: %X\n", uFileCRC); return TRUE; }
void quendi_send_data(int dsock, unsigned frame_size, int block_size) { int i; char buffer[100]; unsigned short crc; if (block_size > 0) { snprintf(buffer, 100, "%i Frame Block Transfer Starting", block_size); quendi_respond(QUENYA_RESPONSE_SENDING_DATA, buffer); for (i = 0; i < block_size; ++i) { if (write(dsock, quendi_input_buffer[i], frame_size) < 0) berror(err, "failed to write to socket"); } crc = CalculateCRC(CRC_SEED, quendi_input_buffer[0], frame_size * block_size); sprintf(buffer, "0x%04X Block CRC", crc); quendi_respond(QUENYA_RESPONSE_BLOCK_CRC, buffer); } return; }
/***************************************** 功能: 解出全部据数 本函数调用的函数清单: 无 调用本函数的函数清单: main 输入参数: *InDataBuf 采样值地址 lenth 总长度 startlen 开始的地方 MmobileType 手机类型 输出参数: *OutDataBuf 数据保存的地方 *endlen 解到哪点了 函数返回值说明: 0为出错,1为成功解出8位数据 使用的资源 ******************************************/ BYTE GetAllData(BYTE *OutDataBuf, short *InDataBuf,unsigned long lenth,unsigned long *endlen,BYTE MobileType) { unsigned long i = *endlen - 1;//指向第i个点 unsigned long j = 0;//指向第j个解出的数据 unsigned long DataLenth = 0;//整个数据的长度,由数据前两字节表示 float LengthOfZorePassage = 0;//过零点之间宽度 float LastRatio = 0;///过零点上一次的比率 float RatioOfZorePassage = 0;//过零点这一次的比率 unsigned long datastart = 0;//当前在解的波的开始点 BYTE bit0flag = 0;//用于实现两个小波表示1 BYTE bitindex = 0;//解出来的数据的位数 unsigned short crc = 0;//用于校验 /************************************/ //下面的参数用于实现0 、1 幅度的对比// unsigned short highest = 0;//每一位中,采样值的最高点// unsigned long sum0 = 0;//0的总和 unsigned long sum1 = 0;// 1的总和 unsigned short number0 = 0;//0的个数 unsigned short number1 = 0;// 1的个数 unsigned long k = 0;//用于实现查找每一位中的最高采样率 等 普通循环 float RatioOf0b1 = 0;// 所有1 中最高采样之和 与 所有0中最高采样之和 的比率。 /************************************/ /************************************/ //下面的参数用于实现波形兼容性检查//// float MaxOf0Wide = 0;//0中宽度偏差之最 float MaxOf1Wide = 0;// 1中宽度偏差之最 /************************************/ for(;i<lenth ;) { datastart = i;//当前波的开始点 LastRatio = RatioOfZorePassage;//保存上一次的过零点比率 if(InDataBuf[i] >= 0)//如果采样值大于等于0 { while(InDataBuf[i] >= 0)//直到采样值小于0 { i++;//下一个采样点 } } else//如果采样值小于0 { while(InDataBuf[i] < 0)//直到采样值大于0 { i++;//下一个采样点 } } RatioOfZorePassage = ((float)(abs(InDataBuf[i]))) / ( (float)(abs(InDataBuf[i - 1])) + (float)(abs(InDataBuf[i])) ); if(i == 28036) { i = i; } //记下当前波过零点之间的宽度 LengthOfZorePassage =LastRatio + (i - datastart - 1) + (1 - RatioOfZorePassage); if(( LengthOfZorePassage >= (3.0/ 2.0)*((float) MobileType+1.0) ) &&(LengthOfZorePassage<(12.0/ 3.0)*((float) MobileType+1.0))) //如果是大波 { if(bit0flag == 1)//小波后面是大波就是出错了 { printf("\ndata error,0after1 \n"); *endlen = i; return 0; } /********************************************************/ highest = abs(InDataBuf[datastart]);//置初值 for(k = datastart+1;k < i;k++)//找出该位中的最高采样值 { if( (abs(InDataBuf[k])) > highest ) { highest = abs(InDataBuf[k]); } } if(highest < 300)//最高采样值不应该比300还低 { printf("\ndata error,0 smoll than 300 \n"); *endlen = i; return 0; } number0++;//多少个0 sum0 += highest;//统计0的采样值之和 /********************************************************/ if( fabs(LengthOfZorePassage - (MobileType+1)*2) > fabs(MaxOf0Wide) ) { MaxOf0Wide = (LengthOfZorePassage - (MobileType+1)*2); } /********************************************************/ OutDataBuf[j] &= ~(1<<(7-bitindex)); bitindex++; } else if((LengthOfZorePassage>= (1.0/3.0)*((float) MobileType+1.0)) &&(LengthOfZorePassage< (3.0/2.0)*((float) MobileType+1.0))&&(i != *endlen)) //如果是小波 { /********************************************************/ if( fabs(LengthOfZorePassage - (MobileType+1)) > fabs(MaxOf1Wide) ) { MaxOf1Wide = (LengthOfZorePassage - (MobileType+1)); } /********************************************************/ if(bit0flag == 0)//如果是第一个小波 { bit0flag = 1; continue; } else//如果是第二个小波 { /********************************************************/ highest = abs(InDataBuf[datastart]);//置初值 for(k = datastart+1;k < i;k++)//找出该位中的最高采样值 { if( abs(InDataBuf[k]) > highest ) { highest = abs(InDataBuf[k]); } } if(highest < 300)//最高采样值不应该比300还低 { printf("\ndata error,1 smoll than 300 \n"); *endlen = i; return 0; } number1++;//多少个1 sum1 += highest;//统计1的采样值之和 /********************************************************/ OutDataBuf[j] |= 1<<(7-bitindex); bitindex++; bit0flag = 0;//两个小波为"1" } } else { if(i == *endlen)//第一个波只取了一点,所以肯定是非常小的 { continue; } printf("\ndata error,too long or small \n"); *endlen = i; return 0;//出现其它的波,直接认为出错了 } if( bitindex == 8 )//8位1字节 { printf("%02x,", OutDataBuf[j]);//打印数据 j++; bitindex = 0; } if((j == 1) && (bitindex == 0))// 一开始1个字节是计数器 g_cPackageCount = OutDataBuf[0]; if((j == 3)&&(bitindex == 0))// 接下来两个字节是数据长度 { DataLenth = OutDataBuf[1] | (OutDataBuf[2] << 8); } //if(( j == 4)&&(bitindex == 0)) if(( j == DataLenth + 3 + 2) && (j >= 3))//全部解出来了 { #if 0 MaxOf0Wide = (3*MaxOf0Wide/(MobileType + 1)/2); MaxOf1Wide = (3*MaxOf1Wide/(MobileType + 1)); printf("\nMaxOf0Wide is %f%%\n",(3*MaxOf0Wide/(MobileType + 1)/2)*100);//打印 printf("\nMaxOf1Wide is %f%%\n",(3*MaxOf1Wide/(MobileType + 1))*100);//打印 for(k = 2; k < DataLenth+1; k++)//计算校验,除长度之外,全部异或 { crc ^= OutDataBuf[k]; } if(crc != OutDataBuf[DataLenth + 1])//如果校验通不过 { printf("\n CRC error \n"); //打印校验出错 *endlen = i; return 0;//校验出错 } #endif /*************************************************************************CRC16**/ crc = OutDataBuf[DataLenth + 3] | (OutDataBuf[DataLenth + 4] << 8); /* BYTE OutDataBuf111[3000] = {0}; BYTE OutDataBuf1111[4] = {0x55,0x55,0x01,0x01}; memset(OutDataBuf111, 0,3000); memcpy(OutDataBuf111,OutDataBuf1111,4); memcpy(OutDataBuf111+4,OutDataBuf,DataLenth);*/ if(crc != CalculateCRC(OutDataBuf+3,DataLenth))//如果校验通不过 { printf("\n CRC error \n"); //打印校验出错 *endlen = i; return 0;//校验出错 } /***********************************************************************************/ printf("\n end \n\n"); *endlen = i; return 1; } } printf("\ndata error,no data \n"); *endlen = i; return 0;//没有数据 }
void go(){ struct termios tty; int fd = open("/dev/ttyAMA0", O_RDWR); if(fd<0){ fprintf(stderr, "Unable to open serial port\n"); return; }else{ printf("ttyAMA0 opened!(%d)\n", fd); } memset(&tty,0,sizeof(tty)); if(tcgetattr(fd, &tty) != 0){ printf("Error: %d, from tcgetattr: %s\n",errno,strerror(errno)); return; } // Set Baud Rate cfsetospeed (&tty, B9600); cfsetispeed (&tty, B9600); // 8 Bits, No Parity and 1 Stop bit settings tty.c_cflag &= ~PARENB; // No Parity tty.c_cflag &= ~CSTOPB; // 1 Stop Bit tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; // 8 Bits tty.c_cflag &= ~CRTSCTS; // no flow control tty.c_cc[VMIN] = 1; // read doesn't block tty.c_cc[VTIME] = 10; // 0.5 seconds read timeout tty.c_cflag |= (CLOCAL | CREAD ); // turn on READ & ignore ctrl lines // Make raw cfmakeraw(&tty); // Flush Port, then applies attributes tcflush( fd, TCIFLUSH ); if ( tcsetattr ( fd, TCSANOW, &tty ) != 0) { printf("Error %d from tcsetattr %s\n",errno,strerror(errno)); return; } unsigned char cmd[8]; int crc; int n_written, n; int i,j; unsigned char addr; char buf [16]; cmd[0]=0x01; cmd[1]=0x03; cmd[2]=0x00; cmd[4]=0x00; cmd[5]=0x01; for(addr = 0; addr < 10 ; addr += 1){ cmd[3]=addr; crc = CalculateCRC(cmd,6); cmd[6] = crc % 256; cmd[7] = (crc / 256)%256; memset (&buf, '\0', sizeof buf); n_written = write( fd, cmd, 8); printf("%d sent >> ",n_written); for(i=0;i<sizeof cmd;i++){ printf("%d ",cmd[i]); } printf("\n"); fflush(stdout); n = read( fd, &buf , sizeof buf ); /* Error Handling */ if(n<0){ printf("Error reading: (%d) %s\n",errno,strerror(errno)); break; } if(n>0){ /* Print what I read... */ printf("%d read << ",n); for(i=0;i<n;i++){ printf("%d ",buf[i]); } printf("\n"); parser(3, addr, buf, n); } } cmd[1]=0x04; for(addr = 0; addr < 3 ; addr += 1){ cmd[3]=addr; crc = CalculateCRC(cmd,6); cmd[6] = crc % 256; cmd[7] = (crc / 256)%256; memset (&buf, '\0', sizeof buf); n_written = write( fd, cmd, 8); printf("%d sent >> ",n_written); for(i=0;i<sizeof cmd;i++){ printf("%d ",cmd[i]); } printf("\n"); fflush(stdout); n = read( fd, &buf , sizeof buf ); /* Error Handling */ if(n<0){ printf("Error reading: (%d) %s\n",errno,strerror(errno)); break; } if(n>0){ /* Print what I read... */ printf("%d read << ",n); for(i=0;i<n;i++){ printf("%d ",buf[i]); } printf("\n"); parser(4, addr, buf, n); } } close(fd); }
void Modbus_WaitForReply(void) { #define MODBUS_TIMEOUT 1000 // millis mb_state = RECEIVING_DATA; buffer = 0; timeout = millis(); // wait up to one second for reply // if ( (*ModbusPort).available() ) // is there something to check? while ( (millis()-timeout)<MODBUS_TIMEOUT && mb_state==RECEIVING_DATA ) { while ( ec_client.available() ) { WDG_RST; // avoid reset // The maximum number of bytes is limited to the serial buffer size of BUFFER_SIZE. // If more bytes is received than BUFFER_SIZE, the overflow flag will be set and // the serial buffer will be flushed as long as the slave is still responding. uint8_t mb_data = ec_client.read(); //Serial.println(mb_data,HEX); // debug if ( mb_state==RECEIVING_DATA ) { if ( buffer==0 && mb_data==0 ) continue; // workaround for leading '0' // read and check data byte if ( buffer>=BUFFER_SIZE ) ProcessError(BUFFER_OVERFLOW); // buffer size overflow else if ( buffer==0 && mb_data!=frame[0] ) ProcessError(WRONG_ID); // wrong slave ID else if ( buffer==1 && (mb_data!=frame[1] || (0x80&frame[1])) ) ProcessError(WRONG_FUNCTION); // wrong function code else if ( buffer==2 && mb_data!=2*frame[5] ) ProcessError(WRONG_DATA_LEN); // wrong data lenght } if ( mb_state==RECEIVING_DATA ) // store data byte only if no error detected so far { frame[buffer++] = mb_data; // store data and increment index // check frame length and CRC if ( buffer>2 && (frame[2]+5)==buffer ) // last byte of frame received { *(uint16_t *)&frame[buffer] = *(uint16_t *)&frame[buffer-2]; // save received CRC CalculateCRC(buffer-2); // overwrite received CRC with calculated value in the frame buffer if ( *(uint16_t *)&frame[buffer] != *(uint16_t *)&frame[buffer-2] ) ProcessError(WRONG_CRC); // wrong CRCs else ProcessSuccess(); // complete and correct reply frame received } } // insert inter character time out if no new data received yet if ( !ec_client.available() ) delayMicroseconds(T1_5); } ////////// END OF FRAME RECPTION ////////// WDG_RST; // avoid reset // The minimum buffer size from a slave can be an exception response of 5 bytes. // If the buffer was partially filled set a frame_error. if ( buffer>0 ) ProcessError(WRONG_FRAME_LEN); // too few bytes received } WDG_RST; // avoid reset if ( buffer==0 ) ProcessError(REPLY_TIMEOUT); // timeout error, no data received startDelay = millis(); // starting delay }
/** * @brief 读取一个BIN文件 * @param file 文件名 * @param magic 文件标识字 * @param buffer 缓存区指针 * @param len 缓存区长度 * @return 成功返回实际读取长度,失败返回-1 */ int ReadBinFile(const char *file, unsigned long magic, unsigned char *buffer, int len) { bin_filehead_t head; FILE *pf; unsigned short crc; unsigned char *memcache = NULL; int memlen, filelen; if((len <= 0) || (len > MAX_FILELEN)) { ErrorLog("invalid len(%d)\n", len); return -1; } AssertLogReturn(NULL==file, -1, "null file\n"); pf = fopen(file, "rb"); if(NULL == pf) return -1; if(fread(&head, sizeof(head), 1, pf) <= 0) { ErrorLog("%s file head too short\n", file); goto mark_fail; } if(head.magic != magic) { ErrorLog("%s magic invalid(0x%08X)\n", file, head.magic); goto mark_fail; } if(head.len <= 0 || head.len > MAX_FILELEN) { ErrorLog("%s len invalid(%d)\n", file, head.len); goto mark_fail; } crc = CalculateCRC((unsigned char *)&(head.datacrc), sizeof(head)-2); if(head.headcrc != crc) { ErrorLog("%s head crc erorr(0x%04X, should be 0x%04X)\n", file, head.headcrc, crc); goto mark_fail; } if(head.len > MAX_MEMLEN) memlen = MAX_MEMLEN; else memlen = head.len; memcache = malloc(memlen); if(NULL == memcache) { ErrorLog("malloc %d bytes fail\n", head.len); goto mark_fail; } crc = 0; filelen = head.len; while(filelen > 0) { if(fread(memcache, memlen, 1, pf) <= 0) { ErrorLog("%s len too long(%d)\n", file, head.len); goto mark_fail; } CalculateCRCStep(memcache, memlen, &crc); filelen -= memlen; if(filelen > 0 && filelen < memlen) memlen = filelen; } if(head.datacrc != crc) { ErrorLog("%s data crc erorr(0x%04X, should be 0x%04X)\n", file, head.datacrc, crc); goto mark_fail; } if(len > head.len) len = head.len; if(head.len > MAX_MEMLEN) { fseek(pf, sizeof(head), SEEK_SET); if(fread(buffer, len, 1, pf) <= 0) { ErrorLog("read file error\n"); goto mark_fail; } } else { memcpy(buffer, memcache, len); } free(memcache); fclose(pf); return len; mark_fail: if(NULL != memcache) free(memcache); fclose(pf); return -1; }