📄 bsldemo.c
字号:
"",
"Options:",
" -h Shows this help screen.",
" -c{port} Specifies the communication port to be used (e.g. -cCOM2).",
" -p{file} Specifies a TI-TXT file with the interrupt vectors that are",
" used as password (e.g. -pINT_VECT.TXT).",
" -w Waits for <ENTER> before closing serial port.",
" -1 Programming and verification is done in one pass through the file.",
/*
" -a{file} Filename of workaround patch (e.g. -aWAROUND.TXT).",
" -b{file} Filename of complete loader to be loaded into RAM (e.g. -bBSL.TXT).",
" -f{num} Max. number of data bytes within one transmitted frame (e.g. -f240).",
*/
#ifdef ADD_MERASE_CYCLES
" -m{num} Number of mass erase cycles (e.g. -m20).",
#endif /* ADD_MERASE_CYCLES */
"",
"Program Flow Specifiers [+ecpvrw]",
" e Mass Erase",
" c Erase Check by file {file}",
" p Program file {file}",
" v Verify by file {file}",
" r Reset connected MSP430. Starts application.",
" w Wait for <ENTER> before closing serial port.",
" Only the specified actions are executed!",
"Default Program Flow Specifiers (if not explicitly given): +ecpvr",
"\0" /* Marks end of help! */
};
int i= 0;
while (help[i] != "\0") printf("%s\n", help[i++]);
}
/*---------------------------------------------------------------
* Main:
*---------------------------------------------------------------
*/
int main(int argc, char *argv[])
{
int error= ERR_NONE;
int i, j;
char comPortName[10]= "COM1"; /* Default setting. */
char *filename= NULL;
char *passwdFile= NULL;
#ifdef ADD_MERASE_CYCLES
int meraseCycles= ADD_MERASE_CYCLES;
#else
const int meraseCycles= 1;
#endif /* ADD_MERASE_CYCLES */
#ifdef NEW_BSL
newBSLFile= NULL;
#endif /* NEW_BSL */
/* Default: all actions turned on: */
toDo.MassErase = 1;
toDo.EraseCheck= 1;
toDo.Program = 1;
toDo.Verify = 1;
toDo.Reset = 1;
toDo.Wait = 0; /* Do not wait for <Enter> at the end! */
toDo.OnePass = 0; /* Do erase check, program and verify */
/* sequential! */
#ifdef WORKAROUND
/* Show memory access warning, if working with bootstrap
* loader version(s) requiring the workaround patch.
* Turn warning on by default until we can determine the
* actual version of the bootstrap loader.
*/
BSLMemAccessWarning= 1;
#endif /* WORKAROUND */
printf("%s (%s)\n", programName, programVersion);
/*-------------------------------------------------------------
* Parse Command Line Parameters ...
*-------------------------------------------------------------
*/
if (argc > 1)
{
for (i= 1; i < (argc - 1); i++)
{
switch (argv[i][0])
{
case '-':
switch (argv[i][1])
{
case 'h': case 'H':
showHelp(); /* Show help screen and */
return(1); /* exit program. */
break;
case 'c': case 'C':
memcpy(comPortName, &argv[i][2], strlen(argv[i])-2);
break;
case 'p': case 'P':
passwdFile= &argv[i][2];
break;
case 'w': case 'W':
toDo.Wait= 1; /* Do wait for <Enter> at the end! */
break;
case '1':
toDo.OnePass= 1;
break;
case 'f': case 'F':
if (argv[i][2] != 0)
{
sscanf(&argv[i][2], "%i", &maxData);
/* Make sure that conditions for maxData are met:
* ( >= 16 and == n*16 and <= MAX_DATA_BYTES!)
*/
maxData= (maxData > MAX_DATA_BYTES) ? MAX_DATA_BYTES : maxData;
maxData= (maxData < 16) ? 16 : maxData;
maxData= maxData - (maxData % 16);
printf("Max. number of data bytes within one frame set to %i.\n",
maxData);
}
break;
#ifdef ADD_MERASE_CYCLES
case 'm': case 'M':
if (argv[i][2] != 0)
{
sscanf(&argv[i][2], "%i", &meraseCycles);
meraseCycles= (meraseCycles < 1) ? 1 : meraseCycles;
printf("Number of mass erase cycles set to %i.\n", meraseCycles);
}
break;
#endif /* ADD_MERASE_CYCLES */
#ifdef WORKAROUND
case 'a': case 'A':
patchFile= &argv[i][2];
break;
#endif /* WORKAROUND */
#ifdef NEW_BSL
case 'b': case 'B':
newBSLFile= &argv[i][2];
break;
#endif /* NEW_BSL */
default:
printf("ERROR: Illegal command line parameter!\n");
} /* switch argv[i][1] */
break; /* '-' */
case '+':
/* Turn all actions off: */
toDo.MassErase = 0;
toDo.EraseCheck= 0;
toDo.Program = 0;
toDo.Verify = 0;
toDo.Reset = 0;
toDo.Wait = 0;
/* Turn only specified actions back on: */
for (j= 1; j < (int)(strlen(argv[i])); j++)
{
switch (argv[i][j])
{
case 'e': case 'E':
/* Erase Flash */
toDo.MassErase = 1;
break;
case 'c': case 'C':
/* Erase Check (by file) */
toDo.EraseCheck= 1;
break;
case 'p': case 'P':
/* Program file */
toDo.Program = 1;
break;
case 'v': case 'V':
/* Verify file */
toDo.Verify = 1;
break;
case 'r': case 'R':
/* Reset MSP430 before waiting for <Enter> */
toDo.Reset = 1;
break;
case 'w': case 'W':
/* Wait for <Enter> before closing serial port */
toDo.Wait = 1;
break;
default:
printf("ERROR: Illegal action specified!\n");
} /* switch */
} /* for (j) */
break; /* '+' */
default:
printf("ERROR: Illegal command line parameter!\n");
} /* switch argv[i][0] */
} /* for (i) */
if (stricmp("-h", argv[i]) == 0)
{
showHelp(); /* Show help screen and */
return(1); /* exit program. */
}
else
{
filename= argv[i];
}
}
else
{
printf("ERROR: Filename required!\n");
printf("Use -h to get help!\n");
return(1);
}
/*-------------------------------------------------------
* Communication with Bootstrap Loader ...
*-------------------------------------------------------
*/
/* Open COMx port (Change COM-port name to your needs!): */
if (comInit(comPortName, DEFAULT_TIMEOUT, 4) != 0)
{
printf("ERROR: Opening COM-Port failed!\n");
return(1);
}
bslReset(1); /* Invoke the boot loader. */
#ifdef NEW_BSL
if ((newBSLFile == NULL) || (passwdFile == NULL))
{
/* If a password file is specified the "new" bootstrap loader can be loaded
* (if also specified) before the mass erase is performed. Than the mass
* erase can be done using the "new" BSL. Otherwise the mass erase is done
* now!
*/
#endif /* NEW_BSL */
if (toDo.MassErase)
{
int i;
/* Erase the flash memory completely (with mass erase command): */
printf("Mass Erase...\n");
for (i= 0; i < meraseCycles; i++)
{
if (i == 1)
{
printf("Additional Mass Erase Cycles...\n");
}
if ((error= bslTxRx(BSL_MERAS, /* Command: Mass Erase */
0xff00, /* Any address within flash memory. */
0xa506, /* Required setting for mass erase! */
NULL, blkin)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
}
passwdFile= NULL; /* No password file required! */
}
#ifdef NEW_BSL
} /* if ((newBSLFile == NULL) || (passwdFile == NULL)) */
#endif /* NEW_BSL */
/* Transmit password to get access to protected BSL functions. */
if ((error= txPasswd(passwdFile)) != ERR_NONE)
{
return(signOff(error, TRUE)); /* Password was transmitted! */
}
/* Read actual bootstrap loader version. */
if ((error= bslTxRx(BSL_RXBLK, /* Command: Read/Receive Block */
0x0ffa, /* Start address */
2, /* No. of bytes to read */
NULL, blkin)) == ERR_NONE)
{
BYTE bslVerLo;
BYTE bslVerHi;
memcpy(&bslVerHi, &blkin[0], 1);
memcpy(&bslVerLo, &blkin[1], 1);
printf("Current bootstrap loader version: %x.%x\n", bslVerHi, bslVerLo);
bslVer= (bslVerHi << 8) | bslVerLo;
if (bslVer <= 0x0110)
{
#ifdef WORKAROUND
#ifdef NEW_BSL
if (newBSLFile == NULL)
{
#endif /* NEW_BSL */
printf("Patch for flash programming required!\n");
patchRequired= TRUE;
#ifdef NEW_BSL
}
#endif /* NEW_BSL */
#endif /* WORKAROUND */
BSLMemAccessWarning= 1;
}
else
{
BSLMemAccessWarning= 0; /* Fixed in newer versions of BSL. */
}
}
if (patchRequired || ((newBSLFile != NULL) && (bslVer <= 0x0110)))
{
/* Execute function within bootstrap loader
* to prepare stack pointer for the following patch.
* This function will lock the protected functions again.
*/
printf("Load PC with 0x0C22...\n");
if ((error= bslTxRx(BSL_LOADPC, /* Command: Load PC */
0x0C22, /* Address to load into PC */
0, /* No additional data! */
NULL, blkin)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
/* Re-send password to re-gain access to protected functions. */
if ((error= txPasswd(passwdFile)) != ERR_NONE)
{
return(signOff(error, TRUE)); /* Password was transmitted! */
}
}
#ifdef NEW_BSL
if (newBSLFile != NULL)
{
printf("Load new BSL \"%s\" into RAM...\n", newBSLFile);
if ((error= programTIText(newBSLFile, /* File to program */
ACTION_PROGRAM)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
printf("Verify new BSL \"%s\"...\n", newBSLFile);
if ((error= programTIText(newBSLFile, /* File to verify */
ACTION_VERIFY)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
/* Read startvector of bootstrap loader: */
if ((error= bslTxRx(BSL_RXBLK, 0x0300, 2, NULL, blkin)) == ERR_NONE)
{
WORD startaddr;
memcpy(&startaddr, &blkin[0], 2);
printf("Starting new BSL at %x...\n", startaddr);
error= bslTxRx(BSL_LOADPC, /* Command: Load PC */
startaddr, /* Address to load into PC */
0, /* No additional data! */
NULL, blkin);
}
if (error != ERR_NONE)
{
return(signOff(error, FALSE));
}
/* BSL-Bugs should be fixed within "new" BSL: */
BSLMemAccessWarning= 0;
patchRequired= FALSE;
patchLoaded = FALSE;
/* Re-send password to re-gain access to protected functions. */
if ((error= txPasswd(passwdFile)) != ERR_NONE)
{
return(signOff(error, TRUE)); /* Password was transmitted! */
}
}
#endif/* NEW_BSL */
#ifdef WORKAROUND
if (patchRequired)
{
printf("Load and verify patch \"%s\"...\n", patchFile);
/* Programming and verification is done in one pass.
* The patch file is only read and parsed once.
*/
if ((error= programTIText(patchFile, /* File to program */
ACTION_PROGRAM | ACTION_VERIFY)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
patchLoaded= TRUE;
}
#endif /* WORKAROUND */
#ifdef NEW_BSL
if ((newBSLFile != NULL) && (passwdFile != NULL) && toDo.MassErase)
{
/* Erase the flash memory completely (with mass erase command): */
printf("Mass Erase...\n");
if ((error= bslTxRx(BSL_MERAS, /* Command: Mass Erase */
0xff00, /* Any address within flash memory. */
0xa506, /* Required setting for mass erase! */
NULL, blkin)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
passwdFile= NULL; /* No password file required! */
}
#endif /* NEW_BSL*/
if (!toDo.OnePass)
{
if (toDo.EraseCheck)
{
/* Parse file in TXT-Format and
* check the erasure of required flash cells.
*/
printf("Erase Check by file \"%s\"...\n", filename);
if ((error= programTIText(filename, ACTION_ERASE_CHECK)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
}
if (toDo.Program)
{
/* Parse file in TXT-Format and program data into flash memory. */
printf("Program \"%s\"...\n", filename);
if ((error= programTIText(filename, ACTION_PROGRAM)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
else
{
printf("%i bytes programmed.\n", byteCtr);
}
}
if (toDo.Verify)
{
/* Verify programmed data: */
printf("Verify \"%s\"...\n", filename);
if ((error= programTIText(filename, ACTION_VERIFY)) != ERR_NONE)
{
return(signOff(error, FALSE));
}
}
}
else
{
unsigned action= 0;
if (toDo.EraseCheck)
{
action |= ACTION_ERASE_CHECK; printf("EraseCheck ");
}
if (toDo.Program)
{
action |= ACTION_PROGRAM; printf("Program ");
}
if (toDo.Verify)
{
action |= ACTION_VERIFY; printf("Verify ");
}
if (action != 0)
{
printf("\"%s\" ...\n", filename);
error= programTIText(filename, action);
if (error != ERR_NONE)
{
return(signOff(error, FALSE));
}
else
{
printf("%i bytes programmed.\n", byteCtr);
}
}
}
return(signOff(ERR_NONE, FALSE));
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -