This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR58891: BSL - Custom

Part Number: MSP430FR58891


I have inherited a custom Bootloader application that was designed for a 2272 uC that I have ported to a 58891. The customer bootloader accepts the downloaded image from a LabVIEW application running on the serial port (eUSCI_A). The image successfully loads into the 58891 uC's FRAM (0x8000 -0xdfff)  and is verified. After a successful verification I jump to the CStart (0x8a38) location in the downloaded image.

// __asm( "mov.w &0xdffe, PC" ); //lnk430fr58891_Operational.xcl -Z(CODE)RESET=dffe-dfff
__asm( "mov.w #0x8a38, PC" ); //lnk430fr58891_Operational.xcl -Z(CODE)RESET=dffe-dfff

This action generates a RESET and the uC fetches the CStart (0x45fe) from my Bootloader application RESET vector( 0xFFFE) and proceeds to execute the custom Bootloader. I have the MPU disabled by calling MPU_Initialize() immediate at the beginning of main() (see below). I have a __intrinsic int __low_level_init(void) routine that I understand is executed by CStart and it is also set to disable the MPU. The bootloader is located at FRAM addresses 0x400-63ff. The Bootloader has the default interrupt  vector table at the top of the 64k address space( RESET 0xFFFE).

------------------------------------------------------------------------------------------------------------------------------

Filename: MPU.c

------------------------------------------------------------------------------------------------------------------------------





void MPU_Initialize( void ) {

MPUCTL0 = MPUPW; // 0xa500; // PWD, GIE =Disabled, LOCK =Open, ENA =Disabled

}



// This is example code from 
// MSP430™ FRAM Technology – How To and Best Practices SLAA628–June 2014
// p.10

/* see intrinsics.h
* If the application provides this function, it is called by the
* startup code before variables are initialized. If the function
* returns 0 the data segments will not be initialized.
*/
// __intrinsic int __low_level_init(void);

