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

📄 xmodem.c

📁 原创:xmodem协议介绍及VxWorks下的应用 最初
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************  文 件 名   : xmodem.c  功能描述   : xmodem协议的实现  创建日期   : 2008年6月28日  作    者   : gateWay  修改记录   : ******************************************************************************/#include "vxWorks.h"#include "stdio.h"#include "fioLib.h"#include "timers.h"#include "string.h"#include "taskLib.h"#include "sysLib.h"#include "tickLib.h"#include "ioLib.h"#include "config.h"#include "t_xmodem.h"extern void memcopy ( S8 *pcDest, const S8 *pcSource, U32 ulLength);/*xmodem协议的公共属性记录*/XMODEM_PROPERTY_STRUCT g_xmodemProperty;U32 g_linkState;/*连接状态记录*/U32 g_ulRetry;  /*重试记录*/U32 g_ulOldTicks;/*ticks记录*/U32 g_ulFileMaxLen; /*加载的最大文件长度,从入参获取到*//* 发送一个字符*/void putChar(U8 *uchar){	write(STD_OUT,(U8 *)uchar,1);}/* 接收一个字符*/STATUS getChar(U8 *uchar){    int bytesRead;    (void) ioctl( STD_IN, FIONREAD, (int) &bytesRead);    if (bytesRead != 0)    {        (void)read(STD_IN, (char *)uchar,1);		        return XMODEM_OK;    }    else        return XMODEM_ERROR;}/*清空缓冲区*/static void flushSerial(void){	(void) ioctl (STD_IN, FIOFLUSH, 0);	(void) ioctl (STD_OUT, FIOFLUSH, 0);}/*CRC计算*/U16 CRC16_CCITT (U8 *ptr, S32 count){     U16 usCrc;	 U8 * pTmp;     U16 i;     usCrc = 0;     pTmp = ptr;     while (--count >= 0)     {          usCrc = usCrc ^ ((U16)( *pTmp++ ) << 8);          for ( i = 0; i < 8; ++i)          {               if ( usCrc & 0x8000 )                   usCrc = (U16)( usCrc << 1) ^ 0x1021 ;               else                   usCrc = (U16)(usCrc << 1);          }      }     return (usCrc & 0xFFFF);}/***************************************************************************** 函 数 名  : xModemDateCheck(void) 功能描述  : 检查xmodem数据是否正确 日    期  : 2008年6月26日 作    者  : gateWay 说    明  : 正确则返回0,否则返回0xff。*****************************************************************************/static S32 xModemDateCheck(void){	U32 ulDateLen;	U16 usCrc,usTcrc;	U8 ucCks = 0;	U32 i;	ulDateLen = g_xmodemProperty.ulProSize;	if (g_xmodemProperty.ucCheckType) 	{		usCrc = CRC16_CCITT(&(g_xmodemProperty.pPacketData[2]), ulDateLen);		usTcrc = ((g_xmodemProperty.pPacketData[ulDateLen + 2])<<8) + 			(g_xmodemProperty.pPacketData[ulDateLen + 3]);		if (usCrc == usTcrc)			return XMODEM_OK;	}	else 	{		for (i = 2; i < ulDateLen + 2; i++) 		{			ucCks += (g_xmodemProperty.pPacketData[i]);		}		if (ucCks == g_xmodemProperty.pPacketData[ulDateLen + 2])		return XMODEM_OK;	}	return XMODEM_ERROR;}/***************************************************************************** 函 数 名  : xModemLink(void) 功能描述  : xmodem接收端发起连接 日    期  : 2008年6月26日 作    者  : gateWay 说    明  : 正确则返回0,否则返回0xff。*****************************************************************************/STATUS xModemLink(void){	U8 ucData;	if(OK == getChar(&ucData))	{		switch ( ucData )		{			case SOH:/*收到SOH则为xmodem协议*/			  g_xmodemProperty.ulProSize = XMODEM_DATA_LENGTH;			  g_linkState = RECEIVE_DATA;			  g_ulRetry = 0;			  g_ulOldTicks = tickGet() + (U32)sysClkRateGet();			  return XMODEM_OK;			case STX:/*收到STX则为1K xmodem协议*/			  g_xmodemProperty.ulProSize =  XMODEM_1K_LENGTH;			  g_linkState = RECEIVE_DATA;			  g_ulRetry = 0;			  g_ulOldTicks = tickGet() + (U32)sysClkRateGet();			  return XMODEM_OK;			  			 case EOT:/*收到EOT文件传输结束*/			  ucData = ACK ;			  putChar(&ucData);			  g_linkState = END_OF_LINK;			  return XMODEM_OK;			  		     case CAN:/*收到CAN文件传输取消*/		      g_linkState = XMODEM_REMOTE_CANCELES;				 return XMODEM_ERROR;			 default:   			  break;		}	}	return XMODEM_OK;}/***************************************************************************** 函 数 名  : xModemGetPacket(void) 功能描述  : xmodem接收一个数据包(c除包头),并校验数据 日    期  : 2008年6月26日 作    者  : gateWay 说    明  : 正确则返回0,否则返回0xff。*****************************************************************************/	STATUS xModemGetPacket(void){	U8 ucData;	U32 ulReceiveSize;	U32 ulLenTemp;	/*将数据放到包缓冲区中*/	if(XMODEM_OK == getChar(&ucData))	{		g_xmodemProperty.pPacketData[g_xmodemProperty.ulLenTemps++] = ucData;		g_ulRetry = 0;		g_ulOldTicks = tickGet() + (U32)sysClkRateGet();	}	ulReceiveSize = g_xmodemProperty.ulProSize + (g_xmodemProperty.ucCheckType ? 1:0 ) + 3;	/*如果收到一包数据*/	if(g_xmodemProperty.ulLenTemps == ulReceiveSize)	{			/*包序列校验及数据校验*/		if (g_xmodemProperty.pPacketData[0] == (unsigned char)(~g_xmodemProperty.pPacketData[1]) && 		(g_xmodemProperty.pPacketData[0] == (g_xmodemProperty.ucPacketNo + 1) || 		(g_xmodemProperty.pPacketData[0] == 0 && (g_xmodemProperty.ucPacketNo == MAX_SEQNO ))) &&		(XMODEM_OK == xModemDateCheck( )))		{			ulLenTemp = g_ulFileMaxLen - g_xmodemProperty.ulDataLength;			if(ulLenTemp >= g_xmodemProperty.ulProSize)			{				ulLenTemp = g_xmodemProperty.ulProSize;			}			g_xmodemProperty.ulDataLength += ulLenTemp;		    memcopy ( g_xmodemProperty.pDataPtr, &g_xmodemProperty.pPacketData[2], ulLenTemp);	        g_xmodemProperty.pDataPtr += ulLenTemp;			if(ulLenTemp < g_xmodemProperty.ulProSize)			{				/*如果文件大小超过传入的最大字节数则取消文件传输*/				/* 最大字节数由xmodemReceive函数的U32 *pLength参数决定*/				ucData = CAN ;		        putChar( &ucData );				ucData = CAN ;		        putChar( &ucData );		        g_linkState = XMODEM_FILE_TOO_LONG;				return XMODEM_OK;							}			else			{				    /* 数据包正确则回应ACK*/				ucData = ACK ;		        putChar( &ucData );		        g_xmodemProperty.ucPacketNo = g_xmodemProperty.pPacketData[0];			}		}		else		{				/* 数据包正确则回应NAK*/			ucData = NAK ;	        putChar ( &ucData );		}		g_xmodemProperty.ulLenTemps = 0;		g_linkState = START_OF_LINK;		return XMODEM_OK;	}	return XMODEM_OK;}/***************************************************************************** 函 数 名  : STATUS xmodemReceive(unsigned char *pBuffer, U32 *pLength) 功能描述  : xmodem接收数据接口函数 日    期  : 2008年6月26日 作    者  : gateWay 说    明  : pLength必须将能接收的最大长度放入后再传下来。g_ulFileMaxLen = *pLength;*****************************************************************************/	STATUS xmodemReceive(unsigned char *pBuffer, U32 *pLength){	U8 ucData;	BOOL ulWaitLink = TRUE;	if(NULL == pBuffer)		return XMODEM_ERROR;	/*接收文件的最大长度从传入的参数pLength获取*/	g_ulFileMaxLen = *pLength;	memset(&g_xmodemProperty,0,sizeof(XMODEM_PROPERTY_STRUCT));	g_xmodemProperty.pDataPtr = pBuffer;	g_xmodemProperty.pPacketData = malloc(PACKET_MAX_LEM);/* 1024(XModem 1k数据) + 2(序列号空间) + 2 (crc 空间)+ NULL */	memset(g_xmodemProperty.pPacketData,0,PACKET_MAX_LEM);	g_xmodemProperty.ucCheckType = CHECK_CRC;	g_ulRetry = 0;	g_ulOldTicks = tickGet () + (U32)sysClkRateGet () * WAIT_SOH_TIME ;	flushSerial( );	ucData = C ;    putChar(&ucData);	g_linkState = START_OF_LINK;	while(1)	{	    switch (g_linkState)	    {			case START_OF_LINK:				xModemLink(); /*接收端发起连接后等待回应*/				break;			case RECEIVE_DATA:				ulWaitLink = FALSE;				xModemGetPacket();/*接收数据包*/				break;			case XMODEM_FILE_TOO_LONG:			case END_OF_LINK:				/*将接收到的实际长度赋给 pLength*/				*pLength = g_xmodemProperty.ulDataLength; 				free(g_xmodemProperty.pPacketData);				return XMODEM_OK;			default:				*pLength = 0;				printf("xModem Receive Data Error! Error State: %d\n\r",g_linkState);				free(g_xmodemProperty.pPacketData);				return XMODEM_ERROR;	    }		/*超时计算代码*/		if ( tickGet() >= g_ulOldTicks )		{			  if ( g_ulRetry < MAX_RETRY )			  {			  	  if((START_OF_LINK == g_linkState) && (TRUE == ulWaitLink))			  	  {			  	  	 /*发送C字符超过4次未回应后改用checksum校验*/  				      if(g_ulRetry >= SEND_C_TIMES)				      {					   	  ucData = NAK;

⌨️ 快捷键说明

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