예제 #1
0
/**
* @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;
}
예제 #2
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();
}
예제 #3
0
/**
* @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;
}
예제 #4
0
파일: flat.c 프로젝트: changlizhi/SmartHome
/**
* @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;
}
예제 #5
0
파일: flat.c 프로젝트: changlizhi/SmartHome
/**
* @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, &sector); //选择写入的扇区
	rtn = write(FlatFid, memcache, sizeof(head)+len); 	
	FLAT_UNLOCK;

	//DebugPrint(0, "writeflat id is %d, rtn is %d\n", sector, rtn);
	return rtn;
}
예제 #6
0
파일: write.c 프로젝트: amigojackal/serial
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;
	}
	
}
예제 #7
0
//--------------------------------------------------------------------------
// 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;
    }
}
예제 #8
0
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;
}
예제 #9
0
파일: FSKModem.c 프로젝트: EQ4/FSK
/*
组包,包格式:
同步域	包计数域	数据长度域	数据域	校验域
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;
}
예제 #10
0
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;
}
예제 #12
0
파일: quendi.c 프로젝트: BlastTNG/flight
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;
}
예제 #13
0
파일: FSKModem.c 프로젝트: EQ4/FSK
/*****************************************
功能:   解出全部据数
本函数调用的函数清单: 无
调用本函数的函数清单: 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;//没有数据
}
예제 #14
0
파일: write.c 프로젝트: amigojackal/serial
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);
}
예제 #15
0
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
}
예제 #16
0
/**
* @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;
}