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 v6.1: using application Flash address offset doesnt work

Other Parts Discussed in Thread: EK-TM4C1294XL

Hello,

I have CCS v6.1.0.00104 running on windows 7.

I have an app compiled and loaded from CCS via JTAG to a Target TM4C1294 and everything is fine.

Following the boot_serial and boot_demo1, boot_demo2 examples, I want my application to load and run from the Flash offset 0x4000.

I modified my *_css.cmd file param

APP_BASE from 0x00000000 to 0x00004000.

Clean and rebuild. No build warnings. Then CCS downloads to Flash address 0x4000 and I can step thru some of my app program. But eventually there must be a bad memory access and the app end up in an infinte loop at pc = 0x117e

The app uses static memory and occasionally ROM routines and when I look the memory locations in the CCS debug mode the addresses seem reasonable. (ie  static addresses > 0x4000)

Eventually I will have a boot image at 0x0 to load this app, but if my app is accessing memory below 0x4000 then somehow the linker isn't doing the correct thing? Is there something else beyond APP_BASE that should need to be changed? Am I missing an additional linker setting somewhere?

Is there an inherent problem with using CCS Debug mode on an app not running from Flash 0x0?

Thanks,

-Phil B

  • Hello Phil,

    I am able to debug (with break points) the "boot_demo2" example under EK-TM4C1294XL board's folder with CCS debugger. I am using Tivaware version 2.1.2.111. With CCS debugger, you should be able to run applications that are not executing from Flash 0x0, as long as the application does not restart.

    Apart from the value of APP_BASE, the other modification is to the Flash length. Please refer "boot_demo1" and "boot_demo2" examples for more details.

    Could the application by itself have a bad memory access and the error have nothing to do with the relocation to a different flash location? Does this application run as expected when the APP_BASE is set to 0?

    Thanks,
    Sai
  • Hello Sai,

    Yes the app works perfectly fine when APP_BASE is set to 0. Of course it is possible that there lies a bad memory access that is somehow obscured when the APP_BASE is set to 0.

    Sorry but I do not see anything regarding flash length in either boot_demo1.c or boot_demo2.c. They work on my launchpad as expected. This app is not running on the launchpad but on custom hardware.

    Its a fairly large app so will require some work to isolate it down.

    I believe the problem seems to be related to the use of TI Tivaware provided low level functions. I have modified some of the ROM_... routines to include into the app itself from the TI Tivaware. When I modify the APP_BASE I see the memory locations for the Tivaware routines to move as expected. Thru the disassembler I can even see the same code move as expected. But when running or stepping over (some of) the TI Tivaware functions, the processor never returns.

    Currently the TI Tivaware functions are includes and my project doesnt have the source. I plan to try copying the source over for some Tivaware functions to see how that affects behavior. I am using Tivaware 2.1.0.12573.

    I'm still wondering about linker settings but don't have anything concrete to really question.

    Thanks,

    -Phil

  • Hello Phil,

    I meant to refer the linker script (.cmd file) in "boot_demo1" and "boot_demo2" examples. As the APP_BASE is a non-zero value, the Flash length should reduce by that number.

    In the "boot_demo1_ccs.cmd" file the flash length is changed from "0x100000" to "0x000fc000". The following lines are taken from the "boot_demo1_ccs.cmd" file.

    MEMORY
    {
        /* Application stored in and executes from internal flash */
        FLASH (RX) : origin = APP_BASE, length = 0x000fc000
        /* Application uses internal RAM for data */
        SRAM (RWX) : origin = 0x20000000, length = 0x00040000
    }

    Sai

  • Sai,
    I have modified the cmd file as indicated and behavior is slightly different but net result is still branching to a bad address. I am working on condensing the project to get it to happen with little code.
    Thanks,
    -Phil
  • Sai,

    I have reduced my app to this following code. It works fine at APP_BASE 0x0. When the  APP_BASE is 0x4000, no system level calls can occur after the TimerEnable() method. The current error for 0x4000 states:

    CORTEX_M4_0: GEL Output:
    Memory Map Initialization Complete
    CORTEX_M4_0: Can't Run Target CPU: (Error -1268 @ 0x1090001) Device is locked up in Hard Fault or in NMI. Reset the device, and retry the operation. If error persists, confirm configuration, power-cycle the board, and/or try more reliable JTAG settings (e.g. lower TCLK). (Emulation package 5.1.641.0)

    My code in main:

    int
    main(void)
    {
        //
        // Set up FPU before SysClk
        //
        FPUEnable();
        ROM_FPULazyStackingEnable();

        //
        // Set the clocking to run directly from the crystal at 120MHz.
        //
        uint32_t sys_xtal = SYSCTL_XTAL_12MHZ; // IPB crystal

        g_ui32SysClock = MAP_SysCtlClockFreqSet((sys_xtal |
                                                 SYSCTL_OSC_MAIN |
                                                 SYSCTL_USE_PLL |
                                                 SYSCTL_CFG_VCO_480), 120000000);

        //
        // Initialize components
        //
     //   InitGpio();

        SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);

        //
        // Testing that interrupt enables can be reset before setting up Timer0.
        //
        IntMasterEnable();
        IntMasterDisable();
        IntMasterEnable();

        //
        // Enable the devices used (post Enabling Interrupts)
        //
        //
        TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
        TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClock / timer0Divisor);  // periodic TIMER0
        IntEnable(INT_TIMER0A);
        TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
        TimerEnable(TIMER0_BASE, TIMER_A);  // this is never disabled!

        // basically any system call after TimerEnable causes a problem

           SysCtlDelay(10000);  // this causes a problem

           //  Test Interrupt enabling/disabling
        IntMasterDisable();
        IntMasterEnable();

        //
        // Loop forever looking for events.
        //
        while(1)
        {
        }
    }

    My isr:

    void
    Timer0IntHandler(void)
    {

        //
        // Clear the timer interrupt.
        //
        TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

        timer0MainCount++;
        if (timer0MainCount == timer0Main)
        {
            timer0MainCount = 0;

            watchdogState = (watchdogState == true) ? false : true;
    //        SetPin(HRTBEAT1_LED, watchdogState, MASK_ALL_ACTIVE);

        }

    }

    Any help appreciated.

    Thanks,

    -Phil B

  • also if needed, relevant parts of my cmd and startup_css.c file:

    from *_ccs.cmd:

    #define APP_BASE 0x00004000
    #define RAM_BASE 0x20000000

    /* System memory map */

    MEMORY
    {
    /* Application stored in and executes from internal flash */
    /* FLASH (RX) : origin = APP_BASE, length = 0x00100000 */
    FLASH (RX) : origin = APP_BASE, length = 0x000fc000
    /* Application uses internal RAM for data */
    SRAM (RWX) : origin = 0x20000000, length = 0x00040000
    }



    from startup_css.c

    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
    (void (*)(void))((uint32_t)&__STACK_TOP),
    // The initial stack pointer
    ResetISR, // The reset handler
    NmiSR, // The NMI handler
    FaultISR, // The hard fault handler
    IntDefaultHandler, // The MPU fault handler
    IntDefaultHandler, // The bus fault handler
    IntDefaultHandler, // The usage fault handler
    0, // Reserved
    0, // Reserved
    0, // Reserved
    0, // Reserved
    IntDefaultHandler, // SVCall handler
    IntDefaultHandler, // Debug monitor handler
    0, // Reserved
    IntDefaultHandler, // The PendSV handler
    IntDefaultHandler, // The SysTick handler
    IntDefaultHandler, // GPIO Port A
    IntDefaultHandler, // GPIO Port B
    IntDefaultHandler, // GPIO Port C
    IntDefaultHandler, // GPIO Port D
    IntDefaultHandler, // GPIO Port E
    IntDefaultHandler, // UART0 Rx and Tx
    IntDefaultHandler, // UART1 Rx and Tx
    IntDefaultHandler, // SSI0 Rx and Tx
    IntDefaultHandler, // I2C0 Master and Slave
    IntDefaultHandler, // PWM Fault
    IntDefaultHandler, // PWM Generator 0
    IntDefaultHandler, // PWM Generator 1
    IntDefaultHandler, // PWM Generator 2
    IntDefaultHandler, // Quadrature Encoder 0
    IntDefaultHandler, // ADC Sequence 0
    IntDefaultHandler, // ADC Sequence 1
    IntDefaultHandler, // ADC Sequence 2
    IntDefaultHandler, // ADC Sequence 3
    IntDefaultHandler, // Watchdog timer
    Timer0IntHandler, // Timer 0 subtimer A
    IntDefaultHandler, // Timer 0 subtimer B
    IntDefaultHandler, // Timer 1 subtimer A
    IntDefaultHandler, // Timer 1 subtimer B
    IntDefaultHandler, // Timer 2 subtimer A
    IntDefaultHandler, // Timer 2 subtimer B
    IntDefaultHandler, // Analog Comparator 0
    IntDefaultHandler, // Analog Comparator 1
    IntDefaultHandler, // Analog Comparator 2
    IntDefaultHandler, // System Control (PLL, OSC, BO)
    IntDefaultHandler, // FLASH Control
    IntDefaultHandler, // GPIO Port F
    IntDefaultHandler, // GPIO Port G
    IntDefaultHandler, // GPIO Port H
    IntDefaultHandler, // UART2 Rx and Tx
    IntDefaultHandler, // SSI1 Rx and Tx
    IntDefaultHandler, // Timer 3 subtimer A
    IntDefaultHandler, // Timer 3 subtimer B
    IntDefaultHandler, // I2C1 Master and Slave
    IntDefaultHandler, // CAN0
    IntDefaultHandler, // CAN1
    IntDefaultHandler, // Ethernet
    IntDefaultHandler, // Hibernate
    IntDefaultHandler, // USB0
    IntDefaultHandler, // PWM Generator 3
    IntDefaultHandler, // uDMA Software Transfer
    IntDefaultHandler, // uDMA Error
    IntDefaultHandler, // ADC1 Sequence 0
    IntDefaultHandler, // ADC1 Sequence 1
    IntDefaultHandler, // ADC1 Sequence 2
    IntDefaultHandler, // ADC1 Sequence 3
    IntDefaultHandler, // External Bus Interface 0
    IntDefaultHandler, // GPIO Port J
    IntDefaultHandler, // GPIO Port K
    IntDefaultHandler, // GPIO Port L
    IntDefaultHandler, // SSI2 Rx and Tx
    IntDefaultHandler, // SSI3 Rx and Tx
    IntDefaultHandler, // UART3 Rx and Tx
    IntDefaultHandler, // UART4 Rx and Tx
    IntDefaultHandler, // UART5 Rx and Tx
    IntDefaultHandler, // UART6 Rx and Tx
    IntDefaultHandler, // UART7 Rx and Tx
    IntDefaultHandler, // I2C2 Master and Slave
    IntDefaultHandler, // I2C3 Master and Slave
    IntDefaultHandler, // Timer 4 subtimer A
    IntDefaultHandler, // Timer 4 subtimer B
    IntDefaultHandler, // Timer 5 subtimer A
    IntDefaultHandler, // Timer 5 subtimer B
    IntDefaultHandler, // FPU
    0, // Reserved
    0, // Reserved
    IntDefaultHandler, // I2C4 Master and Slave
    IntDefaultHandler, // I2C5 Master and Slave
    IntDefaultHandler, // GPIO Port M
    IntDefaultHandler, // GPIO Port N
    0, // Reserved
    IntDefaultHandler, // Tamper
    IntDefaultHandler, // GPIO Port P (Summary or P0)
    IntDefaultHandler, // GPIO Port P1
    IntDefaultHandler, // GPIO Port P2
    IntDefaultHandler, // GPIO Port P3
    IntDefaultHandler, // GPIO Port P4
    IntDefaultHandler, // GPIO Port P5
    IntDefaultHandler, // GPIO Port P6
    IntDefaultHandler, // GPIO Port P7
    IntDefaultHandler, // GPIO Port Q (Summary or Q0)
    IntDefaultHandler, // GPIO Port Q1
    IntDefaultHandler, // GPIO Port Q2
    IntDefaultHandler, // GPIO Port Q3
    IntDefaultHandler, // GPIO Port Q4
    IntDefaultHandler, // GPIO Port Q5
    IntDefaultHandler, // GPIO Port Q6
    IntDefaultHandler, // GPIO Port Q7
    IntDefaultHandler, // GPIO Port R
    IntDefaultHandler, // GPIO Port S
    IntDefaultHandler, // SHA/MD5 0
    IntDefaultHandler, // AES 0
    IntDefaultHandler, // DES3DES 0
    IntDefaultHandler, // LCD Controller 0
    IntDefaultHandler, // Timer 6 subtimer A
    IntDefaultHandler, // Timer 6 subtimer B
    IntDefaultHandler, // Timer 7 subtimer A
    IntDefaultHandler, // Timer 7 subtimer B
    IntDefaultHandler, // I2C6 Master and Slave
    IntDefaultHandler, // I2C7 Master and Slave
    IntDefaultHandler, // HIM Scan Matrix Keyboard 0
    IntDefaultHandler, // One Wire 0
    IntDefaultHandler, // HIM PS/2 0
    IntDefaultHandler, // HIM LED Sequencer 0
    IntDefaultHandler, // HIM Consumer IR 0
    IntDefaultHandler, // I2C8 Master and Slave
    IntDefaultHandler, // I2C9 Master and Slave
    IntDefaultHandler, // GPIO Port T
    IntDefaultHandler, // Fan 1
    0, // Reserved
    (void (*)(void))0xFF01FF02, // HEADER PREFIX 0
    (void (*)(void))0xFF03FF04, // HEADER PREFIX 1
    (void (*)(void))0xFFFFFFFF, // HEADER IMAGE LEN
    (void (*)(void))0xFFFFFFFF, // HEADER CRC32
    (void (*)(void))0xFFFFFFFF, // HEADER Reserved
    (void (*)(void))0xFFFFFFFF, // HEADER Reserved
    (void (*)(void))0xFFFFFFFF, // HEADER Reserved
    (void (*)(void))0xFFFFFFFF // HEADER Reserved

    };
  • Hello Phil,

    It is really hard to understand the code without "Syntaxhighlighter". For future reference, please use "Syntaxhighlighter" while posting code. "Syntaxhiglighter" can be invoked by using the icon

    Can the application cause the device to restart? Looks like the variable "watchdogState" tracks the watchdog's state. Is the watchdog causing a reset?

    Can you use the TivaWare example "boot_demo1" as a starting point to debug this issue? As I mentioned before, I am able to debug it using CCS toolchain.

    Thanks,

    Sai

  • Sai,
    Sorry about the code. I will try using the Syntaxhighlighter.

    So I took the minimal amount of code from my main and pasted it into the boot_demo1.c code. I dont have the same launchpad peripherals so cant do the button but since the code fails before all that it doesnt matter.
    This code has the same effect as my code does. Any system call after TimerEnable() causes the error mentioned previously.

    I changed the freq from 25Mhz to 12Mhz to match the actual hw and changed the target ccxml file appropriate for my target.

    I removed watchdog state as that was just to light an LED to indicate that the app was running.


    //***************************************************************************** // // The interrupt handler for the first timer interrupt. (Periodic) // //***************************************************************************** void Timer0IntHandler(void) { // // Clear the timer interrupt. // TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); } //***************************************************************************** // // A simple application demonstrating use of the boot loader, // //***************************************************************************** int main(void) { // // Enable lazy stacking for interrupt handlers. This allows floating-point // instructions to be used within interrupt handlers, but at the expense of // extra stack usage. // ROM_FPULazyStackingEnable(); // // Set the system clock to run at 120MHz from the PLL // g_ui32SysClockFreq = SysCtlClockFreqSet((SYSCTL_XTAL_12MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); ////// add my timer isr stuff here ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); // // Testing that enables can be reset before setting up Timer0. // IntMasterEnable(); //IntMasterDisable(); //IntMasterEnable(); // // Enable the devices used (post Enabling Interrupts) // // TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); TimerLoadSet(TIMER0_BASE, TIMER_A, g_ui32SysClockFreq / 10); // periodic TIMER0 IntEnable(INT_TIMER0A); TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); TimerEnable(TIMER0_BASE, TIMER_A); // this is never disabled! // basically any system call after TimerEnable causes a problem // Test Interrupt enabling/disabling IntMasterDisable(); IntMasterEnable(); ////// back to boot_demo1.c // // Initialize the peripherals that each of the boot loader flavours // supports. Since this example is intended for use with any of the // boot loaders and we don't know which is actually in use, we cover all // bases and initialize for serial, Ethernet and USB use here. // SetupForUART(); SetupForUSB(); // // Enable Port J Pin 0 for exit to UART Boot loader when Pressed Low. // On the EK-TM4C1294 the weak pull up is enabled to detect button // press. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOJ))); GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE, GPIO_PIN_0); HWREG(GPIO_PORTJ_BASE + GPIO_O_PUR) = GPIO_PIN_0;

    Sai,

  • Sai,
    ok, that code paste didnt work quite as expected....
    But basically I inserted my timer isr code into boot_demo1.c.

    I needed to change the clock freq and the ccxml file for my target and add the timerIsr into the startup_ccs.c file, but the net result is the same. Anything after TimerEnable() creates the error posted earlier.

    -Phil
  • Phil,

    The first step should be to get the example "boot_demo1" to work on your hardware. Make the minimal changes required, without adding additional complexities.

    Once this works, you can start introducing one new variable at a time. This way it will be lot easier for us (on the forum) to help you.

    Thanks,
    Sai
  • Phil B said:
    Anything after TimerEnable() creates the error posted earlier.

    It looks like the TimerEnable() call will be the point the first interrupt occurs.

    Given that that an application Flash address offset has been used I think the base address of the interrupt vectors also needs to be adjusted, by writing to the Vector Table Offset (VTABLE) register.

  • Chester,

    So if I start my app from the bootloader there is already a parameter in bl_config.h that sets

    #define VTABLE_START_ADDRESS 0x4000

    But if I used ccs to dl and start my app from 0x4000 then I need to set VTABLE somewhere in my app? That makes sense.

    So is this a HWREG() type of command to set VTABLE? I'm not sure what the syntax is here.

    I notice that my cmd file has a section:

    .vtable : > RAM_BASE

    but maybe thats not the correct place to set it?

    Thanks,

    -Phil

    -Phil

  • The vector table offset is a register in the NVIC. Yes you have that section in the linker .cmd, but that is only relevant to the code placement. If you check the datasheet, you should find the correct address to change.
    After all, how would your MCU part, specifically the part that handles interrupts - the NVIC - know where the vector table would be?


    Checking the bootloader startup it seems:
    " ;; Set the application's vector table start address. Typically this is the
    ;; application start address but in some cases an application may relocate
    ;; this so we can't assume that these two addresses are equal."


    I don't quite see what the problems is.
    Maybe it was actually easier for me to make myself a bootloader by inspiring a bit on the example, than actually adapting the example.

    Try this on the beginning of your APP code (the code that the bootloader receives over serial)
    HWREG(0xE000E000 + (0xD08)) = 0x4000;
  • Luis Afonso said:
    Try this on the beginning of your APP code (the code that the bootloader receives over serial)
     HWREG(0xE000E000 + (0xD08)) = 0x4000;

    There is the TivaWare constant NVIC_VTABLE for the VTABLE register. i.e. can use:

    HWREG(NVIC_VTABLE) = 0x4000;

    There is an example of NVIC_VTABLE being written to by the CallApplication() function in the TivaWare usb_stick_update.c example, which is an example bootloader. i.e. the bootloader sets VTABLE before calling the application.

     However, if the application with a flash offset is loaded using CCS then VTABLE needs to be set (either in the application startup or in a CCS GEL script)

  • Chester,

    Thanks for the response. The HWREG command does the trick!

    -Phil