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.

CCS/RM48L952: RM48 UART Bootloader question regarding Flash API

Part Number: RM48L952

Tool/software: Code Composer Studio

Hi,

I am trying to integrate the UART Bootloader project into my design. I am successfully receiving the first packet (via YMODEM), but then am failing to initialize the flash via the F021 Flash API. I can step through the code and it fails when it calls Fapi_setActiveFlashBank() and ends up at an undefined instruction interrupt (0x0004).

I think this is a bit of a red herring though, because reading up in other posts it sounds like my Flash API may not be copying into RAM and executing out of it. People suggest a ramfuncs definition in the .cmd file, but I'm at a loss how to do this, and I also feel like the UART Bootloader project probably should have already had this set up?

Can anyone provide some insight on how to link the F021 Flash API .lib into a project? I'm pretty certain that's where my problem is.

Here is my .cmd file:

//*****************************************************************************
//
// bl_link.cmd    : Linker command file
// Author         : QJ Wang. qjwang@ti.com
// Date           : 9-19-2012
//
// Copyright (c) 2006-2011 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
//
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
//
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
//
//*****************************************************************************


--retain="*(.intvecs)"


MEMORY
{
    VECTORS    (X)   : origin=0x00000000 length=0x00000200
    BOOT_LOAD  (RX)  : origin=0x00000200 length=0x00001000
    FLASH_API  (RX)  : origin=0x00001200 length=0x00001000
    FLASH0     (RX)  : origin=0x00002200 length=0x00018000
    FLASH1     (RX)  : origin=0x00020000 length=0x00060000
    FLASH2     (RX)  : origin=0x00080000 length=0x00080000
    FLASH3     (RX)  : origin=0x00100000 length=0x00080000
    FLASH4     (RX)  : origin=0x00180000 length=0x00080000
    SRAM       (RW)  : origin=0x08002000 length=0x0002D000
    STACK      (RW)  : origin=0x08000000 length=0x00001FF0
//    RSV        (RW)  : origin=0x08000000 length=0x00000010 fill=0
}
SECTIONS
{
   .intvecs : {} > VECTORS

   //boot_code :    {..\Release\sys_core.obj    (.text)}  > BOOT_LOAD
   //eabi_start :   {..\Release\sys_startup.obj (.text)}  > BOOT_LOAD
   boot_code :    {sys_core.obj    (.text)}  > BOOT_LOAD
   eabi_start :   {sys_startup.obj (.text)}  > BOOT_LOAD

   flashAPI :
   {
     //..\Release\bl_flash.obj (.text)
     //..\Release\Fapi_UserDefinedFunctions.obj (.text)
     bl_flash.obj (.text)
     Fapi_UserDefinedFunctions.obj (.text)
     //--library= F021_API_CortexR4_LE.lib <FlashStateMachine.obj
     --library= ..\lib\F021_API_CortexR4_LE.lib <FlashStateMachine.obj
                                          Program.obj
                                          Init.obj
                                          Utilities.obj
                                          Async.obj> (.text)
   } load = FLASH_API, run = SRAM, LOAD_START(api_load), RUN_START(api_run), SIZE(api_size)

   .text  > FLASH0
   .const > FLASH0
   .cinit > FLASH0
   .pinit > FLASH0
   .data  > SRAM
   .bss   > SRAM
}

Thanks for any help you can provide.

