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

📄 ymodem.c

📁 EX44B0开发板BootLoader
💻 C
字号:
#include "Ymodem.h"
#include "UART.h"
#include <string.h>

/*******************************************************************************
* Function Name  : Receive_Byte
* Description    : Receive byte from sender
* Input 1        : Character
* Input 2        : Timeout
* Return         : >=0   --      Byte received                           
*                :  -1   --      Timeout   
*******************************************************************************/
static int Receive_Byte(void)
{
	unsigned timeout = NAK_TIMEOUT;
	do
		if(UART_Query())
			return UART_Getch();
	while(--timeout);
	return -1;
}

/*******************************************************************************
* Function Name  : Send_Byte
* Description    : Send a byte 
* Input          : Character
* Return         :  0   --      Byte sent                           
*******************************************************************************/
static void Send_Byte(int c)
{
	UART_Putch(c);
}

/*******************************************************************************
* Function Name  : Receive_Packet
* Description    : Receive a packet from sender 
* Input 1        : Data
* Input 2        : Length
* Input 3        : Timeout
* Return         :   0  --      normally return                         
*                :  -1  --      timeout or packet error                 
*                :   1  --      abort by user                           
*                : *length:                                                
*                :   0  --      end of transmission                    
*                :  -1  --      abort by sender                         
*                :  >0  --      packet length                                      
*******************************************************************************/
static int Receive_Packet(unsigned char *data, int *length)
{
	int c, i, packet_size;

	*length = 0;

	c = Receive_Byte();
	if(c < 0)
		return -1;

	switch(c)
	{
	case SOH:
		packet_size = PACKET_SIZE;
		break;
	case STX:
		packet_size = PACKET_1K_SIZE;
		break;
	case EOT:
		return 0;
	case CAN:
		if(Receive_Byte() == CAN)
		{
			*length = -1;
			return 0;
		}
		else
			return -1;
	case ABORT1:
	case ABORT2:
		return 1;
	default:
		return -1;
	}

	*data = c;

	for(i = 1; i < packet_size + PACKET_OVERHEAD; i++)
	{
		c = Receive_Byte();
		if(c < 0)
			return -1;
		data[i] = c;
	}

	if(data[PACKET_SEQNO_INDEX] != (data[PACKET_SEQNO_COMP_INDEX] ^ 0xff))
		return -1;

	*length = packet_size;
	return 0;
}

/*******************************************************************************
* Function Name  : Ymodem_Receive
* Description    : Receive a file using the ymodem protocol 
* Input          : Address of the first byte 
* Return         : The size of the file                                                               
*******************************************************************************/
int Ymodem_Receive(void *buf, char *filename)
{
	int size, errors = 0, session_begin = 0;

	while(1)
	{
		int file_done = 0, packets_received = 0;
		unsigned char *buf_ptr = buf;

		do {
			unsigned char packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];
			int packet_length;

			switch(Receive_Packet(packet_data, &packet_length))
			{
			case 0:
				errors = 0;
				switch (packet_length)
				{
				case -1:									// abort by sender
					Send_Byte(ACK);
					return 0;
				case 0:										// end of transmission
					Send_Byte(ACK);
					file_done = 1;
					break;
				default:									// normal packet
					if(packet_data[PACKET_SEQNO_INDEX] != (packets_received & 0xff))
						Send_Byte(NAK);
					else
					{
						Send_Byte(ACK);
						if(!packets_received)				// filename packet
						{
							if(packet_data[PACKET_HEADER])	// filename packet has valid data
							{
								unsigned char *file_ptr = packet_data + PACKET_HEADER;

								if(filename)
								{
									do
										*filename++ = *file_ptr;
									while(*file_ptr++);
								}
								else
									while(*file_ptr++);

								size = 0;
								while(*file_ptr)
									size = size * 10 + (*file_ptr++ - '0');

								Send_Byte(CRC16);
							}
							else							// filename packet is empty; end session
								return size;
						}
						else								// data packet
						{
							memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
							buf_ptr += packet_length;
						}
						packets_received++;
						session_begin = 1;
					}
				}
				break;
			case 1:
				Send_Byte(CAN);
				Send_Byte(CAN);
				return -1;
			default:
				if(session_begin)
					errors++;
				if(errors > MAX_ERRORS)
				{
					Send_Byte(CAN);
					Send_Byte(CAN);
					return 0;
				}
				Send_Byte(CRC16);
			}
		} while(!file_done);
	}
}

⌨️ 快捷键说明

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