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

📄 bootloader.cpp

📁 PIC18F1320 bootloader. This a port of the PIC16F87x bootloader to the PIC18F1320. Project includes M
💻 CPP
字号:

#include "Bootloader.h"
#include <stdio.h>	//for sprintf
//#include <fstream.h>

#define PAUSE 60


Bootloader::Bootloader()
{
	Programming = 0;
	Progress = 0;
	cancelled = 0;
	major_address = 0;
	sprintf(Status, "");
}

char *Bootloader::GetStatus()
{
	return Status;
}
int Bootloader::IsProgramming()
{
	return Programming;
}

int Bootloader::GetPercent()
{
	return Progress;
}

void Bootloader::SetComPort(ComPort *port)
{
	comPort = port;
}

void Bootloader::SetFilename(char *filename)
{
	strcpy(firmware_filename, filename);
}


int Bootloader::hexchartoint(char val)
{
	int num = 0;
    switch(val)
    {
    case 'F': num = 15; break;
    case 'E': num = 14; break;
    case 'D': num = 13; break;
    case 'C': num = 12; break;
    case 'B': num = 11; break;
    case 'A': num = 10; break;
    default: if(val >= '0' && val <= '9') num = val - 0x30; break;
    };
	return num;
}

int Bootloader::SendBuffer(char *buf)
{
//	UpdateData(TRUE);
	unsigned char SendBuf[256];
	int checksum = 0;
	int SendLength = 0;


	int address = 0;
	int i, j;

	if(buf[7] == '0' && buf[8] == '4')	//Linear Address Record
	{
		i = hexchartoint(buf[9]) * 16 + hexchartoint(buf[10]);
		j = hexchartoint(buf[11]) * 16 + hexchartoint(buf[12]);
		//note that the address is stored in the hex file as low byte, high byte
		major_address = (j*256 + i) * 0x100;	
		//the configuration word is at 0x300000

		//we don't need to send anything here.
		return 1;
	}
	if(buf[7] == '0' && buf[8] == '1')	//End of File Record
	{
		//we don't need to send anything here.
		return 1;
	}
	if(buf[7] == '0' && buf[8] == '2')	//Segment Address Record
	{
		//we don't need to send anything here.
		return 1;
	}

	//sends the buffer to the serial port after parsing the data out
	if(buf[7] == '0' && buf[8] == '0')
	{
		i = hexchartoint(buf[3]) * 16 + hexchartoint(buf[4]);
		j = hexchartoint(buf[5]) * 16 + hexchartoint(buf[6]);
		address = (i*256 + j); // /2;

		SendBuf[0] = WRITE_COMMAND; //write instruction
		SendBuf[1] = (unsigned char)(((address + major_address) >> 16) & 0xff);  //upper byte
		SendBuf[2] = (unsigned char)(((address + major_address) >> 8) & 0xff);	//high bytes
		SendBuf[3] = (unsigned char)((address + major_address) & 0xff);			//low byte

		int numdata = hexchartoint(buf[1]) * 16 + hexchartoint(buf[2]);
		SendBuf[4] = (numdata & 0xff);

		int iterations = numdata/2;
		//if(numdata & 0x01)	//if it is odd, it won't divide right
		//	iterations++;
		for(int n = 0; n < iterations; n++)
		{
			int pointer = n*4;
			i = hexchartoint(buf[9 + pointer]) * 16 + hexchartoint(buf[10 + pointer]);
			SendBuf[6 + n*2] = (unsigned char)(i & 0xff);
			checksum += i;

			i = hexchartoint(buf[11 + pointer]) * 16 + hexchartoint(buf[12 + pointer]);
			SendBuf[7 + n*2] = (unsigned char)(i & 0xff);
			checksum += i;

		}
		SendBuf[5] = (unsigned char)(checksum & 0xff);
		SendLength = 6 + numdata;
	}
	//0x0EE0 * 2 = 0x1DC0
	//don't write over boot loader or eeprom
	if((address + major_address) >= (0x0EE0 * 2) && (address + major_address) <= (0x2000) )		
		return 1;


	//Sleep(PAUSE);

	//try to send SendBuf up to 5 times.
	for(int tries = 0; tries < 5; tries++)
	{

		unsigned char byte;
		while(comPort->DataWaiting() > 0)
			comPort->Read(&byte, 1);

		FILE *logfile;
		logfile = fopen("log.txt", "a");
		for(int e = 0; e < SendLength; e++)
		{
			fprintf(logfile, "%02x ", SendBuf[e]);
			fflush(logfile);
		}
		fprintf(logfile, "\n");


		for(int r = 0; r < SendLength; r++)
		{
			comPort->Write(SendBuf + r, 1);
			Sleep(10);	//this MUST be greater then 2ms to work
		}

		unsigned char response_buffer[255];
		unsigned char *response = (unsigned char *)&response_buffer;
		
		Clock clock; //start the clock
		clock.Start();
		int recieved = 0;
		int found = 0;
		int bad_data = false;

		unsigned char character;

		while((clock.Elapsed() < (PAUSE*2.0f/1000.0f)) && !found && !bad_data)
		{
			int data_waiting = comPort->DataWaiting();
			while(data_waiting > 0)
			{
				data_waiting--;

				comPort->Read((unsigned char *)&character, 1); //read a byte
				recieved++;
				*response = character;
				response++;
				if(character == DATA_BAD) //data bad byte
				{
					bad_data = true; //get out of the while loop
					break;
				}
				if(recieved == 2)
				{
					found = TRUE;
				}
			}
			Sleep(5);
		}

		fclose(logfile);
		if(bad_data)
			continue;

		if(response - ((unsigned char *)&response_buffer) < 2)
			continue;  //it timed out so try again

		if((response_buffer[0] == (unsigned char)DATA_OK) && (response_buffer[1] == (unsigned char)WRITE_OK))
		{
			return 1;
		}
	}//end for tries
	return 0;

}

//Update is designed to run in it's own thread
void Bootloader::Update()
{
	FILE *hexfile;
	if((hexfile = fopen(firmware_filename, "r")) == NULL)
	{
		Progress = 0;
		return;
	}
	if(feof(hexfile))
	{
		//there was a problem opening the file
		Progress = 0;
		return ;
	}
	fseek(hexfile, 0, SEEK_SET);
	char buff[256];
	int line = 0;

	//count the number of lines
	while(!feof(hexfile))
	{
		if( fgets( buff, 255, hexfile ) == NULL)
			break;
		line++;
	}

	int max_lines = line;
	fclose( hexfile );

	hexfile = fopen(firmware_filename, "r");

	fseek(hexfile, 0, SEEK_SET);

	int Canceled = false;
	int Waiting = true;
	Programming = false;

	unsigned char rbyte;
	line = 0;
	major_address = 0;

	Clock clock; //start the clock
	clock.Start();
	while(Waiting && !cancelled)
	{
		strcpy(Status, "Waiting for Hardware Reset.");
		//send a byte
		unsigned char data2 = IDENT;
		comPort->Write(&data2, 1);
		Sleep(5);
		if(comPort->DataWaiting() > 0)
		{
			comPort->Read(&rbyte, 1);
			if(rbyte == IDACK)
			{
				Waiting = false;
				Programming = true;
			}
		}
		Sleep(5);
		Progress = 0;

	}
	while(Programming)
	{
		Sleep(10);	//programming should take 2ms+2ms=4ms round up to 10ms
		sprintf(Status, "Writing..  %d%%", Progress);

		char buffer[256];
		unsigned char done = (unsigned char)BL_DONE;

		if( fgets( buffer, 255, hexfile ) == NULL)
		{
			Programming = false;
		}

		if(strlen(buffer) > 0)
		{
			if(buffer[0] == ':')
			{
				line++;
				Progress = (int)((float)line/(float)max_lines * 100.0f);
				if(buffer[7] == '0' && buffer[8] == '1')
				{
					comPort->Write(&done, 1);	//send the DONE character
					strcpy(Status, "Programming complete!");
					fclose( hexfile);
				}
				else
				{
					if(SendBuffer(buffer) == 0)
					{
						Programming = false;
						Canceled = true;
						fclose(hexfile);
						Progress = 0;
						strcpy(Status, "Error durring programming.");
					}
				}

			}
			if(feof(hexfile))
			{
				comPort->Write(&done, 1);	//send the DONE character
				strcpy(Status, "Programming complete!");

				Programming = false;
				Canceled = false;
				fclose( hexfile);
			}
		}
		else
		{
			//empty line
		}

	}
	Progress = 0;
	Programming = false;

}

⌨️ 快捷键说明

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