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

📄 message.cpp

📁 基于Nuleus操作系统和s3c4510的编写的EFC。已经包含了该EFC的设计说明。这是个实际产品的代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		if (pSession->mRecv.uCmdID == CMD_REPORT)
		{	//	Auto report from HDLC
			DispatchAutoReport(*pSession);
		}				
		else if (SUBCMD_RETURN(pSession)) // This message was processed, so we send it to uart or ethernet.
		{
			pSession->mRecv.uLength++;
			pSession->mRecv.uCheckSum = pSession->mRecv.CheckSum();
			if(pSession->mRecv.uPacket >= UART_USER && pSession->mRecv.uPacket <= NET_USER_MAX)
			{
				if (pSession->mRecv.uPacket == UART_USER)
				{
					UartSend(pSession->mRecv);
				}
				else
				{
					DWORD dwPath = m_muUsers[pSession->mRecv.uPacket].dwPath;
					if (dwPath)
					{
						NetSend(pSession->mRecv, dwPath);
					}
				}
			}
			else
			{
#ifdef _DEBUG
				printf("Return CMD packet error\n");
#endif
			}
			
			pSession->FreeMessage();
		}
		else  // This command was not processed, we must dispose it.
		{	// remote command
			if (pSession->mRecv.uCmdID == CMD_TFTP)
			{
				m_dwLength = pMsgQueue->dwMsgLength;
			}
			DisposeCmd(*pSession);
		}
	}

	return TRUE;
}

// Firmware upgrade from TFTP server
// Process command CMD_TFTP
void CMessage::OnTftp(SESSION &session)
{
	MESSAGE &mSend = session.mSend;
	MESSAGE &mRecv = session.mRecv;

	// Only one task is permitted at one time
	if ((FindTask("TFTPClientPutTask") != NULL) 
		|| (FindTask("TFTPClientGetTask") != NULL)		
		|| (FindTask("ModermGetTask") != NULL)
		|| (FindTask("ModermPutTask") != NULL))
	{		
		mSend.puData[0] = (BYTE)-1;// too many users
		return;
	}	

	TASKPARAM *pParam = new TASKPARAM; // delete is in task
	ASSERT(pParam);
	pParam->pParam = GetApp();
	memcpy(&pParam->dwParam, mRecv.puData, 4);
	pParam->strParam = &mRecv.puData[4]; // file name
	pParam->dwOther = mRecv.puData[17];	// file type
	pParam->nParam = session.nID;
	pParam->nOther = 0;		// Default is MCU TFTP uploading
	mSend.SetLength(12);
	
	if (pParam->dwOther == TFTP_FPGA) // FPGA upload or backup
	{	
		CFlash *pcFlash = m_pcdDevice->GetFlash();
		ASSERT(pcFlash);
		FLASH_SECTOR fs; // flash sector information
		VERIFY(pcFlash->Lookup(SECTOR_FPGA_MIN, fs));
		for(int i = 0; i < 4; i++)
		{
			if(VPbyte(fs.dwAddr) != 0x5A)
			{
				mSend.puData[0] = 1;	// no Fpga data
				delete pParam;
				return;
			}
		}
	}	
	
	if (mRecv.uSubCmd & 0x01) // It is a distributed system
	{
		if ((mRecv.uSubCmd & 0x06) == 0)//uart
		{
			if (mRecv.puData[18] == 0x0) //mcu
			{					
				if (SUBCMD_READ) // Backup
				{						
					VERIFY(CreateTask("ModermPutTask", (PFNTASK)&CMessage::ModermPutTask, 
						0, pParam));						
				}
				else // Upload
				{						
					VERIFY(CreateTask("ModermGetTask", (PFNTASK)&CMessage::ModermGetTask, 
						0, pParam));						
					m_pcdDevice->SetRedLed(TRUE);						
				}															
			}
			else//swh and liu
			{
				pParam->nOther = 1;  // Sub board uploading												
			}

			mSend.puData[0] = 0; // Thread started successfully.			
		}
		else//net
		{
			if (mRecv.puData[18] == 0x0)//mcu
			{									
				if (SUBCMD_READ) // backup file
				{					
					VERIFY(CreateTask("TFTPClientPutTask",
						(PFNTASK)&CMessage::TFTPClientPutTask, 0, pParam));						
				}
				else // upgrade
				{						
					VERIFY(CreateTask("TFTPClientGetTask",
						(PFNTASK)&CMessage::TFTPClientGetTask, 0, pParam));						
					m_pcdDevice->SetRedLed(TRUE);						
				}				
			}
			else if (SUBCMD_WRITE) // sub board upload
			{		
				pParam->nOther = 1;  // Sub board uploading
				VERIFY(CreateTask("TFTPClientGetTask",
					(PFNTASK)&CMessage::TFTPClientGetTask, 0, pParam));								
			}	
			mSend.puData[0] = 0; // Thread started successfully.
		}
	}
	//no slave board
	else
	{		
		if ((mRecv.uSubCmd & 0x06) == 0) // Uart 
		{
			if (SUBCMD_READ) // Backup
			{
				VERIFY(CreateTask("ModermPutTask", (PFNTASK)&CMessage::ModermPutTask, 
					0, pParam));					
			}
			else // Upgrade
			{
				VERIFY(CreateTask("ModermGetTask", (PFNTASK)&CMessage::ModermGetTask, 
					0, pParam));
				m_pcdDevice->SetRedLed(TRUE);				
			}			
		}
		else // Net
		{
			if (SUBCMD_READ) // Backup
			{
				VERIFY(CreateTask("TFTPClientPutTask",
					(PFNTASK)&CMessage::TFTPClientPutTask, 0, pParam));				
			}
			else // Upgrade
			{			
				VERIFY(CreateTask("TFTPClientGetTask",
					(PFNTASK)&CMessage::TFTPClientGetTask, 0, pParam));					
				m_pcdDevice->SetRedLed(TRUE);				
			}			
		}
		mSend.puData[0] = 0;// Thread started successfully.
	}
}

// Moderm Protocol Get Task
void CMessage::ModermGetTask(DWORD argc, void *argv)
{
	UNUSED(argc);
	ASSERT(argv);

	//
	// get the parameters passed by argv
	//
	TASKPARAM *pParam = (TASKPARAM*)argv;	// task parameter
	DWORD dwType = pParam->dwOther;	// file type (0:app, 1:bios, 2:system.ini)
//	BOOL bSlaveUpload = (pParam->nOther == 1) ? TRUE : FALSE;
	int nID = pParam->nParam; // session id, it should be -1.
	delete pParam;

	SESSION *pSession = NULL;
	m_mapSessions.Lookup(nID, pSession);
	ASSERT(pSession);
	ASSERT(pSession->nID == nID);	
	
	// Delay 100ms to make sure sending completely to console.
	Sleep(100);
	m_bModemUsing = TRUE; // Uart is using by modem protocol.
	// Initiailize Y modem protocol
	xyModem_Init(PROTOCOL_YMODEM, COMM_SERIAL, 0);		
	int nReadCount = xyModem_Get(); // Get data by modem protocol		
	
	if (nReadCount <= 0) // Error occured.
	{		
		TRACE("Upload failed.(%d)\n", nReadCount);		
	}
	else
	{	
		if (dwType == TFTP_APP || dwType == TFTP_BIOS || dwType == TFTP_FPGA)
		{// bios or application
			///////////////////////////////////////////////////////////////////////
			// insure that data area not to be destroied.
			if (nReadCount > (SECTOR_APP_MAX - SECTOR_APP_MIN + 1) << 16)
				nReadCount = (SECTOR_APP_MAX - SECTOR_APP_MIN + 1) << 16;
			///////////////////////////////////////////////////////////////////////
			
			// get system flash chip object
			ASSERT(m_pcdDevice);
			CFlash *pcFlash = m_pcdDevice->GetFlash();
			ASSERT(pcFlash);
			FLASH_SECTOR fs; // flash sector information
			
			// Calculate the min. & max. sector number required by bios or app.
			UINT nMinSector = (dwType == TFTP_APP) ? SECTOR_APP_MIN : SECTOR_BIOS_MIN;
			nMinSector = (dwType == TFTP_FPGA) ? SECTOR_FPGA_MIN : nMinSector;
			UINT nMaxSector = nMinSector - 1;
			for (DWORD dwSize = 0; dwSize < (DWORD)nReadCount;)
			{
				nMaxSector++;
				if (!pcFlash->Lookup(nMaxSector, fs))
				{// sector not found
					nMaxSector--;
					break;
				}
				dwSize += fs.dwSize;
			}
			ASSERT(dwType == TFTP_APP || dwType == TFTP_FPGA || nMaxSector < 4); // sectors for bios: 0-3
			
			// percent increment of every step.
			BYTE uIncrement = 100 / (nMaxSector - nMinSector + 1);
			BYTE uPercent = 0; // progress percent.
			for (UINT nSec = nMinSector; nSec <= nMaxSector; nSec++)
			{// erase the required sectors
				VERIFY(pcFlash->EraseSector(nSec));
				// auto report progress of erasing flash.
				uPercent += uIncrement;
				ProgressReport(1, uPercent, *pSession);
				Sleep(2); // sleep so other task can run.
			}
			if (uPercent < 100)
			{// auto report that flash erasing finished.
				ProgressReport(1, 100, *pSession);
				Sleep(2); // sleep so other task can run.
			}
		
			// file is divided to 100 parts
			if(dwType == TFTP_FPGA)
			{			
				nReadCount += 0x10; // add Flag and length
			}
			
			int nBlockSize = nReadCount / 100 + ((nReadCount % 100) ? 1 : 0);		
			ASSERT(nBlockSize * 100 >= nReadCount);
			BYTE *puBuff = new BYTE[nBlockSize];// buffer used to program to flash
			ASSERT(puBuff);
			
			VERIFY(pcFlash->Lookup(nMinSector, fs));
			
			for (uPercent = 1; uPercent <= 100; uPercent++)
			{// Program binary file to flash
				if(uPercent == 1 && dwType == TFTP_FPGA)
				{	// write FPGA head frame
					memset(puBuff, 0x5A, 0x10);			//  write Flag				
					memcpy(&puBuff[12], &nReadCount, 4);	//	write length
					
					nReadCount = xyModem_GetData(&puBuff[0x10], nBlockSize - 0x10);
					nReadCount += 0x10;
				}
				else
				{
					nReadCount = xyModem_GetData(puBuff, nBlockSize);
				}
				VERIFY(pcFlash->Write(fs.dwAddr, puBuff, nReadCount));
				fs.dwAddr += nReadCount;
				// report current progress to console.
				ProgressReport(2, uPercent, *pSession);
				Sleep(2); // sleep so other task can run
			}
			
			delete[] puBuff;							
		}
		else if (dwType == TFTP_FILE)
		{
			// data file: System.ini
			CMemFile file;
			BYTE buff[1024]; // buffer used to program to flash			
			do
			{
				nReadCount = xyModem_GetData(buff, sizeof(buff));
				file.Write(buff, nReadCount);
				
			} while (nReadCount > 0);
			
			file.SeekToBegin();
			
			// Get system data
			OnGetSysDataFromFile(file);	
			
			// Set save flag
			m_pcdDevice->SetFlagLoaddef(pSession->mRecv.uPacket);
			GetApp()->SetModifiedFlag();					 
		}
	}	

	// Free the memory allocated by modem protocol.
	xyModem_Free(); 		
	m_bModemUsing = FALSE;

	// If it is not uploading user data, 
	// we must restart system by disable watchdog.
	if (dwType != TFTP_FILE)
	{
		Sleep(1000); // sleep 1s
		Disable_Int(nGLOBAL_INT); // disable INT so watchdog can work.
	}
	else
		m_pcdDevice->SetRedLed(FALSE);
	
	// Deletes the finished task.
	VERIFY(DeleteTask("ModermGetTask"));
	ASSERT(m_bModemUsing == FALSE);
}

//Modem Protocol Put Task
void CMessage::ModermPutTask(DWORD argc, void *argv)
{
	UNUSED(argc);
	
	TASKPARAM *pParam = (TASKPARAM*)argv;	// task parameter
	CString strFileName = pParam->strParam;	// name of the file		
	DWORD dwType = pParam->dwOther;	// file type (0:app, 1:bios, 2:system.ini)
	int nID = pParam->nParam; //  session id
	delete pParam;

	SESSION *pSession = NULL;
	m_mapSessions.Lookup(nID, pSession);
	ASSERT(pSession);
	ASSERT(pSession->nID == nID);	
	
	LPSTR lpszFile = (LPSTR)(LPCSTR)strFileName;// name of the file
	BYTE *puSend = NULL;       // The data to send by modem protocol.
	DWORD dwTotalLen = 0;  // The total bytes of sending by modem protocol.

	// Delay 100ms to make sure sending completely to console.
	Sleep(100);
	m_bModemUsing = TRUE; // Uart is using by modem protocol.
	// Initialize modem protocol, Y modem with uart port 0.
	xyModem_Init(PROTOCOL_YMODEM, COMM_SERIAL, 0);

	//App
	if ((dwType == TFTP_APP) || (dwType == TFTP_BIOS))
	{
		CFlash *pcFlash = m_pcdDevice->GetFlash();
		ASSERT(pcFlash);
		FLASH_SECTOR fs; // flash sector information
		UINT nMinSector = (dwType == TFTP_APP) ? SECTOR_APP_MIN : SECTOR_BIOS_MIN;
		UINT nMaxSector = (dwType == TFTP_APP) ? SECTOR_APP_MAX : SECTOR_BIOS_MAX;

		// Get total data length.
		for (UINT i = nMinSector; i <= nMaxSector; i++)
		{
			VERIFY(pcFlash->Lookup(i, fs));
			dwTotalLen += fs.dwSize;
		}
		
		puSend = new BYTE[dwTotalLen];
		ASSERT(puSend);

		// Copy data from flash
		VERIFY(pcFlash->Lookup(nMinSector, fs));
		memcpy(puSend, (char*)fs.dwAddr, dwTotalLen);		
	}
	//File
	else if (dwType == 0x02)
	{
		// data file
		BYTE buff[1024];
		CMemFile file;		
		UINT nCount = 0;		
		
		// Put user data to a file.
		OnPutSysDataToFile(file);
		dwTotalLen = file.GetLength();		
		file.SeekToBegin();

		puSend = new BYTE[dwTotalLen];
		ASSERT(puSend);	
		BYTE *pBuf = puSend;

		do
		{
			nCount = file.Read(buff, sizeof(buff));
			memcpy(pBuf, buff, nCount);	
			pBuf += nCount;
		} while (nCount > 0);			
	}	
	else
	{
		TRACE("Nonsupport uploading!\n");		
	}

	if (dwTotalLen > 0)
	{
		// Sending data by modem protocol
		xyModem_Put(puSend, dwTotalLen, lpszFile);
		m_bModemUsing = FALSE;
		delete [] puSend;
	}	
	
	DeleteTask("ModermPutTask");
	ASSERT(m_bModemUsing == FALSE);
}

// Get system data from a file
BOOL CMessage::OnGetSysDataFromFile(CFile &file)
{
	GetApp()->LoadFromFile(file, 1);
	return TRUE;
}

// Put system data to a file
BOOL CMessage::OnPutSysDataToFile(CFile &file)
{
	GetApp()->SaveToFile(file, 1);
	return TRUE;
}

// auto report the progress of firmware upgrading.
void CMessage::ProgressReport(BYTE uType, BYTE uProgress, SESSION &session)
{
	session.mSend.SetLength(13);
	m_pcdDevice->GetAddr(session.mSend.aSrcAddr);
	session.mSend.uCmdID = CMD_TFTP;
	session.mSend.uSubCmd = 0xC0;
	session.mSend.puData[0] = uType;
	session.mSend.puData[1] = uProgress;
	(session.nID == -1) ? 
		UartSend(session.mSend) : NetSend(session.mSend, session.nID);
	session.FreeMessage();
}

// Mac address
// Process command CMD_MAC_ADDRESS
void CMessage::OnMacAddress(SESSION &session)
{
	MESSAGE &mRecv = session.mRecv;
	MESSAGE &mSend = session.mSend;

	ASSERT(m_pcdDevice);

	NETDEVICE ndDevice;
	m_pcdDevice->GetNetDevice(ndDevice);
	if (SUBCMD_WRITE)
	{
		memcpy(ndDevice.auMac, mRecv.puData, sizeof(ndDevice.auMac));
		m_pcdDevice->SetNetDevice(ndDevice, CONFIG_MAC);
	}
	else
	{
		mSend.SetLength(17);
		memcpy(mSend.puData, ndDevice.auMac, sizeof(ndDevice.auMac));
	}
}

// TCP/IP Property
// Process command CMD_TCPIP
void CMessage::OnTcpip(SESSION &session)
{
	MESSAGE &mRecv = session.mRecv;
	MESSAGE &mSend = session.mSend;

	ASSERT(m_pcdDevice);

	NETDEVICE ndDevice;
	m_pcdDevice->GetNetDevice(ndDevice);
	int i;
	if (SUBCMD_WRITE)
	{
		for (i = 0; i < 4; i++)
		{// copy ip address, subnet mask & gateway
			ndDevice.auIP[i] = mRecv.puData[i];
			ndDevice.auSubnet[i] = mRecv.puData[4 + i];
			ndDevice.auGateway[i] = mRecv.puData[8 + i];
		}
		UINT nPort = MAKEWORD(mRecv.puData[13], mRecv.puData[12]);
		if (nPort != ndDevice.nPort)
		{// restarting system is required when port is modified.
			ndDevice.nPort = nPort;
			m_pcdDevice->Reset(1);
		}
		m_pcdDevice->SetNetDevice(ndDevice, CONFIG_IP);
	}
	else
	{
		mSend.SetLength(25);
		for (i = 0; i < 4; i++)
		{
			mSend.puData[i] = ndDevice.auIP[i];

⌨️ 快捷键说明

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