⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dataoperator.cpp

📁 嵌入式DOS系统上位升级程序FileUpgrade, 需配合本人上传的FileUpr程序应用, VC++开发, 非常实用, 内附说明及源码
💻 CPP
字号:
// DataOperator.cpp: implementation of the CDataOperator class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <malloc.h>

#include "DataOperator.h"

#include "MessageEdit.h"
extern CMessageEdit  m_MsgEdit;
extern CEdit	m_SuccRatioEditCtrl;

#include "CrcCode.h"
static CCrcCode gCrcCode;

#define HAVE_STOP_MARK if(mExitSystemMark) throw((int)THROWMAG_STOP);

extern unsigned char		gCharTimeout;			//每55ms减少1,直到0为止
extern unsigned short int	gIntervalTimeout;		//每55ms减少1,直到0为止.

extern void ShowMessage(char *str);
unsigned char  mBuffer[10240];
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDataOperator::CDataOperator()
{
	m_uPackageSize=1024;//升级文件每包大小
}
CDataOperator::~CDataOperator()
{

}
//Datas格式:Len(2) Status(1)	Func(1)	 Datas(N)
void CDataOperator::SendDataPackage(unsigned char *Datas)
{
	//发送格式:Pro(4) Sync(2)  Len(2) Status(1)	Func(1)	 Datas(N)	Crc32(4) Eof(1)
	unsigned char Head[6]={0xFF,0xFF,0xFF,0xFF,0xF6,0x28};
	unsigned short Len=((Datas[0]<<8)|(Datas[1]&0xFF));
	if(Len<6)
	{
		ShowMessage("Program Error!!!!");
		return ;
	}
	*(unsigned long int *)(Datas+Len-2)=gCrcCode.Crc32Mtt(Datas,Len-2);
	Datas[Len+2]=0xFF;
    sio_write((char *)Head,6);
	sio_write((char *)Datas,Len+3);
}
//返回Datas格式:Len(2) Status(1)	Func(1)	 Datas(N)
unsigned short CDataOperator::ReceiveDataPackage(unsigned char  *Datas)//返回长度Func ,1秒超时
{
	//接收数据格式:0xFF 0xF6 0x28 Len_H Len_L Status Func Datas(N)	Crc32(4)
	signed short ch;
	short int Count,PackageLen;
	gIntervalTimeout=18;//数据总超时,
	gCharTimeout=0;
	while(gIntervalTimeout || gIntervalTimeout)
	{
		HAVE_STOP_MARK
		ch=sio_getch();
		if(ch>>8) continue;
		if(gCharTimeout==0) memset(Datas,0,5);
		gCharTimeout=8;
		Datas[0]=Datas[1];
		Datas[1]=Datas[2];
		Datas[2]=Datas[3];
		Datas[3]=Datas[4];
		Datas[4]=(unsigned char)ch;		
		if(Datas[0]!=0xFF ||Datas[1]!=0xF6 ||Datas[2]!=0x28) continue;
		//接受到数据包头,和长度字节。
		Datas[0]=Datas[3];Datas[1]=Datas[4];
		PackageLen=((Datas[0]<<8) | Datas[1])+2;
		Count=2;
		while(gCharTimeout)
		{
			HAVE_STOP_MARK

			ch=sio_getch();
			if(ch>>8) continue;
			gCharTimeout=5;
			Datas[Count++]=(unsigned char)ch;
			if(Count!=PackageLen) continue;
			if(*(unsigned long int *)(Datas+Count-4)==gCrcCode.Crc32Mtt(Datas,Count-4))
			{
				m_MsgEdit.EditPrintf("<%2X> ",Datas[3]&0xFF);
				return (Datas[3]&0xFF);
			}
			//else m_MsgEdit.AddText("\r\nCRC Error ");
		}
	}
	//m_MsgEdit.AddText("\r\nOver Time ");
	return 0;
}
void CDataOperator::RecvNewChar(unsigned char ch)
{
//	const char B0[]={0xF6,0x28,0x00,0x07,0x01,0xB0,0xF0,0x18,0x5A,0xF7,0x3A};
//	extern CMessageEdit  m_ReceiveDataEdit;
//	extern unsigned char gCharInterval;
//	if(gCharInterval==0) m_MsgEdit.AddText("\r\n");
//	m_MsgEdit.EditPrintf("%02X ",ch);
//	gCharInterval=5;

}


void CDataOperator::Send_Stop_B9_Protocol()
{
	unsigned char B0_Buf[16]={0x00,0x07,0x00,0xB9,0xF1};
	SendDataPackage(B0_Buf);
}

