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.

Loading updater and main application code in different flash sectors

Other Parts Discussed in Thread: TMS320F2811

Hello,

I am currently trying an application upgrade solution on a TMS320F2811 device running from Flash. My design strategy is to load an update program first in a flash sector say Flash sector C. I flash this updater application via JTAG. So this code starts executing normally like any Boot from FLASH method ie from location 0x3F7FF6 it uses the library boot.asm file to initialize and call my updater main application

My updater application uses UART or SPI to recieve new application and uses Flash API to program my new application code into a different flash sector say FlashD.

Now when i reset my device after programming my new application in Sector D, i want the boot.asm to jump the new application main() function located in FlashD.

I want to know whether the boot.asm from the library will be able to load to the new applicaton instead of the updater application? because in boot.inc source code from TI rtssrc zip file, after initialization it calls _args_main. How does it know in this case which main() to call, whether the updater or the application.

Also when i want to reprogram this application, i need to jump again to updater application main() and erase the Flash sector D and reprogram with new data.

How is it possible with the boot.asm library code to identify which main() to call? This would help me get a clear idea of this design approach and start implementing a prototype.

Thanks,

Aviinaash S

  • I believe boot.asm programs a branch instruction to the start of the main() which will execute.

    It sounds like you essentially need two boot options. I suggest programming at the Boot to Flash location some code which reads the input of a GPIO pin. For example, if this pin is high boot to your application. If this pin is low, boot to the uploader application which will reprogram flash. Your boot instruction would be placed where the device boots to Flash by default and depending on what the status of the GPIO is, will branch to one of your two programmed applications.

    sal
  • Hi Sal,

    Thanks for the approach. I also want to know the .reset section in the cmd file is currently set to DSECT and has the address of _c_int00. I tried putting this .reset section in a location in flash and it contains the address of _c_int00 in a particular location in FLASH. During update, if i can erase this flash sector containing the .reset section and program the new .reset section pointing to the new _c_int00 address of the updated program. then on soft reset will it branch to the other application? Please let me know if this approach will work.

    Regards,
    Aviinaash S
  • DSP281x_CodeStartBranch.asmHi Sal,

    Based on the above approach i have told, i have modified the codestartbranch.asm to read a particular address 0x3d8000 which contains the address of the updater application or the main application and jump to that particular location.

    On the first when i flash using JTAG the updater application, the location 0x3d8000 contains the address of the entrypoint of the code (.ie _c_int00). I have changed my linker command file to use start of sector D to load the _c_int00 of the updater application. Then using UART i am sending the new application code, which i flash into sector F,  the new application starts with _c_int00 in the start of sector F.  After flashing sector F with the new code, i erase the locatino 0x3d8000 and put the new address of Flash Sector F to load the other application after reset.

    After reset, the codestartbranch.asm checks this address and jumps to sector F, but it does not execute the application, it returns 0x00000. I am unable to figure out why the new application instructions are not executed. After flash program is completed, i checked the flash contents it was having the new application inside and also the locations 0x3d8000 contains the new address  of start of sector F. The new application hex file which i update is built without codestartbranch.asm. So after reset, it uses the old Codestartbranch.asm , but jumps to the new application in Flash sector F. But i am unable to figure out why the new application is not executing. Is my approach right or is something missing in my approach.

    Please suggest

    I am attaching the Codestartbranch.asm file i am using.

  • it looks like you device is booting to RAM. Please check the boot pins to make sure your device is booting to Flash.

    If you are booting to Flash, Connect the JTAG and see and set a breakpoint at 0x3d8000.

    Let me know if this helps you debug.

    sal
  • Hi Sal,

    It is booting from Flash, as i am able to do the jump from codestartbranch.asm to the new address, and on further debug i am able to step into the _c_int00 implementation code from boot.asm file also of the updated application. But in that code execution only, there is a problem. In the Process C Initialization table part,  the .cinit start address is also correct as i verified it with the map file, but when it tries to copy it from the table to memory, it is getting invalid address and fails. I am adding the snippet of code from the boot.asm and i have marked the failure instruction in red. I debugged it till this instruction and got a invalid memory address error

    ****************************************************************************

    *  IF cinit IS NOT -1, PROCESS CINIT INITIALIZATION TABLE           *

    ****************************************************************************

    MOV AL,#cinit

    MOV AH,#hi16(cinit)

    ADDB ACC,#1

    B DO_PINIT,EQ ; if cinit < 0 (-1) no init tables

    ****************************************************************************

    *  PROCESS CINIT INITIALIZATION TABLE.  TABLE IS IN PROGRAM MEMORY IN THE  *

    *  FOLLOWING FORMAT:                                                       *

    *                                                                          *

    *       .word  <length of init data in words>                              *

    *       .word  or .long <address of variable to initialize>                *

    *       .word  <init data>                                                 *

    *       .word  ...                                                         *

    *                                                                          *

    *  If the variable's address is greater than 65535 (located in 'far'       *

    *  memory), then the address field of the cinit record will be 32-bits     *

    *  instead of the default 16-bits. The length value is negated to tag      *

    *  cinit records for those variables located in far memory.                *

    *                                                                          *

    *  The init table is terminated with a zero length                         *

    *                                                                          *

    ****************************************************************************

    MOVL XAR7,#cinit ; point XAR7 at start of table

    CLRC    TC        ; reset TC bit used as far flag

    B START, UNC ; jump to start processing

    LOOP:

    MOVB    AH,#0        ; zero out upper addr bits

    PREAD   AL,*XAR7 ; load address of variable to be inited

    ADDB    XAR7,#1 ; point to initialization data

          B GET_DATA,NTC        ; get data if variable is not far

    CLRC    TC        ; reset TC bit used as far flag

    PREAD   AH,*XAR7        ; otherwise, get hi bits of 22-bit addr

    ADDB    XAR7,#1

    GET_DATA:

    MOVL XAR6,ACC        ; address

    RPT AR1 ; repeat length + 1 times

    || PREAD   *XAR6++,*XAR7 ; copy data from table to memory

    MOVL ACC,XAR7 ; using ACC as temp, point XAR7 to

    ADD   ACC,AR1 ; next cinit record since PREAD

    ADDB ACC,#1 ; doesn't change value of XAR7.

    MOVL XAR7,ACC

    START:

    PREAD AL,*XAR7 ; load length

    B GET_ADDR,GEQ        ; a length < 0 denotes far data

           NEG     AL        ; negate value to get real length

    SETC    TC        ; flag that the address field is 32-bits

    GET_ADDR:

    MOVZ AR1,AL        ; copy length value to loop register

           ADDB    XAR7,#1 ; point to address field

    BANZ LOOP,AR1-- ; if (length-- != 0) continue

    By the looks of it, ACC is getting a wrong address, can you explain why this is happening, when i just run only 1 application this is not a problem. Also i have not modified any line of the boot.asm, i am directly using the one from the library.

    Thanks in advance,

    Aviinaash S

  • What do you mean "when you run only 1 application this is not a problem"?

    If it is trying to read data, then PREAD is not the intstruction you should be using. Try changing PREAD to MOV. Let me know if this helps.

    sal
  • Hi Sal,

    On further debug i found that there is 16 bytes of empty FFFF, after .text section after which .cinit section starts in the memory. My hex generator did not add this FFFF, so i wrote in continuous memory location, without the FFFF so during the initialization the cinit was pointing to the wrong address and causing trouble. After fixing it, I am able to run the new application after update successfully. Thanks for your help Sal.

    Aviinaash S
  • Good to hear.  Let us know if you have more questions.

    sal