BSL (MSP430)
From Texas Instruments Embedded Processors Wiki
Contents |
Intro to the MSP430 BSL
The Bootstrap Loader, or BSL, is a program built into an MSP430 device designed to communicate with the device, primarily for the purpose of reading and writing to memory. This is often done via commands send through a serial link (UART), but can be done via USB on some 5xx/6xx devices.
The Bootstrap Loader can be divided into two major types: ROM based BSLs found in the 1xx/2xx/4xx devices, and Flash based BSLs found in 5xx and 6xx devices. Though similar, both BSLs have a different protocol and command structure. In addition, the Flash based BSLs can be overwritten with a new program, for instance a BSL which communicates via I2C.
The primary document which describes the use of all BSLs is `MSP430 Programming Via the Bootstrap Loader' (SLAU319). This document describes, in detail, all aspects of all BSLs shipped with TI devices. It is the only document required for the creation of a system which will use the TI BSLs for production programming or other purposes.
Devices in the 5xx and 6xx family have the ability to overwrite the TI-supplied BSL with custom software. This is useful for doing things such as changing the method of communication, or adding desired features not present in the TI standard BSL. In order to facilitate this, an application report has been supplied which describes how a custom BSL can be made: `Creating a Custom Flash-Based BSL' (SLAA450). This document supplies all information for those looking to create their own BSL solution.
Additionally, source code for all shipping BSLs is supplied to jump-start development through code reuse.
In addition to the above mentioned documentation, answers to many questions can be found on the TI E2E forums.
Migration from 1/2/4xx BSL to 5xx UART BSL
Note: This section is the preliminary guide for what will become a section in the BSL User's Guide. Feedback and comments are appreciated.
The 5xx UART BSL is a completely re-written BSL, though it shares many features in common with the previous 1/2/4xx BSLs. This section is intended to point out key differences (and similarities) to allow users to become familiar with the 5xx BSL quickly. Detailed explanations of all items listed here are available in the BSL User's Guide (SLAU319)
Hardware: The same hardware can be used for communication with the 5xx UART BSL. UART TX/RX, Vcc/GND, and REST/TEST connections are required. In addition, the BSL invoke sequence is identical (with the exception of devices which have bug SYS10)
UART: The default UART protocol is also the same: 9600 baud, Start Bit, 8 data bits, an even parity bit, and one stop bit. The only exception is the 5438 non-A (See SLAU319 Section 5.1 for more details) The 5xx does use the internal calibrated oscillator, so early preview material without calibration might not communicate at the correct baud rate.
Security: The BSL still uses the interrupt vector table as a password, and mass erases the device in the case of an incorrect password. The 5xx BSL does not erase the Info memory however. The 5xx BSL does clear the RAM on startup. Unlike the 2xx BSL, the 5xx BSL can not be disabled via a word in User Flash, nor can the mass erase on incorrect password.
Protocol: The 5xx BSL has a completely new protocol. The commands are described in detail in SLAU319 Chapter 3.
Firmware: The 5xx BSL does not have a warm start option. All user based BSL invokes begin by setting the PC to 0x1000. There is also a new function for returning to the BSL (for instance, if a test program was loaded into RAM). See SLAU319 Section 3.7.2 for more details. In addition, the BSL firmware itself is stored in a secure flash location, allowing it to be modified or erased for extra security.
Overall Guidelines for ROM-based BSL (1xx,2xx and 4xx Devices)
Although the method described below is fairly robust, it should be remembered that it is still flash, can still be erased or get errors, and perhaps render your device totally unreachable
That being said, there are some things that can be done to mitigate this risk. Firstly, an implementation of a flash monitor is already described in Application Report slaa341
I would make the following additions, for robustness:
Firstly, it is important that the BSL code reside in a separate section of flash from the application code, which will never be erased. The Interrupt vectors can never be erased either, as the Reset vector always has to point to the BSL program.
- On startup, the system must first execute the BSL code. This BSL code will do a CRC on the Application code. It compares this CRC to a value stored in flash at the beginning of the Application code flash section.
- Only if the CRC check passes, the BSL will the BSL jump into the Application code and begin running
- If the CRC check fails, the BSL knows the Application code is not valid, and waits for communication from an outside source to load in code.
Updating of the Application code proceeds as follows:
- A command is received by the UART ISR, and is seen to be a BSL Command. The ISR exits to the BSL code to begin executing the BSL.
- The BSL erases the Application code flash sector, this includes the previously stored CRC value (setting it to 0xFFFF).
- The BSL receives the code, and writes it to the application sector.
- After all the code is received, it runs a CRC on the Application code, and communicates this back to the host to verify correct programming. Only after this is done, it saves the CRC value to flash.
- The important thing to note, is that the CRC is saved to flash only after the BSL is 100% sure the code is written correctly. This means that if a reset occurs for some reason, the BSL will start up, but not execute Application code if it was half written.
It is important to note, that because the interrupt vectors can never be erased, they must always point to static known locations. The easiest way to do this would be to have a "double jump" table. In this way, the standard 430 interrupt vectors point into a list of jump instructions within the application code, which then jumps off to the real ISRs. Additionally, the RESET vector must also point to the BSL, and the UART ISR must also first examine packets to see if they are BSL packets, then pass them to the application.
The important thing to remember, is that you want to guard against the case where the device resets half way into an update. Since there is no way to recover through hardware (ie. a ROM BSL) you have to always be certain that the device never executes incorrect code.
Custom MSP430 BSL for 1xx/2xx/4xx Devices
Custom MSP430 BSL for 5xx Devices
Implementing Custom BSL for 5xx devices is described in the following `Creating a Custom Flash-Based Bootstrap Loader (BSL)' (SLAA450) application note.
Implementing Custom BSL solution on 5xx devices means that it is possible to adapt the following points:
- how the BSL code is invoked - (see the #Device Startup Sequence section)
- the communication peripheral interface (e.g. UART, I2C, SPI, USB, etc.)
- the protocol (set of commands) used between the BSL and the host processor
- adapting the memory type
in order to suit the application requirements/limitations. However it is important to be noticed that the whole BSL code space is only 2 KB. Usually it is only necessary to adapt the invoke process and the communication peripheral interface only, while the BSL protocol and the memory type are used per default.
Device Startup Sequence
The device startup sequence plays an important role to show how flexible the custom BSL can be implemented to meet the application requirements. To make it easier on understanding the device startup sequence and the BSL code implementation, this following section will explain the device startup sequence along with the implementation of MSP430F5438A BSL implementation using CCS v4.2.0 which can be found in the BSL software source package under Custom_BSL_Zip_File\Example_BSL_Source\CCS_v4.2.0_BSL-5438A directory. The device startup sequence of 5xx/6xx MSP430 device can be illustrated as follows:
(1) If a 5xx device is reset, the device will first of all execute the boot code which will check whether it is necessary to run the BSL code. The boot code will basically check two things before deciding whether to run the BSL code or the user application code: the BSL Signature and the return value of BSL Protect function. This will be explained further in the following steps.
NOTE: The boot code will be only executed on hardware reset (pulling down the /RST signal). Software reset such as using watchdog timer, setting the PMMSWBOR or PMMSWPOR of PMMCTL0 will not trigger the boot code.
(2) For the first verification step, the boot code will start to check whether a valid BSL Signature is available at the memory address 0x17F4 and 0x17F6. The BSL Signature indicates whether a valid BSL resides in the BSL Flash memory. The valid BSL signature values at memory address 0x17F4 and 0x17F6 are 0x3CA5 and 0xC35A respectively.
In the MSP430F5438A BSL implementation, the BSL signature can be found in the BSL430_Low_Level_Init.asm under the “BSLSIG” section as follows:
.sect "BSLSIG" .word 0xFFFF BslProtectVecLoc .word BSL_Protect ;adress of function PBSLSigLoc .word 03CA5h ;1st BSL signature SBSLSigLoc .word 0C35Ah ;2nd BSL signature .word 0xFFFF BslEntryLoc .word BSL_Entry_JMP ;BSL_Entry_JMP PJTAGLOCK_KEY .word 0xFFFF ; Primary Key Location SJTAGLOCK_KEY .word 0xFFFF ; Secondary Key Location ; set default unlock JTAG with option to lock with writting ; a value <> 0x0000 or 0xFFFF
The “BSLSIG” section itself is defined in the linker command file lnk_msp430f5438a.cmd as the memory area starting at address 0x17F0 with the length of 16 bytes:
MEMORY
{
. . . .
BSLSIG : origin = 0x17F0, length = 0x0010
. . . .
}
SECTIONS
{
. . . .
BSLSIG : {} > BSLSIG
. . . .
}
(3) If a valid BSL Signature is found, the boot code will run the BSL Protect function which is pointed by the content of memory address 0x17F2. As can be seen in the implementation of “BSLSIG” section above, the pointer to BSL_Protect is stored in the second word of “BSLSIG” section which basically refers to the address 0x17F2.
The BSL Protect function has basically the following tasks:
- Set the appropriate value of SYSBSLC register to protect the BSL flash memory which contains the BSL code.
- Verify whether it is really necessary to run the BSL and report the result to the boot code by setting/resetting Bit 1 (value 0x02) of R12 (R12 is also used in interfacing C-Assembly code together with R12 if necessary to contain return value of a function).
The step in the BSL Protect function for verifying whether it is necessary to run the BSL code can be flexibly adapted to meet the application requirements/limitations.
Referring to the SLAU319A chapter 1.3, the default way to invoke the BSL for device without USB interface is to apply a specific BSL Entry sequence signals on the RST and TEST/TCK pins of the device. This seems to be a hardware dependent process, but actually for the 5xx family devices such as the MSP430F5438A, it is implemented in software. In the MSP430F5438A BSL code implementation, the BSL Protect function is implemented in BSL430_Low_Level_Init.asm file as follows:
BSL_Protect
CLR RET_low ;lock (keep JTAGLOCK_KEY state)
BIC #SYSBSLPE+SYSBSLSIZE0+SYSBSLSIZE1 , &SYSBSLC ; protects BSL
;BIC #BSL_REQ_JTAG_OPEN, RET_low ;lock (keep JTAGLOCK_KEY state)
;BIS #BSL_REQ_JTAG_OPEN, RET_low ;make sure it remains open for debugging
bit #SYSBSLIND,&SYSCTL ;check for BSL start request
jz BCC2BSL
BIS.W #BSL_REQ_APP_CALL, RET_low
BCC2BSL RETAAs can be seen above, the MSP430F5438A default BSL Protect function only checks the SYSBSLIND bit of the SYSCTL register (which will be set if the BSL Entry sequence signals are applied to the RST and TEST/TCK pins) and set the Bit 1 (BSL_REQ_APP_CALL) of R12 (RET_low) if necessary. This shows that the way to invoke the BSL can be adapted through software.
The following example shows how to invoke a custom BSL for MSP430F5438A using the MSP-EXP430F5438 experimenter board by pressing the S1 switch (connected to P2.6). LED1 which is connected to P1.0 will be also turned on as indication if the BSL code is executed. The implementation of BSL Protect function for this custom BSL is as follows:
BSL_Protect
CLR RET_low ;lock (keep JTAGLOCK_KEY state)
BIC #SYSBSLPE+SYSBSLSIZE0+SYSBSLSIZE1 , &SYSBSLC ; protects BSL
;BIC #BSL_REQ_JTAG_OPEN, RET_low ;lock (keep JTAGLOCK_KEY state)
;BIS #BSL_REQ_JTAG_OPEN, RET_low ;make sure it remains open for debugging
BIC.B #BIT0, &P1OUT ; Clear LED0 by default
BIS.B #BIT0, &P1DIR ; Set LED0 as output
BIS.B #BIT6, &P2REN ; Enable pull resistor on S1
BIS.B #BIT6, &P2OUT ; select pull-up
BIT.B #BIT6, &P2IN ; Check S1
jnz BCC2BSL
BIS.B #BIT0, &P1OUT ; Turn ON LED if staying in BSL
BIS.W #BSL_REQ_APP_CALL, RET_low
BCC2BSL RETAAnother example is the implementation of BSL code for 5xx devices which has USB interface (e.g. MSP430F552x family). Referring to the SLAU319A document – chapter 1.3.3, the 5xx devices with USB can be invoked in two ways:
- powering up the device with the PUR tied to VUSB.
- powering up the device with USB and the reset vector is blank
Below is the implementation of BSL Protect function for the MSP430F552x devices:
BSL_Protect: CLR.W RET_low ; clears JTAG_OPEN, keeping KEY state BIS #SYSBSLPE+SYSBSLSIZE0+SYSBSLSIZE1 , &SYSBSLC ; protects BSL ;BIC.W #BSL_REQ_JTAG_OPEN, RET_low ;lock (keep JTAGLOCK_KEY state) ;MOV.W #BSL_REQ_JTAG_OPEN, RET_low ;open mov.w #0x9628, &USBKEYPID bis.w #PSEIEN, &USBPHYCTL bit.w #PUR_IN, &USBCNF jnz REQUEST_BSL ; if PUR_IN set, request BSL cmp.w #0xFFFF, &0xFFFE ; otherwise, test for blank RESET jne JUST_RETA ; if not blank, skip delay and start ;--------------------------------------------------------------------- ; Delay for USB power-up mov.w #300, R11 DELAY_LOOP dec.w R11 jnz DELAY_LOOP ;--------------------------------------------------------------------- bit.w #USBBGVBV, &USBPWRCTL ; test for USB power jz JUST_RETA ; no power, jump to just start REQUEST_BSL BIS.W #BSL_REQ_APP_CALL, RET_low JUST_RETA bic.w #PSEIEN, &USBPHYCTL mov.b #0x00, &USBKEY RETA
As can be seen above, the BSL invocation for MSP430F552x is actually also purely implemented by software.
Therefore it is basically possible to adapt the BSL Protect function to invoke the BSL code on a way to meet the application requirements/limitations, e.g. BSL Protect function checks the checksum of flash content to verify if the user application code is valid: if checksum fails, BSL code shall be executed. However there are several things to be noticed when trying to implement custom BSL Protect function:
- There is only 2 KB flash memory space allocated for the whole BSL code, so avoid complex and long BSL Protect function because the 2 KB should also hold the real BSL software code itself.
- When the BSL Protect function requires a long processing time, the watchdog timer shall be halted otherwise the watchdog will fire during the BSL Protect function execution and reset the device. This will make the device to be no longer accessible because the device startup sequence can never finish (it will keep getting reset by the watchdog) and the JTAG access is available first after the device startup sequence finishes.
(4) When the BSL Protect returns, the boot code will check Bit 1 of R12 register. If it is set, the BSL code will be executed by jumping to the BSL Start Vector pointed by the address memory location 0x17FA, otherwise the boot code will execute the user application code by jumping to the memory area pointed by the System Reset interrupt at address 0xFFFE.
Invoking Custom BSL Example
In some cases, the connection interface to the MSP430 device in some system is very restricted. Imagine a small MSP430 sensor based sensor system which has only power line and serial communication interface to the outside world, in this case the most elegant way to run the BSL code is by sending a specific command to the MSP430 running the application code via the communication interface. The following custom BSL example tries to set an example on how this can be done.
- BSL code: File:CUSTOM BSL.zip
- Application code: File:CUSTOM BSL APP.zip
The CUSTOM_BSL code contains the BSL code where the BSL Protect function is modified to check for a BSL Flag String (“RUNBSL”) at the beginning as verification to invoke BSL code or not. The CUSTOM_BSL_APP code contains an example code where the application receives several possible UART commands (9600 bps, 8N1), such as “LED ON”, “LED OFF”, and “RUN BSL”. If the application receives “RUN BSL” commands it will try to invoke the BSL using three possible ways:
- Writing the BSL Flag String into the Info B memory and generating software reset (software BOR)
- Writing the BSL Flag String into the Info B memory and requesting for hardware reset to trigger the boot code.
- Jumping directly to the Z-AREA to run the BSL code directly.
There are several compile options in the appl.c file which are explained as follows:
- INVOKE_BSL_WITHOUT_RESET: As explained above, there are three possible ways to invoke the BSL: using software reset, hard reset, or jumping directly to Z-AREA. Defining INVOKE_BSL_WITHOUT_RESET macro will use the latter.
- USE_SW_RESET: This macro is used for test purpose only as the application code tries to do a self-software reset after writing the BSL Flag String into Info B memory. There are three implementations of software reset (WDT, software BOR, software POR), but only software BOR will cause boot code to run.
- SW_RESET :This macro is defined to determine which software reset to be tested. There are three possible software reset to be tested: using watchdog timer, software POR, or software BOR.
BSL Software Overview
The supplied BSL software is basically designed and written to be as modular as possible by dividing the software into three main modules:
- Peripheral Interface (PI) module:
The Peripheral Interface (PI) module implements the communication interface used by the BSL to communicate with the remote station which sends the BSL commands to the BSL. Usually the supplied BSL software uses a UART interface based on the Timer_A module, but it is possible to adapt other communication interfaces such as hardware UART, I2C, SPI, etc.
- BSL API:
The BSL API module implements the interface to the memory which the MSP430 devices posses. It includes basic memory functionality such as locking/unlocking, erasing, writing, reading, and checksum calculations. This module is written to be modular to enable interfacing between different memory types e.g. Flash, FRAM, etc.
- Command Interpreter:
The Command Interpreter module implements the BSL protocol which interprets the BSL Core Command bytes. It uses the PI module to send/retrieve the BSL command request/response, and the BSL API module to do the memory modification. The Command Interpreter module is also written in modular way to enable excluding some BSL core command using preprocessors and also defining new BSL command if necessary.
General Custom BSL FAQ
Q: "What happens with erasure of the vector table? Is it considered one separate 64-byte segment (for purposes of erasure) or is it considered a part of the upper-most 512 byte “segment” of the lower 64KB memory? Next, may individual vectors be re-written?
A: The vector table is not a separate segment. It is considered in the uppermost 512-byte segment and is not 'protected' from erasure during a mass-erase, for example. Individual vectors may be re-written, but only if the whole segment is erased first.
The segment boundaries can be counted from the 0xFFFF boundary and down and then from the 0x10000 boundary and up.
Yes, this causes a concern for a user-BSL in RAM, specifically the possibility that you lose power while the IVT is erased and you end up with a device that must be reprogrammed through the hardware BSL. You must either ensure power during the BSL transfer, or keep a backup image that will be restored in the case that the BSL update fails.
Q: "How can the robustness of the firmware update process be improved, to guard against possible power failures and other events?"
A: One solution is to have a fixed boot loader that always is invoked directly after RESET. This custom boot loader should “own” the memory segment containing the RESET vector and the device’s interrupt vectors and not erase/program this region. But in this case, how to allow the end application to use interrupts? Solution: Re-route interrupt requests. Boot loader to contain small “stub functions” that transfer ISR execution to an address stored in the main application program's memory image. Custom linker command files should be used for the boot loader and the main application to establish the devices memory map and to relocate the interrupt vector table of the main application program, see below example. This will add an interrupt latency of 3-5 cycles depending on the device's CPU architecture. Other options would be to locate the ISRs at fixed addresses, or to directly use a RAM based interrupt vector table (see SYSRIVECT control bit on 5xx-based devices).
MSP430 Custom BSL Memory Map Example:
MSP430 Interrupt Vector Re-Routing Example:
BSL Tools
Currently there is no official hardware solution from TI for accessing MSP430 BSL. However there are some possibilities, such as hardware tools from third parties (e.g. FlashPro430 from Elprotronic), or chapter 4 of the SLAU319 describes a simple and low-cost hardware and software solutions to access the MSP430 BSL via the PC serial port (RS-232). The hardware can be used together with PC programs which comes with the associated files of the SLAU319.
There are two PC programs for communicating with the BSL which can be found in the SLAU319 associated files:
- BSL DEMO: software tool for accessing the ROM based BSL (1xx, 2xx, 4xx devices). It is however deprecated and not officially supported, but available in executable file and source code. It can be found under the BSL_Files\Deprecated\BSLDEMO folder of the SLAU319 associate file. There is no manual/user's guide for it, the only description how to use the BSL DEMO is by executing it with "-h" parameter which will give the following help description:
>BSLDEMO2.exe -h
MSP430 Bootstrap Loader Communication Program (Version 2.00)
BSLDEMO [-h][-c{port}][-s{num}][-p{file}][-w][-1][-m{num}][+ecpvruw] {file}
Options:
-h Shows this help screen.
-c{port} Specifies the communication port to be used (e.g. -cCOM2).
-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).
-e{startnum}
Erase Segment where address does point to.
-m{num} Number of mass erase cycles (e.g. -m20).
-p{file} Specifies a TI-TXT file with the interrupt vectors that are
used as password (e.g. -pINT_VECT.TXT).
-r{startnum} {lennum} {file}
Read memory from startnum till lennum and write to file as TI.TXT.
(Values in hex format.)
-s{num} Changes the baudrate; num=0:9600, 1:19200, 2:38400 (e.g. -s2).
-w Waits for <ENTER> before closing serial port.
-x Enable MSP430X Extended Memory suppport.
-1 Programming and verification is done in one pass through the file.
Program Flow Specifiers [+aecpvruw]
a Restore InfoA after mass erase (only with Mass Erase)
e Mass Erase
c Erase Check by file {file}
p Program file {file}
v Verify by file {file}
r Reset connected MSP430. Starts application.
u User Called - Skip entry Sequence.
w Wait for <ENTER> before closing serial port.
Only the specified actions are executed!
Default Program Flow Specifiers (if not explicitly given): +ecpvr
- BSL Scripter: software tool for accessing the Flash based BSL (5xx/6xx devices). It can be found under the BSL_Files\BSL Scripter folder of the SLAU319 associate file. The BSL scripter is available in executable (.EXE) file and also in source code. The easiest way to compile the source code is by using the Microsoft Visual Studio C++ 2010 Express Edition.
(NOTE: for the following solutions, there is no official support)
The BSL Scripter project file and source code for the Microsoft Visual Studio C++ 2010 Express Edition can be downloaded here: media:BSL_Scripter_VC++.zip. There is a known bug that prevent the BSL Scripter to work with PC COM PORT greater than 9. The BSL executable file with the fixed bug can be downloaded here: media:BSL_Scripter.zip
Errata
SLAU319
| Page | Section | Correction |
| 43 | Table 5-6 | The device list should include 'F23xx |
| 44 | Section 5.4 | The Section title should include F14x1 and F13x devices |
SLAU319A
| Page | Section | Correction |
| 43 | Table 5-7 | The "preperation for software call" of F261x is missing |
SLAA450A
| Page | Section | Correction |
| 8 | Section 5.1 | The "FLASH_AREA" linker command file is missing in the associated file |


