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.

problem with copy Flash API of boot loader from flash to SRAM at runtime

Other Parts Discussed in Thread: HALCOGEN

Dear Experts

I am working on bootloader function with tms570ls1227. I have downloaded an example from  processors.wiki.ti.com/.../TMS570_Hercules_MCU_Bootloader  

here are some questions:

 firstly, in this example,the doc file is empty.so I cannot find any tutorial on this,so I cannot understand the author's design and idea

secondly,  on this website, it says "After HDK reset, the start-up code copies the Flash API of boot loader from flash to SRAM, and execute the boot loader in Flash. "   is this necessary ?  why I need to do this? (what happened if I ignore this)  and most importantly how to do this?

thirdly, according to SPNU501G, it says "API functions require execution in privilege mode" , must I enter the privilege mode? and how? any side effect? how to leave that mode?

and "The F021 Flash API library cannot be executed from the same bank as the active bank
selected for the API commands to operate on. On single bank devices, the F021 Flash API
must be executed from RAM." 

tms570ls 1227 and 0432 only have one flash bank: bank0 , so f021 api must be copied from flash to ram?

sorry for my poor english

Any reply will be helpful and I appreciate that

Regards

Leo

 

  • Leo,

    The bootloaders come from QJ - I am copying him on this forum post.

    The F021 APIs need to be copied to SRAM before executing - because when you start programming operations on the FLASH it becomes unreadable. Therefore code cannot execute from FLASH while flash is being programmed. [with the same bank anyway.. so for everything except FEE on your 1227 and 0432 this means copying to SRAM is always mandatory].

    Privilege is required to write to critical control registers involved in flash programming.

    Privilege is equivalent to saying any CPU mode other than USER. The bootloader really should take control of the CPU at reset and stay in privilege mode if it decides to program the flash although I am not sure it does this. In any case you can confirm the CPU mode by checking the CPSR register - the mode is encoded in the lower bits of this register.

    If you leave Privilege mode and go to USER mode, then it is necessary to have an exception which causes a return to privilege mode.
    Under software control this would normally be either a software generated IRQ (like the SSI) or a software generated SVC call (aka. SWI).
    This mechanism means that there is an ability to prevent USER code from modifying hardware - and any changes back to privilege will come through an exception vector where you can have a point of control to validate that the request from the user software should be honored.

    But I would assume that the bootloader probably executes in the SYSTEM mode which has privilege. In that mode you wouldn't need the interrupt or SVC as you already have privilege.
  • Dear Anthony
    Thank you for your reply, it helps. But I still dont know how to copy Flash API of boot loader from flash to SRAM.
    Can you or Mr QJ help me with that? (give me some directions or a brief tutorial of steps)
    Many thanks and have a nice weekend.
    Leo
  • There are many ways to accomplish this. It depends on if you want the code copied into reserved RAM every time the device starts executing or if you want to overlay this part of RAM only when the bootloader is needed. Read section 8.8 of the ARM Assembly Language Tools User's Guide and see if that helps you get started.

  • Dear Bob and Anthony

     

    Thank you for all the help.The good news is I successfully program the flash region which attributed to you.

    Please allow me to share my experience on this problem:

    the only two steps for accommplish this are 1.modify the cmd file and  2.copy the code from flash  to ram(the reason is shown above)

    for the first step, we have to understand the memory and section directives, here is my cmd file, I use #if and #endif to prevent halcogen from overwrite my code

    /*                                                                            */
    /*----------------------------------------------------------------------------*/
    /* USER CODE BEGIN (0) */
    
    /* USER CODE END */
    
    
    /*----------------------------------------------------------------------------*/
    /* Linker Settings                                                            */
    
    --retain="*(.intvecs)"
    
    /* USER CODE BEGIN (1) */
    #if 0
    /* USER CODE END */
    
    /*----------------------------------------------------------------------------*/
    /* Memory Map                                                                 */
    
    MEMORY
    {
        VECTORS (X)  : origin=0x00000000 length=0x00000020
        FLASH0  (RX) : origin=0x00000020 length=0x0005FFE0
        STACKS  (RW) : origin=0x08000000 length=0x00001500
        RAM     (RW) : origin=0x08001500 length=0x00006B00
    
    /* USER CODE BEGIN (2) */
    /* USER CODE END */
    }
    
    /* USER CODE BEGIN (3) */
    #else
    //自己定义
    MEMORY
    {
        VECTORS (X)  : origin=0x00000000 length=0x00000020
        BOOT_LOAD  (RX)  : origin=0x00000020 length=0x00001000
        FLASH_API  (RX)  : origin=0x00001020 length=0x000014E0
        FLASH0  (RX) : origin=0x00002500 length=0x0005DB00    //FLASH_API  FLASH0 加起来和之前大小一样
        STACKS  (RW) : origin=0x08000000 length=0x00001500
    
       // RAM_API (RW) : origin=0x08001500 length=0x000014E0 //53c0
        RAM     (RW) : origin=0x08001500 length=0x00006B00 // 保持大小不变
    }
    #endif
    #if 0
    /* USER CODE END */
    
    
    /*----------------------------------------------------------------------------*/
    /* Section Configuration                                                      */
    
    SECTIONS
    {
        .intvecs : {} > VECTORS
        .text    : {} > FLASH0
        .const   : {} > FLASH0
        .cinit   : {} > FLASH0
        .pinit   : {} > FLASH0
        .bss     : {} > RAM
        .data    : {} > RAM
    	.sysmem  : {} > RAM
        FEE_TEXT_SECTION : {} > FLASH0
        FEE_CONST_SECTION : {} > FLASH0
        FEE_DATA_SECTION : {} > RAM
    
    /* USER CODE BEGIN (4) */
    
    /* USER CODE END */
    }
    
    /* USER CODE BEGIN (5) */
    #else
    //自己定义
    SECTIONS
    {
        .intvecs : {} > VECTORS
    
       boot_code :    {..\Debug\source\sys_core.obj    (.text)}  > BOOT_LOAD
       eabi_start :   {..\Debug\source\sys_startup.obj (.text)}  > BOOT_LOAD
        flashAPI :
       {
         ..\Debug\customize\Fapi_UserDefinedFunctions.obj (.text)
         ..\Debug\customize\bl_flash.obj (.text)
    
    
    
         --library= F021_API_CortexR4_BE.lib < FlashStateMachine.IssueFsmCommand.obj
                                              FlashStateMachine.SetActiveBank.obj
                                              FlashStateMachine.InitializeFlashBanks.obj
                                              FlashStateMachine.EnableMainSectors.obj
                                              FlashStateMachine.IssueFsmCommand.obj
                                              FlashStateMachine.ScaleFclk.obj
                                              Init.obj
                                              Utilities.CalculateEcc.obj
                                              Utilities.WaitDelay.obj
                                              Utilities.CalculateFletcher.obj
                                              Read.MarginByByte.obj
                                              Read.Common.obj
                                              Read.FlushPipeline.obj
                                              Read.WdService.obj
                                              Async.WithAddress.obj
                                              Program.obj > (.text)
       } load = FLASH_API, run = RAM, LOAD_START(api_load), RUN_START(api_run), SIZE(api_size)
    
    
        .text    : {} > FLASH0
        .const   : {} > FLASH0
        .cinit   : {} > FLASH0
        .pinit   : {} > FLASH0
        .bss     : {} > RAM
        .data    : {} > RAM
        .sysmem  : {} > RAM
        FEE_TEXT_SECTION : {} > FLASH0
        FEE_CONST_SECTION : {} > FLASH0
        FEE_DATA_SECTION : {} > RAM
    }
    #endif
    /* USER CODE END */
    
    
    /*----------------------------------------------------------------------------*/
    /* Misc                                                                       */
    
    /* USER CODE BEGIN (6) */
    /* USER CODE END */
    /*----------------------------------------------------------------------------*/

    secondly copying the api form flash to ram 

    in the demo, this fucntion is developed in assembly language:

    ;-------------------------------------------------------------------------------
    ;
    ; 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
    

    in the sys_core.asm and the function is called in sys_startup just before main();  and dont forget to declare it in header

    but when I use this method, it doesnt work,I'd like some more discussion on this issue and I will verify the answer to close this thread

    but dont worry,you can copy code from flash to ram at the begining of your main function in C language

    void copyflash2ram(char *load,char *start, unsigned int size)
    {
    	do
    	  {
    	  	*start = *load;
    		start++;
    		load++;
    	  } while (--size);
    }

    #define FlashApi_LoadStart 0x00001020
    #define FlashApi_RunStart 0x08001500
    #define FlashApi_LoadSize 0x000014E0

    copyflash2ram(
    (char *) FlashApi_LoadStart,
    (char *) FlashApi_RunStart,
    (uint32) FlashApi_LoadSize );

    some other problems:

    1. dont entirely trust the demo downloaded, for example,if you fine  SLOCK (0) bit of FMSTAT is 1 and also CSTAT(4) bit is one after programing command or others.

    it maybe because of Fapi_enableMainBankSectors();  

     This function sets up the sectors in the non-EEPROM banks that are available for erase and programming
    operations. This function must be called with the bank intended for the erase or program operation as the
    active bank. Additionally, the function must be called once before performing program and sector erase
    operations and always before a bank erase operation. Each bit refers to a single sector where Sector 0 is
    bit 0 to Sector 15 is bit 15 in u16SectorEnables.This function will check the OTP to see if the requested
    sector exists on the device and will enable it only if exists.

    in demo provided by TI, the parameter to this is 0xFF or something else,but this can not be entirely trusted.

    because: the interrupt vectors are in sector 0, and your bootloader routine is just after interrupt vectors. 

    and these sections are really no need to be erased or reprogrammed. so if you want to program sector 15 ,  write (100000000000000 binary) into     Fapi_enableMainBankSectors();  only allow sector 15 to be erased or reprogrammed

    and if this does not work for you, you can use memory browser to see how the registers changing 

    2. the api fucntion return value Fapi_StatusType is not accurate, in the demo you can see the fucntion return value is not used to determine if this fucntion works, it check the registers, and this method is highly recommanded by me, because, even you failed to program the flash, the return value is Fapi_Status_Success,but the register is not in a stable status.

    Any way, thank you for your help and as I said  after  some more discussion on _copyAPI2RAM_ exception , I will verify the answer to close this thread.

    Best Regards

    Leo




     

  • The _copyAPI2RAM_(); works too today. Amazing
    any literature for me to understand TI assembly language?
    many thanks
    leo
  • It is actually ARM assembly language. ARM has a quick reference guide, and there are many books commercially available. The assembly directives used by the TI assembler can be found in the Assembly Language Tools Reference Guide.