📄 bsldemo.c
字号:
/****************************************************************
*
* Copyright (C) 1999-2000 Texas Instruments, Inc.
* Author: Volker Rzehak
* Co-author: FRGR
*
*----------------------------------------------------------------
* All software and related documentation is provided "AS IS" and
* without warranty or support of any kind and Texas Instruments
* expressly disclaims all other warranties, express or implied,
* including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. Under no
* circumstances shall Texas Instruments be liable for any
* incidental, special or consequential damages that result from
* the use or inability to use the software or related
* documentation, even if Texas Instruments has been advised of
* the liability.
*
* Unless otherwise stated, software written and copyrighted by
* Texas Instruments is distributed as "freeware". You may use
* and modify this software without any charge or restriction.
* You may distribute to others, as long as the original author
* is acknowledged.
*
****************************************************************
*
* Project: MSP430 Bootstrap Loader Demonstration Program
*
* File:BSLDEMO.C
*
* Description:
* This is the main program of the bootstrap loader
* demonstration.
* The main function holds the general sequence to access the
* bootstrap loader and program/verify a file.
* The parsing of the TI TXT file is done in a separate
* function.
*
* A couple of parameters can be passed to the program to
* control its functions. For a detailed description see the
* appendix of the corresponding application note.
*
* History:
* Version 1.00 (05/2000)
* Version 1.10 (08/2000)
* - Help screen added.
* - Additional mass erase cycles added
* (Required for larger flash memories)
* Defined with: #define ADD_MERASE_CYCLES 20
* - Possibility to load a completely new BSL into RAM
* (supposing there is enough RAM) - Mainly a test feature!
* - A new workaround method to cope with the checksum bug
* established. Because this workaround is incompatbile with
* the former one the required TI TXT file is renamed to
* "PATCH.TXT".
* Version 1.12 (09/2000)
* - Added handling of frames with odd starting address
* to BSLCOMM.C. (This is required for loaders with word
* programming algorithm! > BSL-Version >= 1.30)
* - Changed default number of data bytes within one frame
* to 240 bytes (old: 64). Speeds up programming.
* - Always read BSL version number (even if new one is loaded
* into RAM.
* - Fixed setting of warning flag in conjunction with loading
* a new BSL into RAM.
* - Added a byte counter to the programTIText function.
* - Number of mass erase cycles can be changed via command
* line option (-m)
* Version 1.14
* 11/2000 FRGR:
* - Minor text bug fixes and cosmetics (title aso...).
* - Read startaddress for loadable BSL from file
* 05/2001 FRGR:
* - Implementation of "+f" parameter for Fast Erase Check by
* File (BSL cmd "0x1C"). Could be speeded up for Mass
* Erase (one single command with whole address range).
* - Bargraph for displaying progress of read/write activities.
* 08/2001 FRGR:
* - See test sequences for new features at file end.
* - Skip verify if BSL with online verification is used.
* - Implementation of "-s{0,1,2}" parameter for Change Baudrate
* command (BSL cmd "0x20").
* - Implementation of "+#" parameter for executing test sequences
* - Time measurement for "Prog/Verify" and "Over all" (in sec).
* Version 1.15
* 01/2004 FRGR
* - Test sequence: Wrong password performs a Mass Erase.
* - Implementation of "+u" parameter for "User Call" simulation
* - Open Help screen also if no cmdline parameter.
* UPSF
* - Fixed bug in end detection of help
* Version 2.00
* 10/2004 FRGR
* - added support for 2.xx
* 03/2005 UPSF
* - added updated support for 2.xx
* - added read file function
* - added support for higher COM ports ( > COM4 )
* - added Erase Segment function
* - added support for Extended Memory (MSP430X)
* - added restore function for InfoA Segment
* - fixed handling of wait option - it got ignored in +option
* - changed parsing of command line so that a parameter without + or - is used as filename
*
****************************************************************/
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include "bslcomm.h"
#include "TI_TXT_Files.h"
/*---------------------------------------------------------------
* Defines:
*---------------------------------------------------------------
*/
/* This definition includes code to load a new BSL into RAM:
* NOTE: Can only be used with devices with sufficient RAM!
* The program flow is changed slightly compared to a version
* without "NEW_BSL" defined.
* The definition also defines the filename of the TI-TXT file
* with the new BSL code.
*/
#define NEW_BSL
/* The "WORKAROUND" definition includes code for a workaround
* required by the first version(s) of the bootstrap loader.
*/
#define WORKAROUND
/* If "DEBUGDUMP" is defined, all checked and programmed blocks are
* logged on the screen.
*/
#define DEBUGDUMP
/* Additional mass erase cylces required for (some) F149 devices.
* If ADD_MERASE_CYCLES is not defined only one mass erase
* cycle is executed.
* Remove #define for fixed F149 or F11xx devices.
*/
#define ADD_MERASE_CYCLES 20
/* Error: verification failed: */
#define ERR_VERIFY_FAILED 98
/* Error: erase check failed: */
#define ERR_ERASE_CHECK_FAILED 97
/* Error: unable to open input file: */
#define ERR_FILE_OPEN 96
/* Mask: program data: */
#define ACTION_PROGRAM 0x01
/* Mask: verify data: */
#define ACTION_VERIFY 0x02
/* Mask: erase check: */
#define ACTION_ERASE_CHECK 0x04
/* Mask: transmit password: */
/* Note: Should not be used in conjunction with any other action! */
#define ACTION_PASSWD 0x08
/* Mask: erase check fast: */
#define ACTION_ERASE_CHECK_FAST 0x10
/*---------------------------------------------------------------
* Global Variables:
*---------------------------------------------------------------
*/
char *programName= "MSP430 Bootstrap Loader Communication Program";
char *programVersion= "Version 2.00SE *** SPECIAL EDITION WITH INVERTED DTR/RTS CONTROL LINES ***";
/* Max. bytes sent within one frame if parsing a TI TXT file.
* ( >= 16 and == n*16 and <= MAX_DATA_BYTES!)
*/
int maxData= 240;
/* Buffers used to store data transmitted to and received from BSL: */
BYTE blkin [MAX_DATA_BYTES]; /* Receive buffer */
BYTE blkout[MAX_DATA_BYTES]; /* Transmit buffer */
#ifdef WORKAROUND
char *patchFilename = "PATCH.TXT";
char *patchFile = NULL;
#endif /* WORKAROUND */
BOOL patchRequired = FALSE;
BOOL patchLoaded = FALSE;
WORD bslVer = 0;
WORD _addr, _len, _err;
BYTE speed = 0; /* default 9600 Baud */
DWORD Time_BSL_starts, Time_PRG_starts, Time_BSL_stops;
char *newBSLFile= NULL;
char newBSLFilename[256];
struct toDoList
{
unsigned MassErase : 1;
unsigned EraseCheck: 1;
unsigned FastCheck : 1;
unsigned Program : 1;
unsigned Verify: 1;
unsigned Reset : 1;
unsigned Wait : 1; /* Wait for <Enter> at end of program */
/* (0: no; 1: yes): */
unsigned OnePass : 1; /* Do EraseCheck, Program and Verify */
/* in one pass (TI TXT file is read */
/* only once) */
unsigned SpeedUp : 1; /* Change Baudrate */
unsigned UserCalled: 1; /* Second run without entry sequence */
unsigned BSLStart: 1; /* Start BSL */
unsigned Dump2file:1; /* Dump Memory to file */
unsigned EraseSegment:1;/* Erase Segment */
unsigned MSP430X:1; /* Enable MSP430X Ext.Memory support */
unsigned RestoreInfoA:1;/* Enable MSP430X Ext.Memory support */
} toDo;
int error= ERR_NONE;
int i, j;
char comPortName[20]= "COM1"; // Default setting.
char *filename= NULL;
char *passwdFile= NULL;
char passwdFilename[256];
BYTE bslVerHi, bslVerLo, devTypeHi, devTypeLo, devProcHi, devProcLo;
WORD bslerrbuf;
#ifdef ADD_MERASE_CYCLES
int meraseCycles= ADD_MERASE_CYCLES;
#else
const int meraseCycles= 1;
#endif // ADD_MERASE_CYCLES
long readStart = 0;
long readLen = 0;
char *readfilename = NULL;
void *errData= NULL;
int byteCtr= 0;
/*---------------------------------------------------------------
* Functions:
*---------------------------------------------------------------
*/
int preparePatch()
{
int error= ERR_NONE;
#ifdef WORKAROUND
if (patchLoaded)
{
/* Load PC with 0x0220.
* This will invoke the patched bootstrap loader subroutines.
*/
error= bslTxRx(BSL_LOADPC, /* Command: Load PC */
0x0220, /* Address to load into PC */
0, /* No additional data! */
NULL, blkin);
if (error != ERR_NONE) return(error);
BSLMemAccessWarning= 0; /* Error is removed within workaround code */
}
#endif /* WORKAROUND */
return(error);
}
void postPatch()
{
#ifdef WORKAROUND
if (patchLoaded)
{
BSLMemAccessWarning= 1; /* Turn warning back on. */
}
#endif /* WORKAROUND */
}
int verifyBlk(unsigned long addr, WORD len, unsigned action)
{
int i= 0;
int error= ERR_NONE;
if ((action & (ACTION_VERIFY | ACTION_ERASE_CHECK)) != 0)
{
#ifdef DEBUGDUMP
printf("Check starting at %x, %i bytes... ", addr, len);
#endif /* DEBUGDUMP */
error= preparePatch();
if (error != ERR_NONE) return(error);
if (toDo.MSP430X) {
if (error = bslTxRx(BSL_MEMOFFSET, 0, (WORD)(addr>>16), NULL, blkin) !=0) return (error);
addr = addr & 0xFFFF;
}
error= bslTxRx(BSL_RXBLK, addr, len, NULL, blkin);
postPatch();
#ifdef DEBUGDUMP
printf("Error: %i\n", error);
#endif /* DEBUGDUMP */
if (error != ERR_NONE)
{
return(error); /* Cancel, if read error */
}
else
{
for (i= 0; i < len; i++)
{
if ((action & ACTION_VERIFY) != 0)
{
/* Compare data in blkout and blkin: */
if (blkin[i] != blkout[i])
{
printf("Verification failed at %x (%x, %x)\n", addr+i, blkin[i], blkout[i]);
return(ERR_VERIFY_FAILED); /* Verify failed! */
}
continue;
}
if ((action & ACTION_ERASE_CHECK) != 0)
{
/* Compare data in blkin with erase pattern: */
if (blkin[i] != 0xff)
{
printf("Erase Check failed at %x (%x)\n", addr+i, blkin[i]);
return(ERR_ERASE_CHECK_FAILED); /* Erase Check failed! */
}
continue;
} /* if ACTION_ERASE_CHECK */
} /* for (i) */
} /* else */
if (toDo.MSP430X)
if (error = bslTxRx(BSL_MEMOFFSET, 0, (WORD)(0),NULL, blkin) !=0) return (error);
} /* if ACTION_VERIFY | ACTION_ERASE_CHECK */
else if ((action & ACTION_ERASE_CHECK_FAST) != 0) /* FRGR 02/01 */
{
#ifdef DEBUGDUMP
printf("Fast Check starting at %x, %i bytes... ", addr, len);
#endif /* DEBUGDUMP */
error= preparePatch();
if (error != ERR_NONE) return(error);
error= bslTxRx(BSL_ECHECK, addr, len, NULL, blkin);
postPatch();
#ifdef DEBUGDUMP
printf("Error: %i\n", error);
#endif /* DEBUGDUMP */
if (error != ERR_NONE)
{
return(ERR_ERASE_CHECK_FAILED); /* Erase Check failed! */
}
} /* if ACTION_ERASE_CHECK_FAST */
return(error);
}
int programBlk(unsigned long addr, WORD len, unsigned action)
{
int i= 0;
int error= ERR_NONE;
if ((action & ACTION_PASSWD) != 0)
{
return(bslTxRx(BSL_TXPWORD, /* Command: Transmit Password*/
addr, /* Address of interupt vectors */
len, /* Number of bytes */
blkout, blkin));
} /* if ACTION_PASSWD */
/* Check, if specified range is erased: */
if (action & ACTION_ERASE_CHECK)
error= verifyBlk(addr, len, action & ACTION_ERASE_CHECK);
else if (action & ACTION_ERASE_CHECK_FAST)
error= verifyBlk(addr, len, action & ACTION_ERASE_CHECK_FAST);
if (error != ERR_NONE)
{
return(error);
}
if ((action & ACTION_PROGRAM) != 0)
{
#ifdef DEBUGDUMP
printf("Program starting at %x, %i bytes... ", addr, len);
#endif /* DEBUGDUMP */
error= preparePatch();
if (error != ERR_NONE) return(error);
/* Set Offset: */
if (toDo.MSP430X) error= bslTxRx(BSL_MEMOFFSET, 0, (WORD)(addr>>16), blkout, blkin);
if (error != ERR_NONE) return(error);
/* Program block: */
error= bslTxRx(BSL_TXBLK, addr, len, blkout, blkin);
postPatch();
#ifdef DEBUGDUMP
printf("Error: %i\n", error);
#endif /* DEBUGDUMP */
if (error != ERR_NONE)
{
return(error); /* Cancel, if error (ACTION_VERIFY is skipped!) */
}
if (toDo.MSP430X)
if (error = bslTxRx(BSL_MEMOFFSET, 0, (WORD)(0),NULL, blkin) !=0) return (error);
} /* if ACTION_PROGRAM */
/* Verify block: */
error= verifyBlk(addr, len, action & ACTION_VERIFY);
if (error != ERR_NONE)
{
return(error);
}
return(error);
} /* programBlk */
unsigned int readStartAddrTIText(char *filename) /* FRGR */
{
WORD startAddr=0;
char strdata[128];
FILE* infile;
if ((infile = fopen(filename, "rb")) == 0)
{
errData= filename;
return(ERR_FILE_OPEN);
}
/* TXT-File is parsed for first @Addr occurence: */
while (TRUE)
{
/* Read one line: */
if (fgets(strdata, 127, infile) == 0) /* if End Of File */
{
break;
}
if (strdata[0] == '@') /* if @ => start address */
{
sscanf(&strdata[1], "%x\n", &startAddr);
break;
}
}
fclose(infile);
return(startAddr);
} /* readStartAddrTIText */
int programTIText (char *filename, unsigned action)
{
int next= 1;
int error= ERR_NONE;
int linelen= 0;
int linepos= 0;
int i, KBytes, KBytesbefore= -1;
WORD dataframelen=0;
unsigned long currentAddr;
char strdata[128];
FILE* infile;
byteCtr= 0;
if ((infile = fopen(filename, "rb")) == 0)
{
errData= filename;
return(ERR_FILE_OPEN);
}
/* Convert data for MSP430, TXT-File is parsed line by line: */
while (TRUE) /* FRGR */
{
/* Read one line: */
if ((fgets(strdata, 127, infile) == 0) ||
/* if End Of File or */
(strdata[0] == 'q'))
/* if q (last character in file) */
{ /* => send frame and quit */
if (dataframelen > 0) /* Data in frame? */
{
error= programBlk(currentAddr, dataframelen, action);
byteCtr+= dataframelen; /* Byte Counter */
dataframelen=0;
}
break; /* FRGR */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -