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.

Compiler/TM4C123GE6PZ: Problem running a program from a different address with bootloader when external interrrupt handlers are present.

Part Number: TM4C123GE6PZ

Tool/software: TI C/C++ Compiler

Hello everyone, 

I am having problems running an application with a bootloader on a custom TM4C123 board. 

The application has 2 interrupt handlers present that is linked on startup.ccs file.

When the application runs from appbase  = 0x00000000 there is no problems and these interrupt handler are called without issue.

However, when I change the appbase to 0x00002800 on the cmd file even though the map file shows correct offset and addresses for the symbols of the handlers they are not called 

and the program jumps to an address where there is no user application(0x20009002).

Does anyone encountered similar problems similar to this?

Thanks. 

The cmd file is the following:


--retain=g_pfnVectors


#define APP_BASE 0x00002800
#define RAM_BASE 0x20000000

MEMORY
{
FLASH (RX) : origin = APP_BASE, length = 0x0003d800
SRAM (RWX) : origin = RAM_BASE, length = 0x00008000
}

SECTIONS
{
.intvecs: > APP_BASE
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH

.vtable : > RAM_BASE
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
}

__STACK_TOP = __stack + 512;

The symbols are shown like this: 

GLOBAL SYMBOLS: SORTED BY Symbol Address

address name
------- ----
00000200 __STACK_SIZE
00002800 g_pfnVectors
...
...
00003e3f Timer1BIntHandler
00003e53 Watchdog0IntHandler

  • Hi Tuna,

      Are you using the TivaWare bootloader example as a reference? Have you had a chance to run any TivaWare bootloader examples? 

      Since you define the APP_BASE at 0x2800, did you also make the same change in the bl_config.h file (if you are using the TivaWare bootloader example as a reference)? 

    //*****************************************************************************
    //
    // The starting address of the application. This must be a multiple of 1024
    // bytes (making it aligned to a page boundary). A vector table is expected at
    // this location, and the perceived validity of the vector table (stack located
    // in SRAM, reset vector located in flash) is used as an indication of the
    // validity of the application image.
    //
    // The flash image of the boot loader must not be larger than this value.
    //
    // Depends on: None
    // Exclusive of: None
    // Requires: None
    //
    //*****************************************************************************
    #define APP_START_ADDRESS 0x4000 // the default is 0x4000 in the example, you need to change to 0x2800 to match the cmd file

  • Yes I am using the boot serial example which uses 2800 not USB example.

    I can run other projects that I built that doesn't have any custom interrupt handlers fine. 

    I only have the problem when I have external interrupt handlers.

  • I suspect that you do not have the NVIC (nested vector interrupt controller) pointing to your correct vector table. By default, the vector table base address is address 0x0. You can see the base address in the NVIC registers in Code Composer.

    The vector table can be in Flash or RAM. Your link command file is setup for both, so I am not sure which one you are trying to use. I will explain both.

    By default, the vector table is in Flash at address zero. If you want to use a vector table in flash, that is not at address zero, you must write the address of the new vector table to the NVIC_VTABLE register. There is no TivaWare function to do this, so it would be done with a direct register write:

            //
            // Point the NVIC at the new Flash vector table.
            //
            HWREG(NVIC_VTABLE) = 0x2800;
    

    You move the vector table to RAM when you call the TivaWare function IntRegister(). This function will copy the vectors pointed to by the NVIC_VTABLE register into the RAM section ".vtable" (unless it is already pointing there) and then replace the one vector which you are registering. 

    If you mix the two methods in application code that runs with a bootloader, you must use the HWREG write of NVIC_VTABLE before calling IntRegister(). That way the IntRegister() function will copy your application's vector table from flash to RAM instead of copying the bootloaders vector table.

    There is more information about the difference between vector tables in flash compared to RAM in section 17.1 of the TivaWare Pericpheral Driver Library User's Guide. (C:\ti\TivaWare_C_Series-2.1.4.178\docs\SW-TM4C-DRL-UG-2.1.4.178.pdf)

  • Bob,

    Staff & this reporter (unanimously) applaud the care, detail & completeness of your writing.    Excellent - and 'if only' an (adequate Tag) could  'somehow be attached!'

    Tag: Forum 'change' negatively impacts a major forum contributor!    Unanticipated consequences (again) rule.   Poster's Tags - appearing (only) w/in opening post - are 'far too general to prove of use!'   Can 'obscuring a terrific effort' be in any means, justified?    (that's just what's happened - has it not?)    The (dreaded) removal of  '**LIKE!** (as we predicted) preceded the forum's degradation...

  • Hello Bob,

    Thanks for a really detailed response.

    I am using the flash nvic table and my application is linked to have the table on 2800. 

    I tried setting the nvic table to 2800 as well but my interrupts are still not firing.

    Right now I am testing the application in isolation(without the bootloader) on ccs would that also create problems or the serial bootloader is not equipped to do the nvic table offset change?

    Best Regards,

    Tuna Bicim 

  • Even without the nvic table jump the program works now. 

    I think when testing on debug mode without the bootloader the example was going to fault when interrupts hit.

    I also tested on debug with the nvic table change and everything runs unless there is a reset and then same behaviour happens which makes sense because table goes back to 0x0000. 

    I also tried using IntRegister but for some reason it didn't work for me. Maybe I did something wrong. 

    Thanks again for all the answers. 

    Best Regards,

    Tuna Bicim