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

📄 dl_srec.c

📁 motorola自己开发的针对coldfire 5272的Dbug bootloader程序
💻 C
字号:
/*
 * File:		dl_srec.c
 * Purpose:		Routines to download Motorola S-Records via serial port.
 *
 * Notes:		Implements Xon/Xoff software handshaking
 *
 */

#include "src/include/dbug.h"
#include "src/uif/uif.h"

/********************************************************************/

#define CHAR_WAIT_TIMEOUT	2000
uint8 overflow[60];
int ovchars;
int ovindex;

/********************************************************************/
static uint8
dl_getchar(void)
{	
	uint8 rval;

	if (ovchars)
	{
		rval = overflow[ovindex++];
		if (!--ovchars)
		{
			/* Send Xon character */
			board_putchar(XON);
			ovindex = 0;
		}
		return rval;
	}
	else
	{
		return board_getchar();
	}
}

/********************************************************************/

static uint8
dl_gethexvalue (uint8 uint8)
{
	switch (uint8)
	{
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			return (uint8 - '0');
			break;
		case 'A':
		case 'a':
			return 10;
			break;
		case 'B':
		case 'b':
			return 11;
			break;
		case 'C':
		case 'c':
			return 12;
			break;
		case 'D':
		case 'd':
			return 13;
			break;
		case 'E':
		case 'e':
			return 14;
			break;
		case 'F':
		case 'f':
			return 15;
			break;
		default:
			return 0;
	}
}

/********************************************************************/
static uint8
dl_getS (void)
{
	/*
	 * This routine skips all characters until an `S' is received.
	 * It then returns the next character.
	 * This routine is here in order to not echo characters back
	 * out as they are received during a download.
	 *
	 * This code ignores NL,CR-LF end of line issues by waiting
	 * for 'S'.
	 */
	uint8 c;

	while (TRUE)
	{
		c = dl_getchar();
		if (c == 'S')
			break;
	}

	/* Get type of S-record */
	return dl_getchar();
}

/********************************************************************/
static uint8
dl_getSpair (void)
{
	uint8 ch;
	uint8 upper;

	ch = dl_getchar();
	upper = (uint8)(dl_gethexvalue(ch) << 4);
	ch = dl_getchar();
	return (upper | dl_gethexvalue(ch));
}

/********************************************************************/
int
dl_download_srec (int offset_to_addr)
{
	int checksum, i, index, done, timeout, type;
	uint8 data, length, hash[5];
	int hashi = 1, hashj = 0;
	ADDRESS address = 0;
	unsigned char buffer[150];
	
	hash[0]=8;	/* Backspace */
	hash[1]=124;/* "|" */
	hash[2]=47; /* "/" */
	hash[3]=45; /* "-" */
	hash[4]=92; /* "\" */

	done = FALSE;
	ovchars = 0;

	/* Send Xon character */
	board_putchar(XON);

	while (!done)
	{
		/* Get start of S-record */
		type = dl_getS();
		
		/* Get record length */
		length = dl_getSpair();
		checksum = length;

		/* Take appropriate action */
		switch (type)
		{
			case '1':
			case '2':
			case '3':
				timeout = 0;
				address = NULL;
				type -= '0';
				for (i = 0; i <= type ; i++)
				{
					/* Formulate address */
					data = dl_getSpair();
					address = (address << 8) | data;
					
					/* Maintain 8-bit checksum */
					checksum = (data + checksum) & 0x00FF;
					length--;
				}
				
				/* Adjust for user specified offset */
				address = (ADDRESS)((int)address + offset_to_addr);
				
				if ((index = flash_dlio_vda((ADDRESS)address)) != 0)
				{
					/* Get data and put into buffer */
					for (i = 0; i < (length - 1); i++)
					{
						buffer[i] = dl_getSpair();
					}
					
					/* Get checksum byte */
					data = dl_getSpair();
					
					/* Send Xoff character */
					board_putchar(XOFF);

					/* Catch the overflow */
					while (timeout++ < CHAR_WAIT_TIMEOUT)
					{
						if (board_getchar_present())
						{
							overflow[ovchars++] = board_getchar();
							timeout = 0;
						}
					}

					/* Write buffered data to Flash */
					flash_program((ADDRESS)address,(ADDRESS)buffer, 
								i, index, FALSE, FALSE);
								
					/* Calculate checksum */
					for (i = 0; i < (length - 1); i++)
					{
						checksum = (*(uint8 *)address + checksum) & 0x00FF;
						++address;		
					}

					if (((data - ~checksum) & 0x00FF) != 0)
					{
						printf("\bError:  S-record checksum error!\n");
						printf("Expected:  %2X,  Received: %2X\n",
							data,checksum);
						printf("Address: %8X\n",address);
					}

					/* Send Xon if no overflow occured */
					if (!ovchars)
						board_putchar(XON);
				}

				else if (board_dlio_vda((ADDRESS)address))
				{
					/* Get data and put into memory */
					for (i = 0; i < (length -1); i++)
					{
						data = dl_getSpair();
						*(uint8 *)address = (uint8)data;
						
						/* Checksum is computed from data written to RAM */
						checksum = (*(uint8 *)address + checksum) & 0x00FF;
						++address;
					}
					
					/* Get checksum byte */
					data = dl_getSpair();
					
					if (((data - ~checksum) & 0x00FF) != 0)
					{
						printf("\bError:  S-record checksum error!\n");
						printf("Expected:  %2X,  Received: %2X\n",
							data,checksum);
						return FALSE;
					}
				}
				else
				{
					printf("\bInvalid download address: %#08X\n",address);
					return FALSE;
				}
				
				/* 
				 * Hash marks to indicate progress 
				 */
				if (++hashj == 10)
				{
					board_putchar(hash[0]);
					board_putchar(hash[hashi]);
					if (++hashi == 5)	
						hashi=1;
					hashj = 0;
				}

				break;
			case '7':
			case '8':
			case '9':
				type = type - '0';
				type = 10 - type;
				while (type-- >= 0)
				{
					data = dl_getSpair();
					checksum = (data + checksum) & 0x00FF;
					address = (address << 8) | data;
					length--;
				}
				address = address + offset_to_addr;
				while (length-- > 1)
				{
					data = dl_getSpair();
					checksum = (data + checksum) & 0x00FF;
				}

				data = dl_getSpair();

				if (((data - ~checksum) & 0x00FF) != 0)
				{
					printf("\bError:  S-record checksum error!\n");
					return FALSE;
				}
				else
				{
					printf("\bS-record download successful!\n");
					cpu_pc_modify(address);
				}
				done = TRUE;
				
 				/* Clear out the \n in the receive buffer */
 				board_getchar();
				break;
			case '0':
			case '4':
			case '5':
			case '6':
			default:
				break;
		}
	}
	return TRUE;
}

/********************************************************************/
void
uif_cmd_dl (int argc, char **argv)
{
	/*
 	 * This routine downloads S-records from the host.
	 */
	int success;
	int32 offset;
	extern ADDRESS md_last_address;
	extern ADDRESS disasm_last_address;
	
	(void)argc;

	if (argv[1] != NULL)
	{
		offset = (int32)get_value(argv[1],&success,BASE);
		if (!success)
		{
			printf(INVALUE,argv[1]);
			return;
		}
		printf("Offset: %#08X (%d)\n", offset);
	}
	else
		offset = 0;

	printf("Escape to local host and send S-records now...\n");
	
	dl_download_srec(offset);

	cpu_cache_flush();

	disasm_last_address = cpu_pc_get();
	md_last_address = cpu_pc_get();
}

/********************************************************************/

⌨️ 快捷键说明

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