在好例子网,分享、交流、成长!
您当前所在位置:首页C# 开发实例C#语言基础 → ymoldem上位机程序.串口自动更新

ymoldem上位机程序.串口自动更新

C#语言基础

下载此实例
  • 开发语言:C#
  • 实例大小:3.58M
  • 下载次数:38
  • 浏览次数:496
  • 发布时间:2018-12-04
  • 实例类别:C#语言基础
  • 发 布 人:seawindcoco
  • 文件格式:.rar
  • 所需积分:5

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

#include "stdafx.h"
#include "ymodem_tx.h"


#include <string.h> // for memcpy and memset


/**
Minimum time in milli-seconds to wait for response from receiver.
*/
const unsigned SendTimeout = 11*1000;


/**
Process response from receiver.

@param c	Value received from InChar.

@return One if received an ACKnowledge,
		zero if received a Negative AcKnowledge,
		or a negative error value.
*/
int YModemTx::ProcessResponse(int c)
	{
	if(c<0)
		return c;
	if(c==CAN)
		{
		if(CancelCount  )
			return ErrorTranferTerminatedByReceiver;
		return 0;
		}
	CancelCount = 0;
	if(c==ACK)
		return 1;
	return 0;
	}


/**
Begin the Y-Modem transfer.

@param timeout	Time in milliseconds to wait receiver to become ready.

@return Zero if transfer initialisation was successful, or an error code on failure.
*/
int YModemTx::SendInitialise(unsigned timeout)
	{
	if(timeout<SendTimeout)
		timeout = SendTimeout;

	while(InChar(0)>=0) // flush input buffers
		{}

	CancelCount = 0;

	int c;
	for(;;)
		{
		const unsigned timeoutStep = 10;
		c = InChar(timeoutStep);
		if(c=='G')
			{
			SendCRC = true;
			WaitForBlockACK = false;
			break;
			}
		else if(c=='C')
			{
			SendCRC = true;
			WaitForBlockACK = true;
			break;
			}
		else if(c==NAK)
			{
			SendCRC = false;
			WaitForBlockACK = true;
			break;
			}
		if(c<0 && c!=ErrorTimeout)
			return c;
		if(timeout<timeoutStep)
			return ErrorTimeout;
		timeout -= timeoutStep;
		}

	ModeChar = c;
	return 0;
	}


/**
Send a single block of data.
A zero sized block terminates the transfer.

@param data		The data to transfer.
@param size		Size of data.

@return The number of transfered, or an error code on failure.
		The number of bytes may be less than \a size.

@pre SendInitialise() must have been successful.
*/
int YModemTx::SendBlock(const uint8_t* data, size_t size)
	{
	uint8_t block[1 2 1024 2];	// buffer to hold data in the block
	int retryCount = 10;		// number of attempts to send the block
	bool waitForBlockACK = WaitForBlockACK;

change_mode:

	size_t blockSize = (Use1KBlocks && size>=1024) ? 1024 : 128;
	size_t dataSize = size<blockSize ? size : blockSize;	// size of data to send in block

	if(!dataSize)
		{
		// all bytes sent, so end transfer by sending a single EOT...
		block[0] = EOT;
		blockSize = 1;
		waitForBlockACK = true;
		}
	else
		{
		// make block header...
		block[0] = blockSize==1024 ? STX : SOH;
		block[1] = BlockNumber&0xffu;
		block[2] = (~BlockNumber)&0xffu;

		// copy data for block (padding with EOF)...
		memcpy(block 3,data,dataSize);
		memset(block 3 dataSize,26,blockSize-dataSize);

		// append checksum/crc...
		if(SendCRC)
			{
			uint16_t crc = CRC16(block 3,blockSize);
			blockSize  = 3;
			block[blockSize  ] = (uint8_t)(crc>>8);
			block[blockSize  ] = (uint8_t)crc;
			}
		else
			{
			uint8_t sum = Checksum(block 3,blockSize);
			blockSize  = 3;
			block[blockSize  ] = sum;
			}
		}

do_retry:
	// count attenpts...
	if(!retryCount--)
		return ErrorBlockRetriesExceded;

	uint8_t* out = block;
	size_t outSize = blockSize;
	for(;;)
		{
		// send some data...
		int result = Port.Out(out,outSize,1000);
		if(result<0)
			return result; // return error
		if(result==0)
			return ErrorTimeout;

		// adjust for data remaining...
		out  = result;
		outSize -= result;

		// end if done...
		if(!outSize)
			break;

		// poll for signal from receiver...
		result = ProcessResponse(InChar(10));
		if(result==ErrorTimeout)
			continue; // nothing received
		if(result<0)
			return result; // return error
		if(!result)
			goto retry; // negative acknowledge received
		}

	if(waitForBlockACK)
		{
		// wait for up to one second for block to be acknowledged...
		int c = InChar(1000);
		int result = ProcessResponse(c);
		if(result<0)
			return result; // return error
		if(!result)
			{
			// negagtive acknowledge received...
			if(c=='C' && !SendCRC)
				{
				// change to CRC mode if receiver sent 'C', and retry...
				SendCRC = true;
				goto change_mode;
				}
			goto retry;
			}
		}
	else
		{
		// check for receiver sending a cancel byte...
		int result = ProcessResponse(InChar(0));
		if(result<0)
			{
			if(result!=ErrorTimeout)
				return result; // return error if it's not a timeout
			}
		else
			{
			// ignore other responses
			}
		}

	// block transferred OK...
	  BlockNumber;
	return dataSize;

retry:
	while(InChar(500)>=0) // flush input buffers
		{}
	goto do_retry;
	}


/**
Send data.
A zero sized block terminates the transfer.

@param data		The data to transfer.
@param size		Size of data.

@return Zero if successful, or a negative error value if failed.

@pre SendInitialise() must have been successful.
*/
int YModemTx::SendData(const uint8_t* data, size_t size)
	{
	do
		{
		int result = SendBlock(data, size);
		if(result<0)
			return result;
		data  = result;
		size -= result;
		}
	while(size);
	return 0;
	}


/**
Send an entire stread of data.

@param in	The stream of data to send.

@return Zero if successful, or a negative error value if failed.

@pre SendInitialise() must have been successful.
*/
int YModemTx::SendAll(InStream& in)
	{
	BlockNumber = 1; // first block to send is number one
	size_t size;
	do
		{
		// get data from input stream...
		uint8_t data[1024];
		int result = in.In(data,sizeof(data));
		if(result<0)
			return ErrorInputStreamError;

		// send data...
		size = result;
		result = SendData(data,size);
		if(result<0)
			return result;
		}
	while(size); // end when no more data left
	return 0;
	}


/**
Construct the data for the first block of a Y-Modem transfer.

@param[out] buffer		The buffer to store the constructed block. Size must be >=128 bytes.
@param fileName			The name of the file being transferred.
@param fileSize			The size of the file being transferred.

@return Zero if successful, or a negative error value if failed.
*/
int YModemTx::MakeBlock0(uint8_t* buffer, const char* fileName, size_t fileSize)
	{
	// setup buffer for block 0...
	uint8_t* out = buffer;
	uint8_t* outEnd = buffer 128-1;
	memset(buffer,0,128);

	// copy file name to block data...
	while(out<outEnd)
		{
		char c = *fileName  ;
		if(c>='A' && c<='Z')
			c  = 'a'-'A';	// convert name to lower-case
		else if(c=='\\')
			c = '/';		// convert back-slash to forward-slash
		*out   = c;
		if(!c)
			break;			// end of name
		}

	// convert fileSize to a decimal number...
	char length[sizeof(size_t)*3 1]; // buffer big enough to hold length as decimal number
	char* lenEnd = length sizeof(length);
	char* len = lenEnd;
	do
		{
		*--len = '0' fileSize%10;	// prepend digit to buffer
		fileSize /= 10;
		}
	while(fileSize);				// end when all digits done

	// append file length to block data...
	while(out<outEnd && len<lenEnd)
		*out   = *len  ;

	// check that buffer was big enough...
	if(out>=outEnd)
		return ErrorFileNameTooLong;

	return 0; // OK
	}


YModemTx::YModemTx(SerialPort& port)
	: YModem(port)
	{
	}


int YModemTx::SendX(InStream& in, unsigned timeout, bool kMode)
	{
	Use1KBlocks = kMode;
	int result = SendInitialise(timeout);
	if(result<0)
		return result;
	return SendAll(in);
	}


int YModemTx::SendY(const char* fileName, size_t size, InStream& in, unsigned timeout)
	{
	Use1KBlocks = true;
	uint8_t buffer[128];
	int result = MakeBlock0(buffer,fileName,size);
	if(result<0)
		return result;

	result = SendInitialise(timeout);
	if(result<0 && result!=ErrorBlockRetriesExceded)
		return result;

	BlockNumber = 0;
	result = SendBlock(buffer,sizeof(buffer));
	if(result<0)
		return result;

	result = InChar(SendTimeout);
	if(result<0)
		return result;
	if(result!=ModeChar)
		return ErrorReceiverNotBehaving;

	result = SendAll(in);
	if(result<0)
		return result;

	result = InChar(SendTimeout);
	if(result<0)
		return result;
	if(result!=ModeChar)
		return ErrorReceiverNotBehaving;

	memset(buffer,0,sizeof(buffer));
	BlockNumber = 0;
	result = SendBlock(buffer,sizeof(buffer));
	if(result<0)
		return result;

	return 0;
	}

实例下载地址

ymoldem上位机程序.串口自动更新

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警