//FF FF FF FF F6 28 00 06 01 01 79 07 B5 B3 FF
//////////////////////////////////////////////////////////////////////////
void CDataOperator::Start()
{
	m_SuccRatioEditCtrl.SetWindowText("");
	if(mDowloadFileMsg.Count==0) return;
	m_MsgEdit.EditPrintf("\r\n--------------本次升级文件数 %d-------------",mDowloadFileMsg.Count);
	try
	{
		CFile file;
		int k;
		sio_flush();
		
		//等待B0
		m_MsgEdit.AddText("\r\n等待连接,一直等待连接...");
		k=0;
		while(ReceiveDataPackage(mBuffer)!=0xB0)
		{
			k++;
			if(k==5) {m_MsgEdit.AddText("+");k=0;}
		}
		m_MsgEdit.AddText(" OK.");
		m_connComputerNo=ftonl(mBuffer+4);
		if(m_ObjComputerNo && m_ObjComputerNo!=m_connComputerNo)
		{
			m_MsgEdit.EditPrintf("升级计算机编号(%lu %lu)不一致,不能升级!!",m_ObjComputerNo,m_connComputerNo);
			if(IDYES!=MessageBox(NULL,"升级计算机编号不一致,不能升级!\n是否强行目标退出升级?","请选择",MB_YESNO|MB_SYSTEMMODAL)) return;
			Send_Stop_B9_Protocol();
			return;
		}
		else m_MsgEdit.EditPrintf("升级计算机编号%lu!",m_connComputerNo);
		
		for(k=0;k<mDowloadFileMsg.Count;k++)
		{
			HAVE_STOP_MARK;
			if(m_ptrFileBuffer) delete[]m_ptrFileBuffer;m_ptrFileBuffer=NULL;
			m_MsgEdit.EditPrintf("\r\n▲▲▲打开升级文件%s,",mDowloadFileMsg.Name[k].srcName);
			if(file.Open(mDowloadFileMsg.Name[k].srcName,CFile::modeRead))
			{
				m_lFileLength=file.GetLength();
				m_ptrFileBuffer=new unsigned char[m_lFileLength];
				file.ReadHuge(m_ptrFileBuffer,m_lFileLength);
				file.Close();

				m_uPackageCount=(unsigned short)((m_lFileLength+m_uPackageSize-1)/m_uPackageSize);
				m_lFileCrcCode=gCrcCode.Crc32Mtt(m_ptrFileBuffer,m_lFileLength,0);
				m_MsgEdit.EditPrintf("长度%lu,包大小%u,升级包数%u,目标文件%s ",m_lFileLength,m_uPackageSize,m_uPackageCount,mDowloadFileMsg.Name[k].objName);
				SendFile(mDowloadFileMsg.Name[k].objName,(mDowloadFileMsg.Count-k-1));
			}
			else m_MsgEdit.EditPrintf("失败");
		}
	}
	catch(int v)
	{
		switch(v)
		{
		case THROWMAG_OK:
			m_MsgEdit.AddText("\r\n<<<<全部文件下载结束!!!>>>>");
			break;
		case THROWMAG_STOP:
			{
				Send_Stop_B9_Protocol();
				m_MsgEdit.AddText("\r\n<<<<强行停止升级!!!>>>>");
			}
			break;
		case THROWMAG_ERROR:
			m_MsgEdit.AddText("\r\n<<<<升级错误停止!!!>>>>");
			break;
		case THROWMAG_OVERTTIME:
			m_MsgEdit.AddText("\r\n<<<<升级数据超时停止!!!>>>>");
			break;
		default:
			break;
		}
	}
	if(m_ptrFileBuffer) delete[]m_ptrFileBuffer;
	m_ptrFileBuffer=NULL;
	return;
}
void CDataOperator::SendFile(const char *objFileName,unsigned char unSendFileCount)
{
	extern unsigned long int GetSystemDefineTime();

	unsigned long UprBeginTime,UprEndTime;
	extern unsigned short int	gSecondTimeout;

	unsigned char  B1_Buf[128];

	//产生B1,数据包
	*(unsigned short *)B1_Buf=ftons(6+18+strlen(objFileName)+1);
	B1_Buf[2]=0;
	B1_Buf[3]=0xB1;
	B1_Buf[4]=unSendFileCount;
	B1_Buf[5]=1;
	*(unsigned long *)(B1_Buf+6)=ftonl(m_lFileLength);
	*(unsigned short *)(B1_Buf+10)=ftons(m_uPackageSize);
	*(unsigned short *)(B1_Buf+12)=ftons(m_uPackageCount);
	*(unsigned long *)(B1_Buf+14)=ftonl(m_lFileCrcCode);
	*(unsigned long *)(B1_Buf+18)=ftonl(m_lFileCrcCode);
	memcpy(B1_Buf+22,objFileName,strlen(objFileName)+1);

	//发送B1,等待B1
	//开始升级
	//每8秒重复发送B1,等待回答B1之F0
	sio_flush();
	m_SuccRatioEditCtrl.SetWindowText("");
	m_MsgEdit.EditPrintf("\r\n (B1)协商发送格式 ");
	for(;;)
	{
		m_MsgEdit.EditPrintf("B1 ");
		SendDataPackage(B1_Buf);
		gSecondTimeout=8;//8秒发一次
		while(gSecondTimeout)
		{
			HAVE_STOP_MARK;
			switch(ReceiveDataPackage(mBuffer))
			{
			case 0xB1:
				if(mBuffer[4]==0xF0) goto ENTER_B2;
				break;
			case 0xB9://收到错误码
				ReceiveErrorCode(mBuffer[4]);
				throw((int)THROWMAG_ERROR);
			default:
				break;
			}
		}
	}

ENTER_B2:
	//发送B2,等待B2
	m_MsgEdit.EditPrintf("... 协商完成\r\n (B2)开始发送文件数据:");
	unsigned short int CurSendIndex=0;
	unsigned short int BeingSendIndex;

	UprBeginTime=GetSystemDefineTime();

	m_ReSendIndex.Empty();
	gSecondTimeout=60;
	for(;;)
	{
		HAVE_STOP_MARK;
		if(gSecondTimeout==0) throw((int)THROWMAG_OVERTTIME);

		//如有重发序号
		if(m_ReSendIndex.GetData(BeingSendIndex)==0)
		{
			BeingSendIndex=CurSendIndex;
			if(CurSendIndex<m_uPackageCount-1) CurSendIndex++;
		}
		//发送B2文件数据。
		SendFileData_0xB2(BeingSendIndex);
		m_MsgEdit.EditPrintf("%u ",BeingSendIndex);

		switch(WaitData())//等待数据
		{
		case 0xB0:
			m_MsgEdit.AddText("\r\n集中器可能已经重新启动,升级未完成");
			throw((int)THROWMAG_ERROR);
			return;
		case 0xB1:
			gSecondTimeout=60;
			break;
		case 0xB2:
			{
				int OKCount=ftons(mBuffer+4);
				short ReSendCount=ftons(mBuffer+6);
				CString cs;
				unsigned short int *ptrRendIndex=(unsigned short int *)(mBuffer+8);
				for(int i=0;i<ReSendCount;i++,ptrRendIndex++) m_ReSendIndex.AddData(ftons(*ptrRendIndex));
				gSecondTimeout=60;
				cs.Format("%.2f%%",100.0*OKCount/m_uPackageCount);
				m_SuccRatioEditCtrl.SetWindowText(cs);
				if(OKCount==m_uPackageCount && ReSendCount==0)
				{
					UprEndTime=GetSystemDefineTime()-UprBeginTime;
					m_MsgEdit.EditPrintf("\r\n (B3)文件升级成功(使用%lu秒),还剩%u个文件未升级.",UprEndTime,unSendFileCount);
					if(unSendFileCount==0)
					{
						Send_Stop_B9_Protocol();
						throw((int)THROWMAG_OK);
					}
					return;
				}
			}
			break;
		case 0xB9://收到错误码
			ReceiveErrorCode(mBuffer[4]);
			throw((int)THROWMAG_ERROR);
			return;
		default:
			break;
		}
	}
	
}
void CDataOperator::SendFileData_0xB2(unsigned short int Index)
{
	short int DataLen=m_uPackageSize;
	unsigned long FileOffset=(long)Index*m_uPackageSize;
	if(Index==m_uPackageCount-1) DataLen=(short)(m_lFileLength-FileOffset);
	*(unsigned short *)mBuffer=ftons(8+DataLen);
	mBuffer[2]=0;
	mBuffer[3]=0xB2;
	*(unsigned short *)(mBuffer+4)=ftons(Index);
	memcpy(mBuffer+6,m_ptrFileBuffer+FileOffset,DataLen);
	SendDataPackage(mBuffer);
};

unsigned short int CDataOperator::WaitData()
{
	//交互式传输就是在没有收到数据时,等待12秒
	short int V;
	for(int ii=0;ii<8;ii++)
	{
		V=ReceiveDataPackage(mBuffer);
		if(V) return V;
	}
	return 0;
}
void CDataOperator::ReceiveErrorCode(unsigned char ErrorCode)
{
	CString cs;
	cs.Format("\r\n    收到错误码:0x%02X,含义:",mBuffer[4]);
	switch(ErrorCode)
	{
	case 0xF1:
		cs+="错误或人为停止升级";
		break;
	case 0xF2:
		cs+="协议(未知)错误";
		break;
	case 0xF3:
		cs+="产生文件错误";
		break;
	case 0xF4:
		cs+="升级磁盘空间不够";
		break;
	case 0xF5:
		cs+="磁盘读写错误";
		break;
	case 0xF6:
		cs+="两次协商状态不一致";
		break;
	case 0xF7:
		cs+="文件传输校验码不对";
		break;
	case 0xF8:
		cs+="升级文件长度不能为0";
		break;
	}
	m_MsgEdit.AddText(cs);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -