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

📄 commprotocol.cpp

📁 coldfire5206芯片的boot程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************************************
* 文 件 名:					commprotocol.cpp
* 输入接口:	BOOL StartupComm(COMMINFO stCommInfo)
*				启动通讯
*				INT32 TransferAndAnalyse(UINT32 ulLength, UINT8* pcRecInfo);
*				处理底层接收数据
* 输出接口:	GetSendData(UINT8* pcSendInfo) 		 UINT32 GetCommSendLength();	
*				提供需要发送的数据,然后由底层驱动发送
*				GetRecCommInfo(COMMINFO* stCommInfo) 
*				将通讯结果返回
* 控制接口:	BOOL GetEndCommFlag();
*				当前通讯是否结束
* 说    明:	升级模块有以下值得注意的:
*				1、协议内不能使用动态内存分配,因为可能升级过程中返回原系统
*				2、实际上无论是输入还是输出都是依赖成员m_stCommInfo
*				   对于版本通讯,通过m_stCommInfo保存对方的ver_no,处理后再修改(放入
*                 自己的ver_no)m_stCommInfo并输出  
*				   (m_stCommInfo.commData.verData.ver_no)
*				   对于文件通讯,接收一方,启动通讯时,给出文件保存的位置指针pcFileInfo,
*				   然后通讯种将数据放入pcFileInfo并返回  
*                 (m_stCommInfo.fileData.pcFileInfo)
*				3、注意comm_frame中pack.dataPack包含info指针是永远不能直接使用的,
*					因为除了它之外其他comm_frame结构成员都不是指针,所以不涉及它时,可以直接使用
*				   	pstCommFrame = (CommFrame*) m_acReceiveFrameInfo; 
*					将接收帧直接转化为结构使用,而一旦要使用它时,必须这样使用:
*					memcpy (m_stCommInfo.commData.fileData.pcFileInfo + m_lFileHandlePos,
*						(UINT8*)(m_acReceiveFrameInfo + 20), pstCommFrame->pack.dataPack.length);
*					(pack.dataPack.info是(UINT8*)(m_acReceiveFrameInfo + 20),但不能赋值)
* 作    者:	史梁材
* 创建时间:	2002.07.30          
* 修改记录:
*				(1)	2002.09.11  构造函数CCommProtocol()   合并构造函数,并将构造函数的参数
*								改为缺省参数(见commprotocol.h的函数声明位置)
*				(2) 2002.10.23  完善重发机制,如果是文件传输中的重发,那么需要在重发命令中,加入
*								需要重发的包的序号,对FileCommSend()进行修改
*				(3)	2002.10.25	增加动态文件读取机制,在这种方式下,使用指针函数来m_funcDynamicGetFilePackInfo
*								进行动态文件读取,即每次取一部分文件内容来发送,文件缓冲只需要帧那么大就行
*								利用m_bIsDynamicSendFile来区别并兼容以前的静态文件读取(即一次将所有的文件内容读取在一个缓冲)
*				(4) 2003.02.18	在版本数据结构中,增加硬件类型(主控板的FLASH容量)
*				(5) 2003.04.11  在StartupComm,对于CST_FILE,计算stCmdPack.info.fs.data_pack_num时,
*								发现了问题:对于长度正好是m_nFrameDataMaxSize时,加1处理是不对的,
*								导致发送数据时,造成发送的实际pack_num比FILE_START中发送的文件信息中的少1
***************************************************************************************************/




#include "CommProtocol.h"

//////////////////////////////////////////////////////////////////////
// Construction / Destruction
//////////////////////////////////////////////////////////////////////
CCommProtocol::CCommProtocol(BOOL cpu_is_same, UINT32 frame_size)
{
	m_bCpuIsSame	= cpu_is_same;

	m_lReceivePos  = 0;
	m_lSendSize		= 0;
	m_lReceiveSize = 0;

	m_bHaveSendFrame = 0;

	m_nResendNum = 0;
	m_bCheckoutIsRight = 1;

	m_bIsDynamicSendFile = 0;

	SetFrameSize(frame_size);
}

CCommProtocol::~CCommProtocol()
{
}

/*********************************************************************
* 函数名称:	CCommProtocol::TransferAndAnalyse
* 说	 明:	将底层缓冲中的接收数据移到协议处理缓冲,并校验帧。
*				执行完该函数后,应该立即执行函数GetSendData来
*               确定是否需要会传数据
* 入口参数:
*				UINT32 length -- 当前接受到的数据的长度
*				UINT8 *rec_info -- 当前接收到的数据的指针
*				BOOL bAllDo		-- 1,进行全部处理;0,仅仅做包的完整性检查
* 返 回 值:
*				INT32  --  -1, 错误数据
*							 0, 正确数据
*							 1, 帧结束
* 作	 者:	Shi Liangcai 
* 时	 间:	2002-07-25 14:32:01 
*********************************************************************/
INT32 CCommProtocol::TransferAndAnalyse(UINT32 length, UINT8 *rec_info, BOOL bAllDo)
{
	UINT8* pcInfoPos = NULL;

	if (m_nStatusFlag == CS_NULL && bAllDo == 1)
	{
		m_lReceiveSize = 0;
		m_lReceivePos = 0;
		return -1;
	}

	memcpy(m_acReceiveFrameInfo + m_lReceivePos, rec_info, length);

	if (!m_lReceivePos)	// 判断帧头是否等于0x7e
	{
		if (m_acReceiveFrameInfo[0] != 0x7e)
			return -1;

	}

	m_lReceivePos += length;

	if (m_lReceivePos >= 7)	// 检验长度
	{
		m_lReceiveSize = GetFrameLength();
		if (m_lReceiveSize < MIN_FRAME_LENGTH)	// 长度校验出错,该帧无效
		{
			m_lReceivePos = 0;
			return -1;
		}
	}

	if (m_lReceivePos >= m_lReceiveSize	&& m_lReceivePos >= MIN_FRAME_LENGTH)
	{
		CheckupFrame();		// 帧校验,校验错,则由通讯处理函数组织重发命令

		if (m_bCheckoutIsRight)
			UnformatFrame();
		
		if (bAllDo == 1)
		{
			switch (m_stCommInfo.nCommType)
			{
			case CST_START:			// 初始化通讯发送方处理
				StartCommSend();
				break;

			case CRT_START:			// 初始化通讯接收方处理
				StartCommReceive();
				break;

			case CST_VERSION:		// 版本发送方处理
				VersionCommSend();
				break;

			case CRT_VERSION:		// 版本接收方处理
				VersionCommReceive();
				break;

			case CST_FILE:			// 文件发送方处理
				FileCommSend();				
				break;

			case CRT_FILE:			// 文件接收方处理
				FileCommReceive();
				break;

			case CST_BREAK:			// 中断发送方处理
				BreakCommSend();
				break;

			case CRT_BREAK:			// 中断接收方处理
				BreakCommReceive();
				break;

			case CST_RENEW:
				RenewCommSend();
				break;

			case CRT_RENEW:
				RenewCommReceive();
				break;

			default:
				m_lReceivePos = 0x00;
				m_lReceiveSize = 0x00;
				return -1;
			}
		}
		// 接收帧处理完毕,接收位置复位,等待接收下一帧
		m_lReceiveSize = 0x00;
		m_lReceivePos = 0x00;		
		return 1;
	}

	return 0;
}

