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.

TMDSCNCD28M36: Bootloader for F28M36 (ARM part) - problem with jump function

Part Number: TMDSCNCD28M36
Other Parts Discussed in Thread: CODECOMPOSER

Hello,

I am working on the development of a bootloader for F28M36 CPU, in special, for the ARM based microcontroller. The bootloader will receive the firmware image from serial communication.

For the development, I am using the following setup:

  • F28M36x controlCard R1.1
  • controlCard Docking Station R4.1
  • Code Composer Studio 8

I am facing an issue with the jump application function.

The following code is implemented on my project:

static void jumpStackPointer(uint32_t address) {
    __asm(" mov sp, r0\n"   // sp is now *address
            " bx r0\n" );     // jump to *address
}

void jumpToApplication(void) {
    uint32_t App_Start_Address = 0x00211258 + 0x1;
    /*
     * Disable interrupts
     * Doesn't work with or without this line.
     * With this line means PRIMASK will be 1 after start app
     * Without means PRIMASK will be 0
     */
    IntMasterDisable();

    // redirect the vector table
    HWREG(NVIC_VTABLE) = Flashif_SectorL_start;


    jumpStackPointer(App_Start_Address);

}

To evaluate the code below, I implemented a simple BlinkLed application and changed the CMD file to save the firmware on the correct place in Flash (SectorL).

Below there is the CMD file for my BlinkLed firmware.


//###########################################################################
// FILE: F28M36x_generic_wshared_M3_FLASH.cmd
// TITLE: Linker Command File for F28M36H63C2 examples that run from FLASH
// Keep in mind that C0 and C1 are protected by the code
// security module.
// What this means is in most cases you will want to move to
// another memory map file which has more memory defined.
//###########################################################################
// $TI Release: F28M36x Support Library v206 $
// $Release Date: Thu Mar 5 10:16:50 CST 2015 $
// $Copyright: Copyright (C) 2012-2015 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
*/

--retain=g_pfnVectors

/* The following command line options are set as part of the CCS project. */
/* If you are building using the command line, or for some reason want to */
/* define them here, you can uncomment and modify these lines as needed. */
/* If you are using CCS for building, it is probably better to make any such */
/* modifications in your CCS project and leave this file alone. */
/* */
/* --heap_size=0 */
/* --stack_size=256 */
/* --library=rtsv7M3_T_le_eabi.lib */

/* System memory map */

MEMORY
{
RESETISR (RX) : origin = 0x00200030, length = 0x0008 /* Reset ISR is mapped to boot to Flash location */

/* Flash Block 0, Sector 0 */
FLASH_BOOT (RX) : origin = 0x00210000, length = 0x0008 /* Reset ISR is mapped to boot to Flash location */
INTVECS (RX) : origin = 0x00211000, length = 0x0258

FLASH_L (RX) : origin = 0x00211258, length = 0x6DA8
FLASH_K (RX) : origin = 0x00218000, length = 0x8000
FLASH_J (RX) : origin = 0x00220000, length = 0x20000
FLASH_I (RX) : origin = 0x00240000, length = 0x20000
FLASH_H (RX) : origin = 0x00260000, length = 0x20000
FLASH_G (RX) : origin = 0x00280000, length = 0x20000
FLASH_F (RX) : origin = 0x002A0000, length = 0x20000
FLASH_E (RX) : origin = 0x002C0000, length = 0x20000
FLASH_D (RX) : origin = 0x002E0000, length = 0x8000
FLASH_C (RX) : origin = 0x002E8000, length = 0x8000
FLASH_B (RX) : origin = 0x002F0000, length = 0x8000
FLASH_A (RX) : origin = 0x002F8000, length = 0x7FD0

CSM_RSVD_Z2 : origin = 0x002FFFD0, length = 0x000C
CSM_ECSL_Z2 : origin = 0x002FFFDC, length = 0x0024

/* RAM */
C0 (RWX) : origin = 0x20000000, length = 0x2000
C1 (RWX) : origin = 0x20002000, length = 0x2000
BOOT_RSVD (RX) : origin = 0x20004000, length = 0x0FF8
C2 (RWX) : origin = 0x200051B0, length = 0x0E50
C3 (RWX) : origin = 0x20006000, length = 0x2000
S0 (RWX) : origin = 0x20008000, length = 0x2000
S1 (RWX) : origin = 0x2000A000, length = 0x2000
S2 (RWX) : origin = 0x2000C000, length = 0x2000
S3 (RWX) : origin = 0x2000E000, length = 0x2000
//S4 (RWX) : origin = 0x20010000, length = 0x2000
//S5 (RWX) : origin = 0x20012000, length = 0x2000
S45 (RWX) : origin = 0x20010000, length = 0x4000
//S6 (RWX) : origin = 0x20014000, length = 0x2000
//S7 (RWX) : origin = 0x20016000, length = 0x2000
S67 (RWX) : origin = 0x20014000, length = 0x4000
C0408 (RWX) : origin = 0x20018000, length = 0xA000
//C4 (RWX) : origin = 0x20018000, length = 0x2000
//C5 (RWX) : origin = 0x2001A000, length = 0x2000
//C6 (RWX) : origin = 0x2001C000, length = 0x2000
//C7 (RWX) : origin = 0x2001E000, length = 0x2000
//C8 (RWX) : origin = 0x20020000, length = 0x2000
//C9 (RWX) : origin = 0x20022000, length = 0x2000
//C10 (RWX) : origin = 0x20024000, length = 0x2000
//C11 (RWX) : origin = 0x20026000, length = 0x2000
//C12 (RWX) : origin = 0x20028000, length = 0x2000
C0913 (RWX) : origin = 0x20022000, length = 0xA000
//C13 (RWX) : origin = 0x2002A000, length = 0x2000
//C14 (RWX) : origin = 0x2002C000, length = 0x2000
//C15 (RWX) : origin = 0x2002E000, length = 0x2000
C1415 (RWX) : origin = 0x2002C000, length = 0x4000

CTOMRAM (RX) : origin = 0x2007F000, length = 0x0800
MTOCRAM (RWX) : origin = 0x2007F800, length = 0x0800

OTPSECLOCK : origin = 0x00681000, length = 0x0004
OTP_Reserved1 : origin = 0x00681004, length = 0x0004
OTP_Reserved2 : origin = 0x00681008, length = 0x0004
OTP_Z2_FLASH_START_ADDR : origin = 0x0068100C, length = 0x0004
OTP_EMACID : origin = 0x00681010, length = 0x0008
OTP_Reserved3 : origin = 0x00681018, length = 0x0004
CUSTOMER_OTP_MAIN_OSC_CLK_FREQ : origin = 0x0068101C, length = 0x0004
OTP_Reserved4 : origin = 0x00681020, length = 0x0004
OTP_BOOT_MODE_GPIO_CONFIGURE : origin = 0x00681024, length = 0x0004
OTP_Reserved5 : origin = 0x00681028, length = 0x0004
OTP_ENTRY_POINT : origin = 0x0068102C, length = 0x0004
OTP_Reserved6 : origin = 0x00681030, length = 0x0010
}

/* Section allocation in memory */

SECTIONS
{
.intvecs: > INTVECS, ALIGN(8)
.resetisr: > FLASH_BOOT, ALIGN(8)
.text : > FLASH_L
.const : > FLASH_L
.cinit : > FLASH_L
.pinit : > FLASH_L

.vtable : > C0 | C1 | C2 | C3
.data : > C2 | C3
.bss : > C0408// | C5 | C6 | C7 | C8
.sysmem : > C0 | C1 | C2 | C3
.stack : > C0 | C1 | C2 | C3

.TI.crctab : > FLASH_L, ALIGN(8)

SERIALBUFFER : > C0913
MTOC_MSG_RAM : > MTOCRAM

GROUP : > MTOCRAM
{
PUTBUFFER
PUTWRITEIDX
GETREADIDX
}

GROUP : > CTOMRAM
{
GETBUFFER : TYPE = DSECT
GETWRITEIDX : TYPE = DSECT
PUTREADIDX : TYPE = DSECT
}
}

