📄 sam7bl.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 + -