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.

BSL for 5xxA series chips compiled via CCS

Other Parts Discussed in Thread: MSP430F5437A

I'm in the process of modifying the TI version of the Bootstrap Loader (BSL) for the MSP430F5437A, and I'm confused about some of the things in the TI version.  I'm using CCS 4.2.3.  The linker command file divides the 2k of BSL memory into the following contiguous segments:

MEMORY
{
...
    ZAREA                   : origin = 0x1000, length = 0x0010
    BSL430_VersionM   : origin = 0x1010, length = 0x0004
    ZAREA_CODE        : origin = 0x1014, length = 0x002E
    BSLSIG                  : origin = 0x17F0, length = 0x0010
    BSL_FLASH           : origin = 0x1042, length = 0x07AE
...
}

where I've left out the MEMORY specs that are irrelevant.  I more or less understand the ZAREA specification.  The TI document on creating a custom flash based BSL (slaa450a) defines it as a small region of memory that can be read or jumped to by programs from anywhere in memory even when the BSL is protected by the SYSBSLPE bit in the SYSBSLC register, which otherwise renders the BSL memory inaccessible.  I say "more or less" because the only documentation of this feature seems to be in slaa450a, and not for instance in the 5x Family Users Guide (slaa 208i).  So my first question is, have I missed something here?  Is the ZAREA behavior documented in more detail in the normal documentation, or is it only documented in the Flash BSL documentation?

The question seems particularly relevant because of the other odd memory segments that are defined here.  I can imagine the version info being forced into a specific address so you can tell what BSL you have from an examination of the image, without having to run the code.  But I'm unclear why the flash memory used for code has been divided into "ZAREA_CODE" and "BSL_FLASH".  These two regions are contiguous, and there is no documentation that I've been able to find or anything I can figure out about why these regions should behave differently.  So why are they treated differently?  Designating a section as "zarea code" seems to imply that it may have special access permissions, but I can't find anything about it.  Does anyone know what is going on here, or where I can find it documented?  Can these two regions be combined into one so that the linker can decide how to best use the memory?