//#include "msp430.h"
__intrinsic int __low_level_init(void)
{
/* Insert your low-level initializations here */
WDTCTL = WDTPW+WDTHOLD;
// Configure MPU
MPUCTL0 = MPUPW; // Write PWD to access MPU registers
//MPUSEGB1 = 0x0480; // B1 = 0x4800; B2 = 0x4C00
//MPUSEGB2 = 0x04c0; // Borders are assigned to segments
// Segment 1 – Allows read and write only
// Segment 2 – Allows read only
// Segment 3 – Allows read and execute only
//MPUSAM = (MPUSEG1WE | MPUSEG1RE | MPUSEG2RE | MPUSEG3RE | MPUSEG3XE);
//MPUCTL0 = MPUPW | MPUENA | MPUSEGIE; // Enable MPU protection
// MPU registers locked until BOR
/*
* Return value:
*
* 1 - Perform data segment initialization.
* 0 - Skip data segment initialization.
*/
return 1;

------------------------------------------------------------------------------------------------------------------------------

Filename: lnk430fr58891_Operational.xcl

------------------------------------------------------------------------------------------------------------------------------



// ****************************** 8000-dfff
//
// XLINK configuration file for MSP430FR58891
//
// Copyright 1996-2016 IAR Systems AB.
//
// See the file 430/doc/licenses/IARSourceLicense.txt for detailed
// license information.
//
// $Revision: 13610 $
//
// ************************************************

// ---------------------------------------------------------
// Description
//

//
// Usage:
//
// xlink [file file ...] -f lnk430fr58891.xcl
//
// -----------------------------------------------
// Device summary
//

//
// Core: MSP430Xv2
//
// Interrupt vectors: 56
//
// Signature memory: 16 Bytes
//
// JTAG Signature memory: 4 Bytes
//
// BSL Signature memory: 4 Bytes
//
// IPE Signature memory: 8 Bytes
//
// Peripheral units: 00100-00FFF
//
// Information memory (FRAM): 01800-019FF
//
// Read/write memory (RAM): 01C00-023FF
//
// Read/write memory (TINYRAM): 00006-0001F
//
// Persistent memory (FRAM): 04400-0FFFF
// 10000-23FFF
//


// -----------------------------------------------
// Segments
//

// -------------------------------------
// Data read/write segments
//

//
// The following segments are available for both
// the DATA16 and DATA20 segment groups.
//
// segment Usage
// ------- --------------------------
// DATA<nn>_Z Data initialized to zero
// DATA<nn>_I Data initialized by copying from DATA<nn>_ID
// DATA<nn>_N Data defined using __no_init
// DATA<nn>_P Data defined using __persistent
// DATA<nn>_HEAP The heap used by 'malloc' and 'free'
//
// segment Usage
// ------- --------------------------
// CSTACK Runtime stack
// TLS16_I Thread-local storage for main thread
//


// -------------------------------------
// Program and data read-only segments
//

//
// The following segments are available for both
// the DATA16 and DATA20 segment groups.
//
// segment Usage
// ------- --------------------------
// DATA<nn>_C Constant data, including string literals
// DATA<nn>_ID Initializers for DATA<nn>_I
//
// segment Usage
// ------- --------------------------
// INFO Information memory
// INFOA Information memory, bank A
// INFOB Information memory, bank B
// INFOC Information memory, bank C
// INFOD Information memory, bank D
// CSTART Program startup code
// CODE Program code
// ISR_CODE Program code for interrupt service routines
// DIFUNCT Dynamic initialization vector used by C++
// CHECKSUM Checksum byte(s) generated by the -J option
// SIGNATURE Signature memory
// JTAGSIGNATURE JTAG Signature memory
// BSLSIGNATURE BSL Signature memory
// IPESIGNATURE IPE Signature memory
// INTVEC Interrupt vectors
// RESET The reset vector
// TLS16_ID Thread-local initializers for main thread
// MPU_B<N> Memory Protection Unit border
// IPE_B<N> Intellectual Property Encapsulation border
// IPECODE16 IPE code
// IPEDATA16_C IPE constant data
//
// Notes:
//
// * The segments CSTART, ISR_CODE, and DIFUNCT, as well as the segments in
// the DATA16 and TLS16 segment groups must be placed in in the range
// 0000-FFFD.
//
// * The INFOx and INFO segments overlap, this allows data either to be
// placed in a specific bank or anywhere in the info memory.
//
// * The INTVEC and RESET segments overlap. This allows an application to
// either use the reset vector provided by the runtime library, or
// provide a reset function by defining an interrupt function associated
// with the reset vector.
//
// * To use the Memory Protection Unit, the symbol ?mpu2_init should be
// included in the application. The symbol '__iar_430_MPU_base' should be
// defined to the location of the MPU peripheral registers, and the
// registers '__iar_430_MPUSAM_value' and '__iar_430_MPUCTL0_value' to
// the value the registers MPUSAM and MPUCTL0 should be initialized to,
// respectively.
//
// * To include Intellectual Property Encapsulation (IPE), the library
// label '__iar_430_ipe_signature' must be included in the application.
// (One way to do this is to use the -g XLINK command-line option.) The
// symbol '__iar_430_MPUIPC0_value' must be defined to the value the
// MPUIPC0 register should be initialized to.
//
// * To include custom segments in the Intellectual Property Encapsulation
// (IPE) area, place them between the segments IPE_B1 and IPE_B2.
//


// ---------------------------------------------------------
// Configuation
//

// -----------------------------------------------
// Stack and heap sizes
//

// Uncomment for command line use
//-D_STACK_SIZE=160
//-D_DATA16_HEAP_SIZE=160
//-D_DATA20_HEAP_SIZE=160
//-g?mpu2_init
//-g__iar_430_ipe_signature


// -----------------------------------------------
// Define cpu
//

-cmsp430


// -----------------------------------------------
// Support for placing functions in read/write memory
//

-QCODE_I=CODE_ID


// -----------------------------------------------
// Support for thread local storage
//

-QTLS16_I=TLS16_ID


// -----------------------------------------------
// Hardware multiplier location
//

-D__iar_HWMUL=4C0


// ---------------------------------------------------------
// Placement directives
//

// -----------------------------------------------
// Information memory
//

-Z(CONST)INFO=1800-19FF
-Z(CONST)INFOA=1980-19FF
-Z(CONST)INFOB=1900-197F
-Z(CONST)INFOC=1880-18FF
-Z(CONST)INFOD=1800-187F


// -----------------------------------------------
// RAM memory
//

-Z(DATA)BOOTLOADER_MESSAGE=1c00-1c05
-Z(DATA)TINYRAM=0006-001F
-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,TLS16_I=1c06-23FF
//-Z(DATA)TINYRAM=0006-001F
//-Z(DATA)DATA16_I,DATA16_Z,DATA16_N,TLS16_I=1C00-23FF
-Z(DATA)CODE_I
-Z(DATA)DATA20_I,DATA20_Z,DATA20_N
-Z(DATA)CSTACK+_STACK_SIZE#


// -----------------------------------------------
// FRAM memory
//

// -------------------------------------
// Low memory 0-0FFFF
//

// ---------------------------
// Read/write data in FRAM
//

-Z(CONST)DATA16_P,DATA20_P=8000-dfff
-Z(DATA)DATA16_HEAP+_DATA16_HEAP_SIZE
-Z(DATA)DATA20_HEAP+_DATA20_HEAP_SIZE

// ---------------------------
// Memory Protection Unit (MPU) border
//

-Z(CONST)MPU_B1

// ---------------------------
// Intellectual Property Encapsulation (IPE)
//

-Z(CONST)IPE_B1=8000-dfff
-Z(DATA)IPEDATA16_N
-Z(CODE)IPECODE16
-Z(CONST)IPEDATA16_C,IPE_B2

// ---------------------------
// Memory Protection Unit (MPU) border
//

-Z(CONST)MPU_B2

// ---------------------------
// Constant data
//

-Z(CONST)DATA16_C,DATA16,TLS16_ID,DIFUNCT_ID,CHECKSUM=8000-dfff

// ---------------------------
// Code
//

-Z(CODE)CSTART,ISR_CODE,CODE16=8000-dfff


// -------------------------------------
// All memory 0-FFFFF
//

// ---------------------------
// Code
//

-P(CODE)CODE=8000-dfff,10000-23FFF
-Z(CODE)CODE_PAD

// ---------------------------
// Constant data
//

-Z(CONST)DATA20_C,DATA20_ID,CODE_ID=8000-dfff,10040-23FFF


// -------------------------------------
// Signature memory and interrupt vectors
//

-Z(CONST)SIGNATURE=DF80-DF8F
-Z(CONST)JTAGSIGNATURE=DF80-DF83
-Z(CONST)BSLSIGNATURE=DF84-DF87
-Z(CONST)IPESIGNATURE=DF88-DF8F
-Z(CODE)INTVEC=DF90-DFFF
-Z(CODE)RESET=DFFE-DFFF

  • Hi Gary,

    I do not see any question raised in this post, are you experiencing any difficulties with your application or simply sharing a successful project port with the community?

    Regards,
    Ryan
  • Why does the  _asm( "mov.w #0x8a38, PC" ); instruction cause a reset?

  • What kind of reset is shown by the SYSRSTIV after the unexpected behavior? This will help determine if the MPU or some other peripheral is erroneously being violated. And why not point instead to the Application's RESET vector (should be located at 0xDFFE)?

    Regards,
    Ryan
  • I tried both with the same result.

    However, I am now working.

    I moved my vector table to the top of ram and reduced RAM from 1c00-23ff to 1c00-21ff and my customer bootloader is now working.
    Also I set SYSCLT's SYSRIVECT=1 after making the appropriate changes to the linker file for both the bootloader and the down loaded image.

    // -----------------------------------------------
    // RAM memory
    //

    -Z(DATA)BOOTLOADER_MESSAGE=1c00-1c05
    -Z(DATA)TINYRAM=0006-001F
    -Z(DATA)DATA16_I,DATA16_Z,DATA16_N,TLS16_I=1C06-21ff
    -Z(DATA)CODE_I
    -Z(DATA)DATA20_I,DATA20_Z,DATA20_N
    -Z(DATA)CSTACK+_STACK_SIZE#

**Attention** This is a public forum