c#使用Xmodem协议传输

需求:前一段时间朋友想要上位机向板卡传输升级文件,做到自动升级板卡程序,上位机使用c#编写,下位机使用c语言编写,可执行程序采用Xmodem协议传输,在网上浏览了很久没有找到好的c#版本的Xmodem协议的demo,大家可以参考这个例子;

协议:在网上有很多Xmodem协议相关的东西,不多说......

文件流方式打开传输:

XModem xModem = new XModem();
xModem.init_xmodem(SP);//SerialPort

using (FileStream fs = File.Open(filePath, FileMode.Open))//文件路径
{
	using (BinaryReader b_reader = new BinaryReader(fs))
	{
		xModem.xmodem_send(b_reader);
	}
}

XModem帮助类发送:

public void xmodem_send(BinaryReader B_reader)//开始发送,有两种包长度,128和1024两种方式
{
	int err = 0;
	Sender_Packet_Number = 1;
	this.wait_c();
	
	Sender_Data = B_reader.ReadBytes(1024);
	err = Send_Packet(Sender_Data, Sender_Packet_Number, 1024);//第一包数据
	while(true)
	{
		if(err == 1)
		{
			Sender_Data = B_reader.ReadBytes(1024);
			
			if(Sender_Data.Length == 0)//结束跳出循环
			{						
				break;
			}
			else if(Sender_Data.Length != 1024)
			{
				byte[] full_stream = new byte[1024];
				byte[] zero_ary = new byte[1024 - Sender_Data.Length];
				Array.Clear(zero_ary, 0, zero_ary.Length);
				
				Console.WriteLine(Sender_Data.Length);
				
				Array.Copy(Sender_Data, 0, full_stream, 0, Sender_Data.Length);
				Array.Copy(zero_ary, 0, full_stream, Sender_Data.Length, zero_ary.Length);
				
				Sender_Data = full_stream;
			}
			
			Sender_Packet_Number++;
			err = Send_Packet(Sender_Data, Sender_Packet_Number, 1024);
		}
		else
		{
			err = Send_Packet(Sender_Data, Sender_Packet_Number, err);
		}
	}
	
}

private int Send_Packet(byte[] data, byte SPN, int Length)//每一包数据
{
	if(Length == 128)
	{
		Sender_Packet[0] = Constants.SOH;//包首字节
	}
	else if(Length == 1024)
	{
		Sender_Packet[0] = Constants.SOX;
	}
	Sender_Packet[1] = SPN;//包第二字节

	//Sender_Packet[2] = BitConverter.GetBytes(255 - SPN)[0];
	Sender_Packet[2] = (byte)(~SPN);//包第三字节

	Console.WriteLine(BitConverter.ToString(Sender_Packet));
	SPort.Write(Sender_Packet, 0, 3);//发送前三字节
	
	Console.WriteLine(BitConverter.ToString(data));
	SPort.Write(data, 0, Length);//发送有效载荷

	//Sender_Crc = crc16.ComputeCrc(data);
	//Sender_Crc = Crc_o.calcrc(data);
	Sender_Crc_us = crc16.CRC16_ccitt(data, 0, Length);//crc_16两字节校验
	Sender_Crc[0] = (byte)((Sender_Crc_us >> 8) & 0xFF);
	Sender_Crc[1] = (byte)(Sender_Crc_us & 0xFF);

	Console.WriteLine(BitConverter.ToString(Sender_Crc));//发送两字节校验
	SPort.Write(Sender_Crc, 0, 2);
	
	return Wait_ACK_NAK(Length);
}

private int Wait_ACK_NAK(int Length)
{
	int SPort_read;

	while(true)
	{
		Console.WriteLine("Wait_ACK_NAK");
		SPort_read = SPort.ReadChar();//Console.Read();

		if(SPort_read == Constants.NAK) 		//重复发送
		{
			Console.WriteLine("NAK");
			return Length;
		}
		else if(SPort_read == Constants.ACK) 	//继续发送
		{
			Console.WriteLine("ACK");
			return 1;
		}
		else
		{
			Console.WriteLine(SPort_read);
		}
	}
}

帮助类下载链接:地址  方便大家下载,学习......

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_bill

老板大气!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值