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

📄 sam7bl.cpp

📁 Bootloader for Atmel AT91SAM7S128 lloader_sram9 - The ARM code pc2 - The pc software
💻 CPP
字号:
#include "stdafx.h"
#include "windows.h"
#include "stdlib.h"
#include "time.h"

const commWrite = 1;
const commRead = 2;
const commErase = 3;
const commVersion = 4;

HANDLE openComm(int port, int bitrate);
void   commClose(HANDLE h);
void   commSendz(HANDLE h, char *p);
void   commSendn(HANDLE h, char *p, int n);
void   commSendc(HANDLE h, char c);
char   commReceiveChar(HANDLE h);
unsigned int hex1toint(char);
unsigned int hextoint(char*, unsigned int);
void parseHex(char*);

char* fileName = 0;
bool write = false;
bool read = false;

const BASE_FLASH = 1048576;
const BASE_RAM = 2097152;
unsigned int sizeFlash;
unsigned int sizeFlashPage;

unsigned long linearbaseaddress = 0;
unsigned long extendedsegmentaddress = 0;
char** mempage;
bool* mempageused;


int main(int argc, char* argv[])
{	
	HANDLE comm;
	unsigned int port=0, baud=0, chip=0, i, j;
   
	printf("----------------------------------------\n");
	printf("-- SAM7-Bootloader --- js@altronix.se --\n");
	printf("----------------------------------------\n");

	//Read and save arguments
	while(argc--) {
		if(strncmp(*argv, "-port", 5) == 0) {
			argv++;argc--;
			port = (int) strtoul(*argv, NULL, 10);
		} else if(strncmp(*argv, "-baud", 5) == 0) {
		    argv++;argc--;
			baud = (int) strtoul(*argv, NULL, 10);
		} else if(strncmp(*argv, "-write", 6) == 0) {
			write = true;
			argv++;argc--;
			fileName = *argv;
		} else if(strncmp(*argv, "-read", 5) == 0) {
			read = true;
			argv++;argc--;
			fileName = *argv;
		} else if(strncmp(*argv, "-chip", 5) == 0) {
			argv++;argc--;
			chip = (int) strtoul(*argv, NULL, 10);
			switch(chip) {
			case 32:
				sizeFlash = 256;
				sizeFlashPage = 128;
				break;
			case 64:
				sizeFlash = 512;
				sizeFlashPage = 128;
				break;
			case 128:
				sizeFlash = 512;
				sizeFlashPage = 256;
				break;
			case 256:
				sizeFlash = 1024;
				sizeFlashPage = 256;
				break;
			}
			mempage = (char**) calloc(sizeFlash, sizeof(char*));
			for (i=0; i<sizeFlash; i++)
				mempage[i] = (char*) calloc(sizeFlashPage, sizeof(char));
			mempageused = (bool*) calloc(sizeFlash, sizeof(bool));
		}
		argv++;	
	}

	//Check arguments
	if(port==0) {
		printf(" Please specify port number, example:\n");
		printf("  sam7bl.exe -port 1:\n");
		printf("----------------------------------------\n");
		return 0;
	} else if(baud==0) {
		printf(" Please specify baud rate, example:\n");
		printf("  sam7bl.exe -baud 115200:\n");
		printf("----------------------------------------\n");
		return 0;
	} else if(chip==0) {
		printf(" Please specify chip type, example:\n");
		printf("  sam7bl.exe -chip 128:\n");
		printf("----------------------------------------\n");
		return 0;
	} else if(fileName==0) {
		printf(" Please specify file name, example:\n");
		printf("  sam7bl.exe -read project.hex:\n");
		printf("  sam7bl.exe -write project.hex:\n");
		printf("----------------------------------------\n");
		return 0;
	}

	//Connect to target
	comm = openComm(port, baud);

	commSendc(comm, commVersion);
	if(commReceiveChar(comm) == 1) {
		printf(" * Connected\n");
	} else {
		printf(" Unable to connect to target.\n");
		printf("----------------------------------------\n");
		return 0;
	}
	
	//Write HEX to FLASH
	if(write) {
		FILE *pfile;
		long fileSize;

		//Open file
		pfile = fopen(fileName, "r");
		if(pfile == NULL) {
			printf(" * Unable to open file: %s\n", fileName);
			printf("----------------------------------------\n");
			return 0;
		} else {
			printf(" * File opened: %s\n", fileName);
		}
		fseek(pfile ,0 ,SEEK_END);
		fileSize = ftell(pfile);
		rewind(pfile);

		//Parse file
		char* filebuffer = (char*) malloc(fileSize);
		if(filebuffer == NULL) {
			printf(" * Error parsing file\n");
			printf("----------------------------------------\n");
			return 0;
		}
		fread(filebuffer,1,fileSize,pfile);
		parseHex(filebuffer); 
		free(filebuffer);
		fclose(pfile);
		printf(" * File closed\n");

		//Send data to FLASH
		printf(" * Flashing: ");
		for(i=0;i<sizeFlash;i++) {
			if(mempageused[i]) {

				commSendc(comm, commWrite);

				//Page
				commSendc(comm, i % sizeFlashPage);
				if(i>sizeFlashPage)
					commSendc(comm, 1);
				else
					commSendc(comm, 0);

				//Data
				for(j=0;j<sizeFlashPage;j++) {
					commSendc(comm, mempage[i][j]);
				}
								
				//Wait while FLASHING
				commReceiveChar(comm);
				printf(".");
			}
		}
		printf("\n * Flash complete\n");
	}

	//Read FLASH to HEX
	if(read) {
		printf(" Read Not implemented\n");
		
	}

	commClose(comm);
	printf("----------------------------------------\n");
	return 0;
}

unsigned int hex1toint(char hex) {
	if(hex < 58)
		return hex - 48;
	else if(hex > 71)
		return hex-87;
	else
		return hex-55;		
}

unsigned int hextoint(char* hex, unsigned int n) {
	unsigned int i;
	unsigned int tmpRet = 0;
	for(i=0;i<n;i++) {
		tmpRet += hex1toint(hex[n-1-i])<<(i*4);
	}
	return tmpRet;
}

void parseHex(char* filebuffer) {

	unsigned int buflen;
	unsigned int bytecount;
	unsigned long address;
	unsigned int type;
	unsigned int data[32];
	unsigned int checksum;

	unsigned int n, mempagen, mempagen_old;
	unsigned int filepos = 0;
	char tmpbuffer[4];
	
	for(n=0;n<sizeFlash;n++)
		mempageused[n] = false;

	buflen = strlen(filebuffer);
	printf(" * Reading file: ");

	while(buflen-filepos > 10) {

		//Start code
		if(filebuffer[filepos++] != ':') {
			break;
		}

		//Byte count
		strncpy(tmpbuffer, filebuffer+(filepos), 2);
		bytecount = hextoint(tmpbuffer , 2);
		filepos+=2;

		//Address
		strncpy(tmpbuffer, filebuffer+filepos, 4);
		address = hextoint(tmpbuffer , 4);
		filepos+=4;

		//Type
		strncpy(tmpbuffer, filebuffer+filepos, 2);
		type = hextoint(tmpbuffer , 2);
		filepos+=2;
		
		//Data
		for(n=0;n<bytecount;n++){
			strncpy(tmpbuffer, filebuffer+filepos, 2);
			data[n] = hextoint(tmpbuffer , 2);
			filepos+=2;
		}

		//Checksum
		checksum = 0;
		filepos+=2;

		//Newline
		filepos++;


		//Evaluate row
		switch(type) {
		case 0:
			//Write to FLASH region
			if(linearbaseaddress == BASE_FLASH) {
				address += extendedsegmentaddress;
				for(n=0;n<bytecount;n++){
					mempagen = (unsigned int) (address + n) / sizeFlashPage;
					mempageused[mempagen] = true;
					mempage[mempagen][(address + n) % sizeFlashPage] = data[n];

					if(mempagen_old != mempagen) {
						mempagen_old = mempagen;
						printf(".");
					}
				}
			}
			break;

		case 1:
			//Termination
			filepos = buflen;
			break;

		case 2:
            //Segment base adress
            extendedsegmentaddress = (data[0]<<16) | (data[1]<<8);
			break;

		case 4:
            //Linear Base Address
			linearbaseaddress = (data[0]<<24) | (data[1]<<16);
			break;

		}
	}
		
	printf("\n");
}

HANDLE openComm(int port, int bitrate)
{
   HANDLE CommID;
   char com[64];
   DCB dcbComm;
   COMMTIMEOUTS CommTimeouts;
   
   wsprintf(com, "\\\\.\\COM%d", port);
   CommID = CreateFile(com, GENERIC_READ | GENERIC_WRITE,
                    0, NULL, OPEN_EXISTING, 0, NULL);
   if(CommID != INVALID_HANDLE_VALUE)
   {
      SetupComm(CommID, 32768, 2048);
      wsprintf(com, "COM%d:%d,%c,%d,%d", port, bitrate, 'N', 8, 1);
      memset(&dcbComm, 0, sizeof(DCB));
      BuildCommDCB(com, &dcbComm);
      dcbComm.fNull = dcbComm.fOutX = dcbComm.fInX = dcbComm.fParity = 0;
      dcbComm.XonChar = (char)0x81;
      dcbComm.XoffChar = (char)0x82;
      dcbComm.ErrorChar = (char)0x83;
      dcbComm.EofChar = (char)0x84;
      dcbComm.EvtChar = (char)0x85;
      dcbComm.fDtrControl = DTR_CONTROL_ENABLE;
      dcbComm.fRtsControl = RTS_CONTROL_ENABLE;
      SetCommState(CommID, &dcbComm);
      CommTimeouts.ReadIntervalTimeout = 50;
      CommTimeouts.ReadTotalTimeoutMultiplier = 10;
      CommTimeouts.ReadTotalTimeoutConstant = 50;
      CommTimeouts.WriteTotalTimeoutMultiplier = 50;
      CommTimeouts.WriteTotalTimeoutConstant = 10;
      SetCommTimeouts(CommID, &CommTimeouts);
   }
   return CommID;
}

void commSendz(HANDLE h, char *p)
{
   int n;
   DWORD BytesWritten;
   DWORD Errors;

   n = strlen(p);
   
   if(WriteFile(h, p, n, &BytesWritten, NULL) == 0)
      ClearCommError(h, &Errors, NULL);
}

void commSendn(HANDLE h, char *p, int n)
{
   DWORD BytesWritten;
   DWORD Errors;
   
   if(WriteFile(h, p, n, &BytesWritten, NULL) == 0)
      ClearCommError(h, &Errors, NULL);
}  

void commSendc(HANDLE h, char c)
{
	commSendn(h, &c, 1);
}  

char commReceiveChar(HANDLE h)
{
	clock_t timeout =  clock() + (clock_t) (CLOCKS_PER_SEC * 0.4);

	DWORD BytesRead;
	DWORD Errors;
	char c;

	BytesRead = 0;
	while((BytesRead == 0) && (timeout>clock()))
	{
		if(ReadFile(h, &c, 1, &BytesRead, NULL) == 0)
			ClearCommError(h, &Errors, NULL);
	}
	return c;
}

void commClose(HANDLE h)
{
   CloseHandle(h);
}

⌨️ 快捷键说明

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