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.

CC3220S: custom boot

Part Number: CC3220S
Other Parts Discussed in Thread: UNIFLASH, ENERGIA, CC3200

in a custom board with CC3220S I need to be able to start 2 different applications

in flash memory, the executables of these 2 applications must be separated (App1.bin and App2.bin)

to do this, I have developed a custom 2nd level bootloader which, after having established which application must be executed, loads it into RAM and run it

  • my booloader occupies addresses 0x20004000-0x2001285F
  • applications are built to reside starting at address 0x20014000 (so there is no overlap with my boot)
  • the .resetVecs element is placed in 0x20014000 (value forced in linker cmd file)
  • the resetISR is placed in 0x200302d5 (value read from the map file)

My boot starts successfully and copies (for example) App1 from flash to RAM starting from 0x20014000

To run the application I use the following assembler lines, forcing the register R0 = 0x20014000 (= address of the .resetVecs of the application)

  1. ldr sp,[r0] --> reset the stack pointer to the initial value
  2. add r0,r0,#4 --> increases R0 by 4 (R0 = 0x20014004)
  3. ldr r1,[r0] --> in 0x20014004 there is the address of the resetISR of the application, which is copied in R1
  4. bx r1 --> jump to the address contained in R1 (then the address of the application's resetISR is stored in the Program Counter)

Using the built-in debugger in Code Composer Studio 12, everything looks fine but the application doesn't run...

I integrate everything into the flash memory, using UniFlash 8

  • my bootloader is the MCU Image
  • the application is inserted as User File in /sys/app1.bin (the same path used by mu boot to load it)

After program and restart:

  • the boot starts
  • the application is loaded in RAM (with a CRC32 control to make sure it is loaded correctly)
  • the previous assembler lines are executed successfully

... but the application deosn't start.

For the application I tried to save both the debug version and the MCU+Image version in flash, but nothing changes

What am I doing wrong?

Thank you, Andrea

  • Hi Andrea,

    What you described should work. I use similar way with bootloader for CC3220SF (2nd stage bootlaoder is executing from XIP flash) which I written long time ago, and it works. Personally I suspect some issue with linker file, but hard to say without debugging real code... Maybe at my bootlaoder source code you find some clue.

    Jan

  • Hi Jan,

    thanks a lot for your reply.

    My bootloader source code is very similar to yours (below only the procedure that load and execute the application)

    #define SRAM_BASEADDR           0x20000000
    #define SRAM_APP_OFFSET            0x14000
    
    void RunFirmwareImage(unsigned long);
    __asm("    .sect \".text:RunFirmwareImage\"\n"
          "    .clink\n"
          "    .thumbfunc RunFirmwareImage\n"
          "    .thumb\n"
          "RunFirmwareImage:\n"
          "    ldr    sp,[r0]\n"
          "    add    r0,r0,#4\n"
          "    ldr    r1,[r0]\n"
          "    bx     r1");
    
    void LoadAndExecute(AppRec_t AppRec)
    {
    	unsigned long Token;
    	long FileHandle;
    	SlFsFileInfo_t FsFileInfo;
    
        // Get the file size using File Info structure
        if (sl_FsGetInfo(FWname[AppRec], NULL, &FsFileInfo) >= 0)
        {
            // File exist - open it
            FileHandle = sl_FsOpen(FWname[AppRec], SL_FS_READ, &Token);
            if (FileHandle > 0)
            {
                // File opened - read it into RAM
                if (sl_FsRead(FileHandle, 0, (unsigned char *)(SRAM_BASEADDR + SRAM_APP_OFFSET), FsFileInfo.Len) >= 0)
                {
                    // File copied into RAM - close it
                    if (sl_FsClose(FileHandle, 0, 0, 0) >= 0)
                    {
                        // Eval and check CRC32
                        if (CRC32check(AppRec, (unsigned char *)(SRAM_BASEADDR + SRAM_APP_OFFSET), FsFileInfo.Len) == 0)
                        {
                            // CRC32 is correct - stop the network services
                            sl_Stop(200);
                            // Execute the application
                            RunFirmwareImage(SRAM_BASEADDR + SRAM_APP_OFFSET);
                        }
                    }
                }
            }
        }
    }

    The only difference is the CRC32check() function, used for validate the CRC32 of the file loaded in RAM

    I have 2 questions:

    1. since my device is CC3220S (secure), the application (energia.bin in your example, app1.bin in my case) must be signed or I can use the "normal" bin file builded in CCS?
    2. opening the map file af my application I note this:
      1. ENTRY POINT SYMBOL: "resetISR"  address: 2000cc25
      2. 2000cc24    0000001a     nortos_cc32xx.a : startup_cc32xx_ccs.oem4 (.text:resetISR)

    in the line (a.), the address of resetISR it is an odd number and this address is loaded into program counter for run the application; this is correct?

    Best regards

    Andrea

  • Hi Andrea,

    Answers to your questions:

    1. You application cannot have header with signature at beginning of binary code. Only your bootloader should be signed against to certificate chain, because this is verified by ROM bootlaoder. You should verify if you application code does not contains this header.

    2. I am sorry, but I don't understand your question. I don't use map files from TI compiler regularly. But I think similar job can do "memory allocation tool" at CCS.

    I can provide example for linker files for application and bootlaoder for CC3200 device. This code I used at one of previous project. Because CC3220S and CC3200 have same way for code execution (entry point from bootlaoder 0x20004000, 256kB RAM with execution from RAM), examples should work at CC3220S as well.

    bootloader:

    --retain=g_pfnVectors
    
    #define RAM_BASE 0x20004000
    
    MEMORY
    {
        SRAM_CODE (RWX) : origin = 0x20004000, length = 0x8000
        SRAM_DATA (RWX) : origin = 0x20000000, length = 0x4000
    }
    
    SECTIONS
    {
        .intvecs:   > RAM_BASE
        .init_array : > SRAM_CODE
        .vtable :   > SRAM_CODE
        .text   :   > SRAM_CODE
        .const  :   > SRAM_CODE
        .cinit  :   > SRAM_CODE
        .pinit  :   > SRAM_CODE
        .data   :   > SRAM_DATA
        .bss    :   > SRAM_DATA
        .sysmem :   > SRAM_DATA
        .stack  :   > SRAM_DATA(HIGH)
    }

    application:

    --retain=g_pfnVectors
    
    #define RAM_BASE 0x20020000
    
    MEMORY
    {
        SRAM_DATA (RWX) : origin = 0x20000000, length = 0x20000  /* 128 KB */
        SRAM_CODE (RWX) : origin = 0x20020000, length = 0x20000  /* 128 KB */
    }
    
    SECTIONS
    {
        .intvecs:   > RAM_BASE
        .init_array : > SRAM_CODE
        .vtable :   > SRAM_CODE
        .text   :   > SRAM_CODE
        .const  :   > SRAM_CODE
        .cinit  :   > SRAM_CODE
        .pinit  :   > SRAM_CODE
        .data   :   > SRAM_DATA
        .bss    :   > SRAM_DATA
        .sysmem :   > SRAM_DATA
        .stack  :   > SRAM_DATA(HIGH)
    }
    

    Jan

  • Hi Jan,

    using the step-by-step debug in Deassembly window in CCS, I discovered that my booloader run correcly

    Stack Pointer and Program counter are setted successfully and the core executes "something" (I see only the assembler code)

    But, if I let the code run freely, it jump into the freertos resetISR()

    So, I tried this experiment:

    • I rebuilt my App1 so that the .resetVecst is mapped in 0x20004000 (entry point address)
    • I removed by bootloader from flash memory and I overwrote it with the App1 (via Uniflash)

    In this way, the SLB should launch App1 directly --> but not, App1 doesnt' start (!!)

    The strange thing is that if I load App1 through the debugger in CCS, everything works

    But I think this new problem needs a new ticket...

    Best regards

    Andrea