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

📄 ccd_commcenter.c

📁 串口传输文件device端实例
💻 C
📖 第 1 页 / 共 3 页
字号:
	if(!SetCommMask(CommCenterVar->comId, EV_RXCHAR|EV_ERR)) {
		WinShowSystemPromptDialog(0, (Char *)"文件下载", (Char*)"打开串口出错4!");
		return FALSE;
	}
	return TRUE;
}


Boolean CommCenter_ErrorDealEvent(CommCenter_DEMOGVRType *CommCenterVar, Int32 ErrorCode, Int32 cSEQ)
{
	Char	 szRspPacketPtr[sizeof(CommCenter_PACKETHEADType) + sizeof(Int32) + 256];
	Int32	 size = 0, dwCount = 0, Id;
#ifdef debug_modul
	Char	 szOutPutBuff[256];
#endif


#ifdef debug_modul
	sprintf((char *)szOutPutBuff, (char *)"==== CommCenter_ErrorDealEvent: %d %d\n", ErrorCode, cSEQ);
	EOS_Write(CommCenterVar->deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
#endif

	MemSet(szRspPacketPtr, 0, sizeof(szRspPacketPtr));

	if(ErrorCode == 0x00000000) {//发送成功汇报报文		
		size = CommCenter_Creat_RspError(CommCenterVar, szRspPacketPtr, ErrorCode, CommCenter__ErrText[ErrorCode], cSEQ);
		dwCount = Write(CommCenterVar->comId, szRspPacketPtr, size);

#ifdef debug_modul
		sprintf((char *)szOutPutBuff, (char *)"CommCenter_Creat_RspError:%d\n", dwCount);
		EOS_Write(CommCenterVar->deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
#endif
		return dwCount == size;
	}

	if(0 <= CommCenterVar->hFile) {
		EOS_Close(CommCenterVar->hFile);
		CommCenterVar->hFile = -1;
	}

	if(ErrorCode == 0x00000001 || ErrorCode == 0x00000002) {
		if(0 <= CommCenterVar->comId) {
			Close(CommCenterVar->comId);
			CommCenterVar->comId = -1;
		}

		MemSet(CommCenterVar, 0, sizeof(CommCenter_DEMOGVRType));
		CommCenterVar->comId = -1;
		CommCenterVar->hFile = -1;
		CommCenterVar->nStep = CommCenter_FILEWAIT;

		//重新打开并初始化串口
		return CommCenter_OpenInitCom(CommCenterVar);	
	}

	//发送报头错误报告报文
	size = CommCenter_Creat_RspError(CommCenterVar, szRspPacketPtr, ErrorCode, CommCenter__ErrText[ErrorCode], cSEQ);
	dwCount = Write(CommCenterVar->comId, szRspPacketPtr, size);

	if(CommCenterVar->nStep != CommCenter_FILEDATA) {
		//恢复到最初状态
		MemSet(&CommCenterVar->fcb, 0, sizeof(CommCenter_FILEINDEXType));

		CommCenterVar->nStep = CommCenter_FILEWAIT;
		CommCenterVar->nStat = CommCenter_PACKETHEAD;
		CommCenterVar->fStep = 0;				
		CommCenterVar->nPotS = 0;				
		CommCenterVar->nPotE = 0;				
		CommCenterVar->CRC   = 0;			    
		CommCenterVar->FiletotleCount = 0;
	}
	if(CommCenterVar->nStep == CommCenter_FILEDATA) { //如果正在写文件,删除文件,后退等待重发文件
		//保存Id或回退Id
		Id = FILE_INDEX < CommCenterVar->fStep? CommCenterVar->fcb.nId-1:CommCenterVar->fcb.nId; 

		CommCenterVar->fcb.nId = Id;
		CommCenterVar->nStat = CommCenter_PACKETHEAD;
		CommCenterVar->fStep = 0;				
		CommCenterVar->nPotS = 0;				
		CommCenterVar->nPotE = 0;				
		CommCenterVar->CRC   = 0;
	}
	return dwCount == size;
}	

//创建目录
Boolean MdWithFile(Char *dirName, Char *chrPtr)
{
	Char *SLASHPtr = NULL, DirBuff[MAXPATH_LEN + 1];	
	
	if(0 < StrLen(chrPtr)) { 
		SLASHPtr = StrChr(chrPtr, '\\');	
		if(NULL != SLASHPtr) {
			MemSet(DirBuff, 0, sizeof(DirBuff));
			StrNCopy(DirBuff, dirName, (Int32)(SLASHPtr-dirName));
			EOS_MakeDir(DirBuff);
			return MdWithFile(dirName, SLASHPtr + 1);
		}
	}
	return TRUE;
}


static void CommCenterThread_Inform(Int32 Pid, Int32 wndId, Int32 Param1, Int32 Param2, Int32 Param3, Int32 Param4)
{
	EventType eventP;

	//封装显示文件传输进度事件,发送
	eventP.PId		= Pid; 		
	eventP.eType	= RSPCOM_MSG;  
	eventP.sParam1	= Param1;
	eventP.sParam2	= Param2;
	eventP.lParam3	= Param3;
	eventP.lParam4	= Param4;
	eventP.hwndId	= wndId; 
	eventP.ctlId	= 0;
	eventP.flags	= 0;
	eventP.len		= 0;
	EvtAddEventToQueue(&eventP);
}


//线程处理过程:按通讯协议规则通过串口收发数据
Boolean CommCenter_IOThread()
{
	Int32			 readcount = 0, tmpFIndex = 0, tmpWcount = 0;
#ifdef debug_modul
	Int32			 clen, i;
	Int16			 nTAG;
	Char			 szOutPutBuff[512], *p = NULL, cFC, cPC;	
#endif
	CommCenter_DEMOGVRType commVar;


	//打开串口,并初始化文件下载
	MemSet(&commVar, 0, sizeof(CommCenter_DEMOGVRType));
	commVar.nStep = CommCenter_FILEWAIT;
	commVar.comId = -1;
	commVar.hFile = -1;
	commVar.nStat = CommCenter_PACKETHEAD;

	//打开串口
	if(FALSE == CommCenter_OpenInitCom(&commVar)) {
		return FALSE;
	}

#ifdef debug_modul
	commVar.deBugfp = EOS_Open((Char *)"C:\\DEBUG.CFG", PO_CREAT|PO_WRONLY|PO_TRUNC, PS_IWRITE);
#endif	

	while(NULL != g__winP) {
		//读取端口的数据
		readcount = Read(commVar.comId, commVar.szStoreBuffer + commVar.nPotE, sizeof(commVar.szStoreBuffer) - commVar.nPotE);
		if(0 >  readcount) {
			//串口错误报告, 处理
			CommCenter_ErrorDealEvent(&commVar, 0x00000001, 0x00000000);
			continue;
		}
		if(0 == readcount) {
			//端口没有数据, 继续
			NU_Sleep(5);
			continue;
		}

		commVar.nPotE += readcount;
		readcount = commVar.nPotE - commVar.nPotS;

#ifdef debug_modul
		sprintf((char *)szOutPutBuff, (char *)"==== IOEVENT: %d %d %d\n", commVar.nStat, readcount, commVar.nPotS);
		EOS_Write(commVar.deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
		for(i=0, p = szOutPutBuff; i< readcount && i < 256; i++, p += 2) {
			sprintf((char *)p, (char *)"%02x", commVar.szStoreBuffer[commVar.nPotS+i]);
		}
		EOS_Write(commVar.deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
#endif

		commVar.pcb = (CommCenter_PACKETHEADType *)commVar.szStoreBuffer;

		//1. 指示接收包头
		if(CommCenter_PACKETHEAD == commVar.nStat) { 
			//检查是否接收完包头
			if(readcount < sizeof(CommCenter_PACKETHEADType)) {
				//包头未收完, 继续收包头
				continue;
			}

			//保存报文的CRC值
			commVar.CRC = CommCenter_ntohs(commVar.pcb->cCRC);
			commVar.pcb->cCRC = 0x0000;

			//计算包头的CRC16
			commVar.pcb->cCRC = Add_CRC16(0xffff, commVar.szStoreBuffer, sizeof(CommCenter_PACKETHEADType));

#ifdef debug_modul
			sprintf((char *)szOutPutBuff, (char *)"==== Head1: %04x %d %d %d %d\n", commVar.pcb->cTAG, commVar.pcb->cFC, commVar.pcb->cPC, commVar.nPotS, commVar.nPotE);
			EOS_Write(commVar.deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
#endif

			//更新相关数据
#ifdef debug_modul
			cFC = commVar.pcb->cFC;
			cPC = commVar.pcb->cPC;

			nTAG= commVar.pcb->cTAG;
			clen= commVar.pcb->clen;
#endif
			commVar.pcb->cTAG = CommCenter_ntohs(commVar.pcb->cTAG);
			commVar.pcb->clen = CommCenter_ntohl(commVar.pcb->clen);
#ifdef debug_modul
			commVar.pcb->cFC = cFC;
			commVar.pcb->cPC = cPC;
#endif

#ifdef debug_modul
			sprintf((char *)szOutPutBuff, (char *)"==== Head2: %04x %d %d %d %d\n", commVar.pcb->cTAG, commVar.pcb->cFC, commVar.pcb->cPC, commVar.nPotS, commVar.nPotE);
			EOS_Write(commVar.deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
#endif

			//检查数据包头
			if(0xfff0 != commVar.pcb->cTAG) {//包头错误报告,处理
				CommCenter_ErrorDealEvent(&commVar, 0x00000002, 0x00000001);
				continue;
			}
			if(0x06 != commVar.pcb->cFC) {
				CommCenter_ErrorDealEvent(&commVar, 0x00000002, 0x00000002);
				continue;
			}
			if(0x06 == commVar.pcb->cFC) {
				if(0x01 == commVar.pcb->cPC) {
					//发送文件请求
					commVar.nStep = CommCenter_FILEREQ;
				} else if(0x02 == commVar.pcb->cPC) {
					//发送文件数据
					commVar.nStep = CommCenter_FILEDATA;
					commVar.fStep = FILE_INDEX;
				} else {
					CommCenter_ErrorDealEvent(&commVar, 0x00000002, 0x00000003);
					continue;
				}
			}

			commVar.nStat = CommCenter_PACKETINFO; //准备接收包体
			commVar.nPotS = sizeof(CommCenter_PACKETHEADType);
			readcount -= sizeof(CommCenter_PACKETHEADType);

#ifdef debug_modul
			sprintf((char *)szOutPutBuff, (char *)"==== COM1: %d %d %d %d\n", commVar.nStat, commVar.nPotS, commVar.nPotE, readcount);
			EOS_Write(commVar.deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
#endif
			//准备处理包体
		}

		//2. 指示接收包体
		if(CommCenter_PACKETINFO == commVar.nStat) { 

			//a. 发送文件个数请求
			if(CommCenter_FILEREQ == commVar.nStep) { 
				if(readcount < sizeof(UInt32)) {
					//包体尚未接收到最小数据长度
					continue;
				}

				//计算包体的CRC16
				commVar.pcb->cCRC = Add_CRC16(commVar.pcb->cCRC, commVar.szStoreBuffer+commVar.nPotS, sizeof(UInt32));

				if(FALSE == IsValid_CRC16(commVar.pcb->cCRC, commVar.CRC) ) {
					CommCenter_ErrorDealEvent(&commVar, 0x00000003, 0x00000004);
					continue;
				}

				//保存文件个数
				commVar.FiletotleCount = CommCenter_ntohl( CommCenter_strtol(commVar.szStoreBuffer + commVar.nPotS) );
				if(0 >= commVar.FiletotleCount) {
					//一般不可能
					commVar.nStep = CommCenter_FILEWAIT;
					commVar.nStat = CommCenter_PACKETHEAD;
					continue;
				}

#ifdef debug_modul
				sprintf((char *)szOutPutBuff, (char *)"==== COM2: %d %d %d\n", commVar.FiletotleCount, commVar.nPotS, commVar.nPotE);
				EOS_Write(commVar.deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
#endif

				//向父进程发送消息,要求显示“开始传输文件”
				CommCenterThread_Inform(AppRequest_GetFatherPid(), WinGetWindowHwndId(g__winP), CommCenter_FILEREQ, 0, commVar.FiletotleCount, 0);

				//发送响应报文
				if(0 == CommCenter_RspSendFileEvent(&commVar)) {
					//可能出现情况
					commVar.nStep = CommCenter_FILEWAIT;
					commVar.nStat = CommCenter_PACKETHEAD;
					continue;
				} 

				//更新相关数据
				commVar.nStat = CommCenter_PACKETHEAD; //指示接收包头
				commVar.nPotS = 0;
				commVar.nPotE = 0;
				commVar.fStep = FILE_INDEX;

				//完成处理文件个数请求响应
				continue;
			} //end if(CommCenter_FILEREQ == commVar.nStep)

			//b. 发送文件数据
			if(CommCenter_FILEDATA== commVar.nStep) { 
				//1. 取文件索引
				if(FILE_INDEX == commVar.fStep) { 
					if(readcount < sizeof(UInt32)) {
						//包体尚未接收到最小数据长度
						continue;
					}

					//计算包体的CRC16
					commVar.pcb->cCRC = Add_CRC16(commVar.pcb->cCRC, commVar.szStoreBuffer+commVar.nPotS, sizeof(UInt32));

					//检查、更新文件索引
					tmpFIndex = commVar.fcb.nId; 
					commVar.fcb.nId = CommCenter_ntohl( CommCenter_strtol(commVar.szStoreBuffer + commVar.nPotS) );
					if(commVar.fcb.nId != tmpFIndex + 1) {
							//文件顺序错误报告, 处理
							CommCenter_ErrorDealEvent(&commVar, 0x00000004, 0x00000005);
							continue;
					}

#ifdef debug_modul
					sprintf((char *)szOutPutBuff, (char *)"==== COM3: %d %d %d\n", commVar.fcb.nId, commVar.nPotS, commVar.nPotE);
					EOS_Write(commVar.deBugfp, szOutPutBuff, StrLen(szOutPutBuff));
#endif

					//更新其它数据
					commVar.fStep = FILE_PATHLEN;
					commVar.nPotS+= sizeof(UInt32);
					readcount -= sizeof(UInt32);

					//继续处理缓冲区
				} //end 取文件索引

				//2. 取文件路径长度

⌨️ 快捷键说明

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