-Brian

  • Hello Brian,

    RM48 has 2 flash Banks. If your flash API related code is located bank0, and you want to erase sectors of bank0, you have to copy the flash API related code to SRAM and execute those code in SRAM. If you want to erase sectors of bank1, you don't have to execute the flash API related code in SRAM.

    Change to:
    flashAPI :
    {
    bl_flash.obj (.text)
    Fapi_UserDefinedFunctions.obj (.text)
    --library= ..\lib\F021_API_CortexR4_LE.lib (.text)
    } load = FLASH_API, run = SRAM, LOAD_START(api_load), RUN_START(api_run), SIZE(api_size)

    And call the copy function (_copyAPI2RAM, located in sys_core.asm) at the beginning of main() or before calling main() (in sys_startup.c)

    ;-------------------------------------------------------------------------------
    ; Copy the Flash API from flash to SRAM.

    .def _copyAPI2RAM_
    .asmfunc

    _copyAPI2RAM_

    .ref api_load
    flash_load .word api_load
    .ref api_run
    flash_run .word api_run
    .ref api_size
    flash_size .word api_size

    ldr r0, flash_load
    ldr r1, flash_run
    ldr r2, flash_size
    add r2, r1, r2
    copy_loop1:
    ldr r3, [r0], #4
    str r3, [r1], #4
    cmp r1, r2
    blt copy_loop1
    bx lr
    .endasmfunc
  • Thanks for the reply. I am still having issues.

    I already had copyAPI2RAM in my assembly (sys_core.asm), and it was already being called before main().

    My .cmd file looked very similar to your suggestion, except for the <.obj> definitions after the --library callout. I tried removing those and now I get a "program will not fit into available memory." error when I compile. Could you tell me if that is what you intended I remove from my .cmd file or if I'm missing something else you suggested? Is this memory capacity error real, or is it a side product of a syntax error?

    Here is my new .cmd file for reference:

    --retain="*(.intvecs)"
    
    
    MEMORY
    {
        VECTORS    (X)   : origin=0x00000000 length=0x00000200
        BOOT_LOAD  (RX)  : origin=0x00000200 length=0x00001000
        FLASH_API  (RX)  : origin=0x00001200 length=0x00001000
        FLASH0     (RX)  : origin=0x00002200 length=0x00018000
        FLASH1     (RX)  : origin=0x00020000 length=0x00060000
        FLASH2     (RX)  : origin=0x00080000 length=0x00080000
        FLASH3     (RX)  : origin=0x00100000 length=0x00080000
        FLASH4     (RX)  : origin=0x00180000 length=0x00080000
        SRAM       (RW)  : origin=0x08002000 length=0x0002D000
        STACK      (RW)  : origin=0x08000000 length=0x00001FF0
    //    RSV        (RW)  : origin=0x08000000 length=0x00000010 fill=0
    }
    SECTIONS
    {
       .intvecs : {} > VECTORS
    
       //boot_code :    {..\Release\sys_core.obj    (.text)}  > BOOT_LOAD
       //eabi_start :   {..\Release\sys_startup.obj (.text)}  > BOOT_LOAD
       boot_code :    {sys_core.obj    (.text)}  > BOOT_LOAD
       eabi_start :   {sys_startup.obj (.text)}  > BOOT_LOAD
    
       flashAPI :
       {
         //..\Release\bl_flash.obj (.text)
         //..\Release\Fapi_UserDefinedFunctions.obj (.text)
         bl_flash.obj (.text)
         Fapi_UserDefinedFunctions.obj (.text)
         //--library= F021_API_CortexR4_LE.lib <FlashStateMachine.obj
         --library= ..\lib\F021_API_CortexR4_LE.lib (.text)
       } load = FLASH_API, run = SRAM, LOAD_START(api_load), RUN_START(api_run), SIZE(api_size)
    
       .text  > FLASH0
       .const > FLASH0
       .cinit > FLASH0
       .pinit > FLASH0
       .data  > SRAM
       .bss   > SRAM

    Thanks again,
    -Brian

  • Hi QJ,

    Any ideas how my .cmd configuration might still be wrong?

    I have been trying different things and it seems my Flash API functions aren't all getting copied to RAM correctly, because when I step through the code it looks like it's having issues. I'm confused on the .cmd setup, so any help would be really appreciated.

    Thanks!

    -Brian

  • QJ,

    I've been stepping through the code and it has issues at the first Fapi call (Fapi_setActiveFlashBank). I can see problems in the disassembly:

    $Ven$AT$L$PI$$Fapi_setActiveFlashBank():
    08002dd4: E59FC000 ldr r12, [pc]
    08002dd8: E12FFF1C bx r12
    08002ddc: 00004625 andeq r4, r0, r5, lsr #12
    $Tramp$AA$L$PI$$UART_putString():
    08002de0: E51FF004 ldr pc, [pc, #-4]
    08002de4: 000033E8 andeq r3, r0, r8, ror #7
    08002de8: 00000000 andeq r0, r0, r0
    08002dec: 00000000 andeq r0, r0, r0
    08002df0: 00000000 andeq r0, r0, r0
    08002df4: 00000000 andeq r0, r0, r0

    This does not look good - the Fapi_setActiveFlashBank looks like it got overwritten by UART_putString(), unless I'm misreading my assembly (entirely possible).

    To reiterate, I'm using the sample TI UART Bootloader project for the RM48, so I feel like all the default settings should be working and I shouldn't have to be changing much. That's why I'm confused why there would be apparent corruption in the RAM, or problems in general here.

    Anyone have advice? 

    -Brian

  • I have fixed some issues through much trial and error.

    I found that I needed to explicitly call out the functions I needed in FAPI in my flashAPI section in the .cmd file. My cmd file now calls out:

    FlashStateMachine.InitializeFlashBanks.obj
    FlashStateMachine.SetActiveBank.obj
    FlashStateMachine.EnableMainSectors.obj
    FlashStateMachine.IssueFsmCommand.obj
    FlashStateMachine.ScaleFclk.obj
    FlashStateMachine.IssueAsyncCommandWithAddress.obj

    I had found that some of these functions were still in flash, which caused issues. I only found the names of these linked functions with a combo of build_information.txt (from the F021 API) and the linkInfo.xml. There must be a better way of finding the linked function names, but this is how I solved it.

    I am now having a new issue when erasing the flash. In bl_flash.c there is a loop that erases each sector (in bank 0):

        	do{
            	stat = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, eraseStartAddr);
            	while( FAPI_CHECK_FSM_READY_BUSY == Fapi_Status_FsmBusy );
            	while(FAPI_GET_FSM_STATUS != Fapi_Status_Success);
    
                remaining -= flash_sector[j++].length;
        		eraseStartAddr = flash_sector[j].start;
    
            }while((remaining > 0) && ( j < flash_bank[bk].numOfSectors));

    My issue here is very strange. The first few banks erase successfully, but when j is 8 the FAPI_GET_FSM_STATUS check does not pass. It looks like my FMdlStat register is 0x11 instead of 0.

    Anyone have any idea what would be significant about sector 8? This is address 0x000A0000. There must be something set up wrong between FAPI and my processor...

    Thanks!

    -Brian

  • I am making some significant progress here, and want to document this for future people needing help.

    I first had the notion that I should stop bothering with executing the FAPI out of RAM, because currently my application is ~1.1MB, which will fit in bank 1 (which is 1536k). So I changed everything over to that, but still found that sector 8 was failing to erase. Well that made no sense.

    I looked over what 0x11 means from FMdlStat, and found that SLOCK (bit 0) should only get set in clear circumstances detailed in the docs. I was still scratching my head over this, until I finally realized that FBSE was set up incorrectly. I spent an embarrassingly long time not realizing 0xFF wouldn't enable 255 sectors, but would instead only enable 8 (face palm on the bitmask - sometimes you're in too deep to see the easy stuff). So I fixed TI's sample code (!) in bl_flash.c :: Fapi_BlockErase:

        for (bk = ucStartBank; bk < ucEndBank+1; bk++){
    
        	Fapi_setActiveFlashBank((Fapi_FlashBankType)bk);
    
        	if (bk == 0){
        	    j = ucStartSector;
        	    remaining = Size_In_Bytes;
        	}else{
         	    j = 0;
        	}
    
            Fapi_enableMainBankSectors(0xFFFF);        /* used for API 2.01*/

    In the sample code this does Fapi_enableMainBankSectors(0xFF), which is 4 bits shy of how big bank 1 is, and 7 bits short for bank 0. I just set it to the max to enable everything. I am guessing TI did not test very large applications with this bootloader, or we're just expected to know to fix this. Frustrating, but whatever.

    This got me to actually be able to program the entire flash with my program.

    Next step, which I've been working on today, is figuring out how to generate a binary file. I was previously testing with a .out file, but when I finally looked at it in a HEX editor I saw all kinds of linker garbage in there that the bootloader has no interest in. I fiddled around with HEX output options in the Linker settings in Code Composer, but didn't really find a raw binary file. There must be one there, but I didn't find it.

    So instead I took the TI-txt file format that I'm already using for an MSP432 (much more forgiving bootloader by the way), and I wrote a conversion program to convert that ASCII to binary. That got me really close.

    I am now using my newly developed .cmd editing skills to offset the interrupt vectors and flash of my main application to 0x20000. For the future searchers, here is what that looks like:

    MEMORY
    {
        VECTORS (X)  : origin=0x00020000 length=0x00000020
        FLASH0  (RX) : origin=0x00020020 length=0x0015FFE0
        FLASH1  (RX) : origin=0x00180000 length=0x00180000
        STACKS  (RW) : origin=0x08000000 length=0x00001500
        RAM     (RW) : origin=0x08001500 length=0x0003eb00

    I think I am getting pretty close here and wanted to document my progress. I'll come back and mark this resolved when my program successfully boots.

    Thanks for reading...

    -Brian

  • My bootloader is now all working. I was having trouble after jumping to my main application, where the code wasn't fully booting. I couldn't really debug it so I was just stepping through assembly code. It looked to be getting stuck pretty early, and I finally diagnosed it down to waiting for a clock or PLL lock.

    I realized I probably shouldn't be setting up the core hardware registers twice. So I started all over and duplicated my entire main application project. I then put in the bootloader code. This fixed everything and my bootloader is now working correctly. I can also debug the main application by selectively only writing the portions of flash for it (instead of erasing everything).

    I hope this helps someone in the future, and if you have questions on getting the TI example project working let me know. Because it does not seem like a well-supported piece of code and it took a lot of fiddling and bug fixes to get it working!

    -Brian