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

📄 prog.c

📁 M68HC08及HCS08系列单片机bootloader引导程序源码/示例
💻 C
📖 第 1 页 / 共 2 页
字号:
	} while(d);

	return 0;
}

//////////////////////////////////////////////////////////////
// read memory block, return number of bytes read or -1

int read_blk(unsigned a, int len, BYTE *dest)
{
	if(len < 0 || len >= MAX_LENGTH || a >= MAX_ADDRESS)
		return -1;

	// issue command
	flush_uart(FDISCARD, FDISCARD);
	W8(RD_DATA);
	// and parameters
	if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) W24(a) else W16(a);
	W8(len);

	// block read
	if(rb(dest, len) != len)
		return -1;

	// return number of bytes read (==requested)
	return len;
}

//////////////////////////////////////////////////////////////
// masquerade vector table (work on memory image)
// the trick is to move any vector values from S19 file to 
// special jump table located at ident.app_vect_tbl

int setup_vect_tbl(void)
{
	unsigned src, dest;
	int any_hit = 0;

	if((bl_version == BL_HC08) || (bl_version == BL_HC08_LARGE))
	{
		// start of jump table
		dest = ident.bl_tbl;

		// we store private data first
		memcpy(&image.d[dest], ident.priv_data, sizeof(ident.priv_data));
		dest += sizeof(ident.priv_data);

		// and jump-table next
		for(src = 0xfffe; src >= ident.int_vect_tbl; src -= 2)
		{
			image.d[dest++] = 0xcc;	// jump instruction
			image.d[dest++] = image.d[src]; 
			image.d[dest++] = image.d[src+1];

			// is the vector valid ?
			if(image.f[src] && image.f[src+1])
				any_hit = 1;

			// original vector (from s19 image) is no longer valid
			image.f[src] = 0;
			image.f[src+1] = 0;
		}
	}
	else if ((bl_version == BL_HCS08) || (bl_version == BL_HCS08_LONG))
	{
		// start of jump table
		dest = ident.bl_tbl;

		// private data not stored (YET)
		// and jump-table next
		for(src = ident.int_vect_tbl; src <= 0xfffe ; src += 2)
		{
			image.d[dest++] = image.d[src]; 
			image.d[dest++] = image.d[src+1];

			// is the vector valid ?
			if(image.f[src] && image.f[src+1])
				any_hit = 1;

			// original vector (from s19 image) is no longer valid
			image.f[src] = 0;
			image.f[src+1] = 0;
		}
	}	
	else if (bl_version == BL_HCS08_LARGE)	//at least QE family does not support the redirection, so use 'old' style
	{
		// start of jump table
		dest = ident.bl_tbl;

		// and jump-table next
		for(src = 0xfffe; src >= ident.int_vect_tbl; src -= 2)
		{
			image.d[dest++] = 0xcc;	// jump instruction
			image.d[dest++] = image.d[src]; 
			image.d[dest++] = image.d[src+1];

			// is the vector valid ?
			if(image.f[src] && image.f[src+1])
				any_hit = 1;

			// original vector (from s19 image) is no longer valid
			image.f[src] = 0;
			image.f[src+1] = 0;
		}
	}


	// write the whole system area, but only if at least one vector was valid in the S19
	if(any_hit)
		memset(&image.f[ident.bl_tbl], 2, dest - ident.bl_tbl);

	return 0;
}

//////////////////////////////////////////////////////////////
// erase single block around given address

int erase_blk(unsigned /*long */a)
{
	int ret;
	BYTE d;

	DBG1("\nerase_blk: 0x%06x\n", a);
	if(a >= MAX_ADDRESS)
		return -1;

	// issue command
	flush_uart(FDISCARD, FDISCARD);
	W8(ERASE);
	// and parameter
	if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) W24(a) else W16(a);

	// wait for ack
	while((ret = rb(&d, 1)) == 0)
		; // do nothing

	// it must be ACK character
	if(ret > 0 && d != ACK)
		ret = -1;

	// either -1 or 1
	return ret;
}

//////////////////////////////////////////////////////////////
// program single block

int prg_blk(unsigned long a, int len)
{
	int ret;
	BYTE d;

	DBG2("\nprg_blk: 0x%06x-0x%06x\n", a, a+len-1);
	if(len < 0 || len >= MAX_LENGTH || a >= MAX_ADDRESS) 
		return -1;

	// issue command
	flush_uart(FDISCARD, FDISCARD);
	W8(WR_DATA);
	// and parameters
	if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) W24(a) else W16(a);
	W8(len);

	if(wb(&image.d[a], len) != len)
		return -1;

	// wait for ack
	while((ret = rb(&d, 1)) == 0)
		; // do nothing

	// must be ACK character
	if(ret > 0 && d != ACK)
		ret = -1;

	// either -1 or 1
	return ret;
}

//////////////////////////////////////////////////////////////
// program one continuous area and give user a progess 

static int prg_area(unsigned long start, unsigned long end)
{
	unsigned long i, er, wr, er_next, wr_end, wr_next;
	unsigned long wr_one, written=0, total=0;

	DBG2("prg_area: 0x%06x-0x%06x\n", start, end);
	if(start >= MAX_ADDRESS || end >= MAX_ADDRESS) 
		return -1;

	// count valid bytes
	for(i=start; i<end; i++)
		if(image.f[i]) total++;


#define FLASHMODULO(x,y) ((unsigned long)(MAX_ADDRESS - (y) *(1 + ((MAX_ADDRESS-(unsigned long)((x)+(y))-1) / (y)))))


	// take start address as it is, but do further steps to erblk boundaries
	for(er=start; er<end; er=er_next)
	{
		// start of next erase block
		er_next = FLASHMODULO(er,ident.erblk);

		// anything to program in this erase block ?
		wr = wr_end = er;
		for(i=er; i<er_next; i++)
		{
			// valid byte
			if(image.f[i])
			{
				if(!image.f[wr]) wr = i;
				wr_end = i+1;
			}
		}

		// never pass after end
		if(wr_end > end)
			wr_end = end;

		// wr is now pointing to first valid byte (within current erase block)
		// wr_end is now pointing after last valid byte (within current erase block)
		if(wr < wr_end)
		{
			if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
				printf("\rMemory programming: E 0x%06X %d%%", wr, 100*written/total);
			else
				printf("\rMemory programming: E 0x%04X %d%%", wr, 100*written/total);
			fflush(stdout); DBG("\n");

			// use the first valid-byte address
			if(erase_blk(wr) < 0) 
			{
				printf("\n");
				if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
					fprintf(stderr, "Can't erase block at address 0x%06X\n", wr);
				else	
					fprintf(stderr, "Can't erase block at address 0x%04X\n", wr);
				return -1;
			}

			for(/* original wr */; wr<wr_end; wr=wr_next)
			{
				// start of next write block
				wr_next = FLASHMODULO(wr,ident.wrblk);

				if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
					printf("\rMemory programming: W 0x%06X %d%%", wr, 100*written/total);
				else
					printf("\rMemory programming: W 0x%04X %d%%", wr, 100*written/total);

				fflush(stdout); DBG("\n");

				wr_one = umin(wr_end, wr_next)-wr;
				if(prg_blk(wr, wr_one) < 0) 
				{
					printf("\n");
					if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
						fprintf(stderr, "Can't program block at address 0x%06X\n", wr);
					else
						fprintf(stderr, "Can't program block at address 0x%04X\n", wr);
					return -1;
				}

				if((bl_rcs) && (verify))	// read command implemented!
				{
					unsigned char rbuff[256];
					unsigned int adr;

					if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
						printf("\rMemory reading:     R 0x%06X %d%%", wr, 100*written/total);
					else
						printf("\rMemory reading:     R 0x%04X %d%%", wr, 100*written/total);

					fflush(stdout); DBG("\n");
					if (read_blk(wr, wr_one, rbuff) <0)
					{
						printf("\n");
						if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
							fprintf(stderr, "Can't read block at address 0x%06X\n", wr);
						else
							fprintf(stderr, "Can't read block at address 0x%04X\n", wr);
						return -1;
					}

					for(adr = wr; adr < wr+wr_one; adr++)
					{
						if (image.d[adr] != rbuff[adr-wr])
						{
							if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
								fprintf(stderr, "\nVerification failed at address 0x%06X, image: [0x%02X], MCU: [0x%02X]\n", adr, image.d[adr], rbuff[adr-wr]);
							else
								fprintf(stderr, "\nVerification failed at address 0x%04X, image: [0x%02X], MCU: [0x%02X]\n", adr, image.d[adr], rbuff[adr-wr]);
							return -1;
						}
					}
				}

				// the percentage-counting algorithm is not perfect, in some cases there might 
				// be more than 100% achieved (if S19 file has holes within erblks = rare case)
				if((written += wr_one) > total)
					written = total;
			}
		}
	}

	return 0;
}