/*********************************************************************
* 函数名称:	CCommProtocol::StartupComm
* 说	 明:	启动指定通讯
1、对于无数据通讯,只给出类型
2、对于版本通讯,对于通讯双方,stCommInfo中包含各自的版本信息
3、对于文件通讯,接收和发送的文件缓冲都是由应用提供,本身不提供
发送方stCommInfo中包含将发送的文件信息缓冲指针
接收方stCommInfo中包含将接收文件信息放入的缓冲指针
* 入口参数:
*				CommInfo m_stCommInfo -- 通讯信息
* 返 回 值:
*				BOOL  --  1,启动成功,需要调用GetSendData函数
*						  0,无法启动
* 作者: Shi Liangcai 
* 时间 : 2002-07-30 11:25:48 
*********************************************************************/
BOOL CCommProtocol::StartupComm(COMMINFO stCommInfo)
{
	CmdPack stCmdPack;

	memcpy((UINT8*)(&m_stCommInfo), (UINT8*)(&stCommInfo), sizeof(COMMINFO));

	// 清通讯标志
	m_bHaveSendFrame = 0;
	m_nResendNum = 0;
	m_bCheckoutIsRight = 1;
	m_nCommEndFlag = CET_NOT;

	switch (m_stCommInfo.nCommType)
	{
	case CST_START:			// 初始化通讯
		stCmdPack.type = CMD_START;
		stCmdPack.length = 0x00;
		FormatFrame(CPT_CMD, &stCmdPack);
		m_nStatusFlag = CSS_START_WAIT_YES;
		break;

	case CST_VERSION:		// 版本
		stCmdPack.type = CMD_VERSION;
		stCmdPack.length = 0x14;
		stCmdPack.info.ver.soft_no = m_stCommInfo.commData.verData.soft_no;
		memcpy(stCmdPack.info.ver.ver_info, m_stCommInfo.commData.verData.ver_info, 4);
		stCmdPack.info.ver.flash_no = m_stCommInfo.commData.verData.flash_no;
		stCmdPack.info.ver.module_no = m_stCommInfo.commData.verData.module_no;
		FormatFrame(CPT_CMD, &stCmdPack);
		m_nStatusFlag = CSS_VERSION_WAIT_AV;
		break;

	case CST_FILE:			// 文件发送方处理
		stCmdPack.type = CMD_FILESTART;
		stCmdPack.length = 0x14;
		if (m_stCommInfo.commData.fileData.lFileLength % m_nFrameDataMaxSize)
			stCmdPack.info.fs.data_pack_num = m_stCommInfo.commData.fileData.lFileLength / m_nFrameDataMaxSize + 1;
		else
			stCmdPack.info.fs.data_pack_num = m_stCommInfo.commData.fileData.lFileLength / m_nFrameDataMaxSize;
		stCmdPack.info.fs.file_no = m_stCommInfo.commData.fileData.file_no;
		stCmdPack.info.fs.file_type = m_stCommInfo.commData.fileData.file_type;
		memcpy(stCmdPack.info.fs.file_name, m_stCommInfo.commData.fileData.file_name, FIELD_FILE_NAME_LENGTH);
		m_lFileHandlePos = 0;
		FormatFrame(CPT_CMD, &stCmdPack);
		m_nStatusFlag = CSS_FILE_WAIT_SYES;
		break;

	case CST_BREAK:			// 中断通讯
		stCmdPack.type = CMD_BREAK;
		stCmdPack.length = 0x00;
		FormatFrame(CPT_CMD, &stCmdPack);
		m_nStatusFlag = CSS_BREAK_WAIT_YES;
		break;

	case CST_RENEW:			// 更新通讯发送
		stCmdPack.type = CMD_RENEW;
		stCmdPack.length = 0x01;
		stCmdPack.info.rn.cResultFlag = m_stCommInfo.commData.renewData.cResultFlag;
		FormatFrame(CPT_CMD, &stCmdPack);
		m_nStatusFlag = CSS_RENEW_WAIT_YES;
		break;

	case CRT_VERSION:		// 版本通讯接收
		m_nStatusFlag =  CSR_VERSION_WAIT_RV;
		break;

	case CRT_FILE:			// 文件通讯接收
		m_nStatusFlag = CSR_FILE_WAIT_SCMD;
		break;
	case CRT_BREAK:			// 中断通讯接收
		m_nStatusFlag = CSR_BREAK_WAIT_BCMD;
		break;

	case CRT_START:			// 初始化通讯
		m_nStatusFlag = CSR_START_WAIT_CMD;
		break;

	case CRT_RENEW:			// 更新通讯接收
		m_nStatusFlag = CSR_RENEW_WAIT_CMD;
		break;

	default:
		return 0;
	}

	return 1;
}

/*********************************************************************
* 函数名称:	CCommProtocol::GetSendData
* 说	 明:	将需要的回传(应答)数据返回给底层驱动,然后发送数据无效;
*				如果不需要,那么返回NULL
*				此外,将通讯状态置位等待
*
* 入口参数:
*				UINT8* pcSendInfo -- 返回发送数据的指针,
*						长度由GetSendLength返回,不使用结束符
* 返 回 值:
*				void  -- 
* 作	 者:	Shi Liangcai 
* 时	 间:	2002-07-30 09:16:39 
*********************************************************************/
void CCommProtocol::GetSendData(UINT8* pcSendInfo)
{
	if (m_bHaveSendFrame)
	{
		memcpy(pcSendInfo, m_acSendFrameInfo, m_lSendSize);
		m_bHaveSendFrame = 0;
	}

	return;
}



/*********************************************************************
* 函数名称:	CCommProtocol::GetEndCommFlag
* 说	 明:	目前执行的通讯是否结束
* 入口参数:
* 返 回 值:
*				通讯结束标志,见enum CommEndType
* 作	 者:	Shi Liangcai 
* 时	 间:	2002-08-01 08:48:56 
*********************************************************************/
UINT32 CCommProtocol::GetEndCommFlag()
{
	if (m_nStatusFlag == CT_NULL)
		return m_nCommEndFlag;
	else
		return CET_NOT;
}

/*********************************************************************
* 函数名称:	CCommProtocol::GetRecCommInfo
* 说	 明:	返回通讯结果
* 入口参数:
*				CommInfo* pstCommInfo -- 通讯信息
* 返 回 值:
*				void  -- 
* 作	 者:	Shi Liangcai 
* 时	 间:	2002-08-07 11:18:59 
*********************************************************************/
void CCommProtocol::GetRecCommInfo(COMMINFO* pstCommInfo)
{
	memcpy((UINT8*)(pstCommInfo), (UINT8*)(&m_stCommInfo), sizeof(COMMINFO));

	return;
}
/*********************************************************************
* 函数名称:CCommProtocol::GetCommSendLength
* 说明:
* 入口参数:
* 返回值:
* UINT32  -- 桢长度
* 作者: Shi Liangcai 
* 时间 : 2002-08-07 11:17:40 
*********************************************************************/
UINT32 CCommProtocol::GetCommSendLength()
{
	if (m_bHaveSendFrame)
		return m_lSendSize;
	else
		return 0;
}


/*********************************************************************
* 函数名称:	CCommProtocol::CheckupData
* 说	 明:	对一段信息(字符串)进行校验
* 入口参数:
*				UINT8 *pcData -- 校验目标字符串
*				UINT32 lDataLen -- 校验字符串的长度
*				UINT32 lCode -- 校验码
*				UINT16 nValueByteNum -- 校验结果取几个字节
* 返 回 值:
*				BOOL  -- 1,校验正确;0,校验失败
* 作	 者:	Shi Liangcai 
* 时	 间:	2002-07-31 08:47:10 
*********************************************************************/
BOOL CCommProtocol::CheckupData(UINT8 *pcData, UINT32 lDataLen, UINT32 lCheckCode, UINT16 nValueByteNum)
{
	UINT32 i;
	UINT32 lCode;

	lCode = 0;
	for (i = 0; i < lDataLen; i ++)
	{
		lCode += *(pcData + i);
	}

	switch (nValueByteNum)
	{
	case 1:
		lCode = (UINT8)lCode;
		break;

	case 2:
		lCode = (UINT16)lCode;
		break;

	default:		// 其他情况均看做4个字节,32位的校验码
		break;
	}

	if (lCode == lCheckCode)
		return TRUE;
	else
		return FALSE;

}

⌨️ 快捷键说明

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