Steve

 

  • Stephen Manion said:
    I more or less understand the ZAREA specification.

    Indeed. When teh BSL is protected, you may not fetch data or code from it if teh PC is not already in the same memory segment. This prohibits jumps or calls. The ZAREA is not protected, so you can read (and fetch instructions) from it, but it counts as 'the same segment' for the protection scheme.

    So entry points of the BSL code are placed here. On 0x1010, there is the BSL version code, which can be read from outside too. ZAREA_CODE can be used to place code into it, which will be visible. Maybe more entry points, or more constant data (like a copyright notice, which one usually wants to be visible)

    BSLSIG contains the signature of the BSL, so the startup microcode can detect it (the BSL area is not yet protected at this point) and decide whether to call the BSL entry check code or proceed with the reset vector because no BSL is there. And the rest, BSL_FLASH, contains the BSL code itself.

    However, I'm too surprised that the ZAREA ends at 0x1041 and not 0x103f or a more 'logical' point. Maybe this is a leftover from a 'tweak': the original code put into ZAREA was a bit larger than the actual ZAREA code, and since the linker cannot seamlessly merge the two segments, the ZAREA segment was virtually enlarged. Making the ZAREA smaller and BSL_FLASH bigger would possibly result in protected code being accidentally exposed. not using part of ZAREA would have resulted in less available space for the application. But that's just my imagination running wild about why this unexpeced values are there.

    The reason why there are ZAREA and ZAREA_CODE most likely is because the contiguous ZAREA segment was divided in two by the version segment being placed right into it. I guess this was necessary because then it is properly positioned for each MSP, while a simple address location in the source code would not auto-adjust relativ to the beginning of the ZAREA.

    Lots of (reasonable, I think) guessing here. It's such a low-level thing that it is indeed poorly documented.

  • I agree that what you've said seems reasonable, but some of it contradicts the TI documentation.  In particular, from slaa450a, section 1.1, "The Z-Area is a section of memory between addresses 0x1000 and 0x100F that can be jumped to and read from external application code".  So the BSL version code cannot be read from external memory because it starts at 0x1010, though the fixed location means that you could read it before loading a code update to a device from a hex file.  And the section "ZAREA_CODE" starts at 0x1014 and has nothing whatsoever to do with the ZAREA, despite the name.

    Lane, are you out there?

    Steve

  • The description you cite has an obvious flaw: if the whole, unprotected ZAREA were only from 0x1000 to 0x100f, then the BSL version code would be inaccessible too.

    So I think, the text refers to the first part of the ZAREA and does not cover that the total unprotected area is larger than just the first 16 bytes.

    However, this whole topic is described very incomplete.

    One thing you can test: write a program that jsu treads teh BSL area, and check, how much of its beginning is not 0x3fff. It will clear some questions.

  • As suggested, I wrote a program to step through the BSL area and read data to see what was actually protected, with the following results:

    If the SYSBSLPE bit is set in the SYSBSLC register, then:

    1) I can read data from 0x1000 to 0x100F.  It reads as 0xFFFF, which is odd, but which may just mean that I've erased the BSL at some point in my experimentation.

    2) As soon as I try to read data from 0x1010, the CPU appears to reset.  It does not read as 0x3FFF, and I do not have the VMAIE (Vacant memory access interrupt enable) or ACCVIE (Flash controller access violation interrupt enable) bits set in SFRIE1 (the Special Function Registers Interrupt Enable Register).  I'm not sure if I missed something int he documentation or if the reset on illegal read is more undocumented behavior.

     

    If the SYSBSLPE bit is not set, then all of the BSL reads as 0xFFFF with no errors or resets

     

    As an additional note, much of the TI sample code on the BSL is wrong in that it has some form of the following:

        //  Protect the BSL memory space
        SYSBSLC &= ~(SYSBSLPE | SYSBSLSIZE0 | SYSBSLSIZE1);

    In order to PROTECT the BSL memory space, the SYSBSLPE bit needs to be SET, not CLEARED.  This error shows up both in the sample code that downloads as part of SLAA450, and in some of the sample assembler code that is posted on the BSL wiki that TI maintains.

    The bottom line is that I still don't understand exactly how the BSL protection works, what the consequences of reading BSL protected memory are meant to be, or why the sample BSL program has an section called ZAREA_CODE.  If any TI employees are out there, I would appreciate an answer.

    Steve

     

     

  • Stephen Manion said:
    As soon as I try to read data from 0x1010, the CPU appears to reset.  It does not read as 0x3FFF, and I do not have the VMAIE (Vacant memory access interrupt enable)

    That's strange. reading from the protected area should not trigger a reset, it should set VMAIFG and trigger an NMI if VMAIE is set.

    However, teh 5x family users guide is, well, unlogical here:

    "Accesses to vacant memory space generate a system (non)maskable interrupt (SNMI) when enabled (VMAIE = 1). Reads from vacant memory results in the value 3FFFh. In the case of a fetch, this is taken as JMP $. Fetch accesses from vacant peripheral space result in a PUC."

    How can a fetch from this address result in a JMP $ when it triggers a PUC?

    Maybe here's a copy/paste error and behavior is different than described. I'll add this to my list of documentation quirks.

     

  • Stephen,

    ZAREA_CODE is used to store the assembly functions BSL_Protect and BSL_ACTION0 and the reason it is located in a separate memory space is to ensure that ZAREA_CODE is within a JUMP distance from ZAREA.

    And there is more information regarding Z-Area, as well as the 5xx BSL, in the following document.

    MSP430 Programming Via the Boostrap Loader User's Guide: http://www.ti.com/lit/ug/slau319a/slau319a.pdf

    Best regards,

    Austin Miller

  • Austin Miller said:
    ZAREA_CODE is used to store the assembly functions BSL_Protect and BSL_ACTION0 and the reason it is located in a separate memory space is to ensure that ZAREA_CODE is within a JUMP distance from ZAREA.

    Thank you for clarifying this.
    So ZAREA_CODE is there because it contains code that must be within +-512 words of ZAREA, so it can be reached by a JMP instruction located in ZAREA.

    This also means, that ZAREA_CODE can be as large as 1k if you want to put all directly reachable functions into it, or as small as 32 bytes if you just place 8 branch instructions there.

    Austin Miller said:
    And there is more information regarding Z-Area in the following document

    The problem with most documentation is, that often does not include the smart ideas, engineers and developers had when designing something. Many details are left out because they seem to be 'obvious' (but aren't if you're not that much 'in' it)

    That's why we let our documentations write by someone who was not part of the development process. He can be a PIA with his questions, but the result usually covers everything the users want/need to know.

  • Austin,

    Thank you for the response.   That answers my question about the ZAREA_CODE, but there are a couple of related ones I am still unclear on.

     

    First, I also commented that the TI example code is shown sometimes setting and sometimes clearing the SYSBSLPE bit in the SYSBSLC register.  I believe that for the production release of the code the bit should always be set, but that the example code is sometimes shown clearing it because it must be cleared in order to use the JTAG debugger to step through the code for testing.  I assume it was an oversight not to have changed the code to set the bit.  My experience has been that if I set the SYSBSLPE bit and try to step through the code I then lose the chip forever with a message that it cannot be programmed because the JTAG fuse is blown.  Is that interpretation correct?  Can I safely use the JTAG to control and debug code running out of the BSL flash if the SYSBSLPE bit is cleared?

     

    My second question relates to the environment present when the BSL_Protect() function is called.  I assume the stack pointer been set up at that point - how else could the return instruction at the end of BSL_Protect() work?  Can you confirm that this is true and that it is safe for me to write a C BSL_Protect() function that creates local variables on the stack and calls other C functions?

     

    Thanks,

    Steve

     

**Attention** This is a public forum