//////////////////////////////////////////////////////////////
// program all

int	prg_mem(void)
{
	unsigned s,e;

	// find first and last valid byte
	for(s=0; s<MAX_ADDRESS; s++)
		if(image.f[s]) break;
	for(e=MAX_ADDRESS; e>s; e--)
		if(image.f[e-1]) break;

	if(prg_area(s, e) < 0)
		return -1;


	if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
	{
		printf("\rMemory programmed:             100%%\n");
		if((bl_rcs) && (verify)) 
			printf("\rMemory verified:               OK\n");
	}
	else
	{
		printf("\rMemory programmed:           100%%\n");
		if((bl_rcs) && (verify)) 
			printf("\rMemory verified:             OK\n");
	}
	return 0;
}

//////////////////////////////////////////////////////////////
// print ID$, only printable char, max. 255 chars

void cleanprint(char * str)
{
int cnt = 255;
    
	while(*str && cnt--) 
    {
		if (isprint(*str))
			putchar(*str);
		else
			putchar('.');

		str++;
    }
}

//////////////////////////////////////////////////////////////
// check if code goes to valid memory only

int	check_image()
{
	unsigned a, i, f;

	unsigned s,e;

	char* scannm;
	char id;


	// find first and last valid byte
	for(s=0; s<MAX_ADDRESS; s++)
		if(image.f[s]) break;
	for(e=MAX_ADDRESS; e>s; e--)
		if(image.f[e-1]) break;


	// skip COM if specified and scan number and mode (optional)
	id = strnicmp(image.d+s, "ID$:", 4);

	if (id == 0)
	{
		scannm = image.d+s+4;	/* string ptr. after ID$ */

		printf("\r\nMCU software version: ");
		cleanprint(scannm);
		putchar('\n');
	}

	//sscanf(scannm, "%i%c%c", &portNum, &modemode, &serial_mode);

	
	
	for(a=0; a<MAX_ADDRESS; a++)
	{
		if(image.f[a]==1)
		{
			f = 0;
			for(i=0; i<ident.num_blocks; i++)
			{
				if ((a>=ident.mem_start[i]) && (a<ident.mem_end[i]))
				{
					f = 1;
					break;
				}
			}
			if(f == 0)
				goto err_hit;	//location at address a won't fit any memory block!
		}
	}

	// no error
	return 0;

err_hit:
	if ((bl_version == BL_HCS08_LARGE) || (bl_version == BL_HCS08_LONG)) 
		fprintf(stderr, "\nWARNING! S19 image will not fit into available memory (at address 0x%06X)!\n", a);
	else
		fprintf(stderr, "\nWARNING! S19 image will not fit into available memory (at address 0x%04X)!\n", a);
	return -1;
}

//////////////////////////////////////////////////////////////
// exit program mode, start application

int	unhook(void)
{
	W8(QUIT);
	return 0;
}

⌨️ 快捷键说明

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