__STACK_TOP = __stack + 256;

From the CodeComposer this firmware is working fine.

To evaluate my function, I am not using my Flash store functions already in order to avoid other potential problems that can mask the real problem from the jump function.

I am using the following procedure to test my jump function:

  • I load the BlinkLed firmware to the Flash, using CodeComposer Debug
  • I changed my MainFirmware to erase just the flash sectors that will be used on the firmware (in this case, SectorN and SectorM)
  • I load my MainFirmware to the Flash, using CodeComposer Debug
  • From CodeComposer, I can see that there is code located at SectorL (BlinkLed Firmware application)
  • I started the Firmware, using both CodeComposer and reseting the board

In both cases, I cannot see the led blinking.

I don't know if the problem is my jump function, the CMD file, my procedure, or all of this together.

I would like to ask for some advice in order to solve this issue.

Best regards,

Flavio

  • Flavio

    Have you stepped through your jump function and it is working (at least reaching the desired address)?
    Your boot settings are set to boot to flash?

    When it doesn't work, what address is the PC going to?

    I'm clear the order of what is going on. Once you load both firmwares, you expect it to boot to flash which goes to what? Then how does it get to the other firmware?

    Best regards
    Chris
  • Hello Chris,

    Thank you for you fast response.

    I can see the jump going to the desired address. At least that. I, in fact, did not follow PC after it stops working.

    How to I know it I set the boot to flash? Isn't it done by the CMD file? Is my file correct?

    I didn't understand your last 2 questions. I load two firmware, in this order:

    * Led blinking firmware
    * Bootloader firmware (at the moment, running just the jump application)

    For now, I am loading both firmwares using CodeComposer. I expect that the bootloader firmware starts and jump to the start point of the Led blinking firmware. I believe that my CMD file prepares the binary to boot from Flash, but as I am not a linker script expert, I don't know if there is somethings wrong with my CMD file.

    Best regards,

    Flavio
  • Flavio

    Is the issue with booting up and getting to your application? Or is the issue with jumping from the bootloader firmware to the led blink firmware?
    Refer to the technical reference manual on details to make sure you are pulling the correct GPIOs high and low to get to flash boot.
    There is nothing obviously wrong for your linker file, the resetISR is in the correct place for flash boot.

    If issue jumping to the blinking LED, you can try the following method which we use to jump to a specific address:
    entry_addr |= 1; //Need to set bit[0] in BLX instruction otherwise will result in usage fault
    ((void (*)(void))entry_addr)();

    Best regards
    Chris
  • Hello Chris,

    Sorry for the BOOT options confusion. On my ControlCard all the switches are in 1, which I assume (looking at the board's schematics) it is for Flash Boot Mode.

    When I execute my application, I can see the jump from Code Composer.

    It stops on an memory position 0x2130DA, which means for IntDefaultHandler() function on my BlinkLed firmware.

    I changed the jump procedure for this one that you've sent to me. I tried that approach already, with the same result.

    Below there is my bootloader code:

    void jumpToApplication(void) {
        uint32_t App_Start_Address = 0x00210000 | 1;
        /*
         * Disable interrupts
         * Doesn't work with or without this line.
         * With this line means PRIMASK will be 1 after start app
         * Without means PRIMASK will be 0
         */
        IntMasterDisable();
    
        ((void (*)()) App_Start_Address) ();
    }
    
    int main(void) {
    	
        volatile unsigned long ulLoop;
    
        // Disable Protection
        HWREG(SYSCTL_MWRALLOW) =  0xA5A5A5A5;
    
        // Tells M3 Core the vector table is at the beginning of C0 now.
        HWREG(NVIC_VTABLE) = 0x20005000;
    
        // Sets up PLL, M3 running at 75MHz and C28 running at 150MHz
        SysCtlClockConfigSet(SYSCTL_USE_PLL | (SYSCTL_SPLLIMULT_M & 0xF) |
    	                         SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 |
    	                         SYSCTL_XCLKDIV_4);
    
        // Copy time critical code and Flash setup code to RAM
        // This includes the following functions:  InitFlash();
        // The  RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart
        // symbols are created by the linker. Refer to the device .cmd file.
        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    
        // Call Flash Initialization to setup flash waitstates
        // This function must reside in RAM
        FlashInit();
    
        // Configure the board peripherals
        pinout_setup();
    
        // assign S0 and S1 of the shared ram for use by the c28
        // Details of how c28 uses these memory sections is defined
        // in the c28 linker file.
        RAMMReqSharedMemAccess((S1_ACCESS | S2_ACCESS | S4_ACCESS |
    	                                    S5_ACCESS), C28_MASTER);
    
        init_system();
    
        // Enable processor interrupts.
        IntMasterEnable();
    
        // Disable clock supply for the watchdog modules
        SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG1);
        SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG0);
    
        // Gain flash pump semaphore
        // This function must reside in RAM
        FlashGainPump();
    
        /* Jump to application: test purpose */
        jumpToApplication();
    
    }

    And below we have my led blinking firmware:

    int main(void) {
    	
        volatile unsigned long ulLoop;
    
        // Disable Protection
        HWREG(SYSCTL_MWRALLOW) =  0xA5A5A5A5;
    
        // Tells M3 Core the vector table is at the beginning of C0 now.
        HWREG(NVIC_VTABLE) = 0x20005000;
    
        // Sets up PLL, M3 running at 75MHz and C28 running at 150MHz
        SysCtlClockConfigSet(SYSCTL_USE_PLL | (SYSCTL_SPLLIMULT_M & 0xF) |
    	                         SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 |
    	                         SYSCTL_XCLKDIV_4);
    
        // Configure the board peripherals
        pinout_setup();
    
        // assign S0 and S1 of the shared ram for use by the c28
        // Details of how c28 uses these memory sections is defined
        // in the c28 linker file.
        RAMMReqSharedMemAccess((S1_ACCESS | S2_ACCESS | S4_ACCESS |
    	                                    S5_ACCESS), C28_MASTER);
    
        // Enable processor interrupts.
        IntMasterEnable();
    
        // Disable clock supply for the watchdog modules
        SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG1);
        SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG0);
    
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, ~0);
    
        while(1) {
    
    	    //
    	    // Turn on the LED.
    	    //
    	    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);
    	    //
    	    // Delay for a bit.
    	    //
    	    for(ulLoop = 0; ulLoop < 2000000; ulLoop++) { }
    	    //
    	    // Turn off the LED.
    	    //
    	    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, ~0);
    	    //
    	    // Delay for a bit.
    	    //
    	    for(ulLoop = 0; ulLoop < 2000000; ulLoop++) { }
    	}
    
    }
    

    What could be causing such problem?

    Best regards,

    Flavio

  • Flavio

    Correct if my understanding is incorrect, but whether run from CCS or boot up, you don't see the LED blinking. When you step through, it does jump to the LED blink firmware, but it doesn't reach the code to blink the LED. From what you stated, sounds like an interrupt is happening and bringing you to IntDefaultHandler(). You should determine what is causing this interrupt. 

    Best regards

    Chris

  • Hello Chris,

    This led blinking firmware has init functions based on the main firmware that will be effectively loaded to the CPU.

    Those init functions are causing an (for now) unknown interrupt.

    Using a simpler led blinking firmware solves this issue and I could confirm that the jump_application() function above works.

    Thank you for all your support.

    Best regards,

    Flavio