TM4C1294NCPDT: vector table

Part Number: TM4C1294NCPDT

As per data sheet of TM4C1294 controller the Register 57: Vector Table Offset (VTABLE), offset 0xD08

we can change the address of vector table, but the first 9 bits are RO (read only) so how does this program still works.

*Bootloader program

    __asm(" mov r0, #0x4000\n"
          " ldr r1, [r0]\n"
          " msr msp, r1"
    );
    __asm(" ldr r0, [r0, #4]\n"
    " bx r0\n");

*Application Program

HWREG(NVIC_VTABLE) =  0X4000;

i think I should we have to write

HWREG(NVIC_VTABLE) =  0X4000 << 10;

  • Hi soham patel

    No, you should not shift the address, and your proposed modification HWREG(NVIC_VTABLE) = 0x4000 << 10; is incorrect. The original application code HWREG(NVIC_VTABLE) = 0x4000; is technically right regarding the target address value, but it will fail on this specific MCU because the TM4C1294 requires the vector table to be aligned to a 1024-byte (1 KB) boundary, meaning bits [9:0] must be zero.
    The address 0x4000 already meets this requirement, so you pass the absolute memory address directly to the register without any shifting.
    1. Vector Table Alignment Demystified
    The TM4C1294 microcontroller uses an ARM Cortex-M4F processor. In this architecture, the VTABLE register holds the absolute 32-bit base address of the vector table. [1]
    • The Read-Only Bits: Bits [9:0] are reserved or read-only (RO) and are hardwired to 0.
    • The 1024-Byte Alignment Requirement: Because the lowest 10 bits are forced to 0, any address written to VTABLE must be a multiple of 1024 (which is 2¹⁰ or 0x400).
    • Your Target Address: The address 0x4000 in binary is 0000 0000 0000 0000 0100 0000 0000 0000. The lowest 10 bits are already all zeros.
    When you execute HWREG(NVIC_VTABLE) = 0x4000;, the hardware maps the bits directly. Bits [31:10] receive the corresponding upper bits of 0x4000, and the lower read-only bits naturally match the trailing zeros.
    2. Why Shifting Fails
    If you apply a bitwise shift using 0x4000 << 10, the resulting value becomes 0x1000000.

    Writing this to VTABLE tells the processor that your vector table is located at 0x01000000 (which points to an invalid or completely different memory region on the TM4C1294 chip layout), causing an immediate hard fault when an interrupt triggers.
    3. The Real Bug in the Code
    While shifting is wrong, the original line HWREG(NVIC_VTABLE) = 0x4000; has a different, critical issue. The address 0x4000 (16 KB) is located inside the Flash Memory region of the TM4C1294.
    Flash memory on this MCU cannot be written to like normal RAM. You cannot simply overwrite the VTABLE register if the register assignment micro-macro (HWREG) is trying to force a raw change without looking at alignment toolchains. More importantly, a standard ARM Cortex-M4 vector table contains over 100 entries and requires at least 1024-byte alignment.
    While 0x4000 is perfectly aligned (16384 ÷ 1024 = 16), make sure your application image is actually compiled to start exactly at 0x4000 in your linker script (.cmd or .ld file).
    Correct Implementation
    To safely relocate your vector table in C, let the compiler toolchain handle the mathematics and alignment dynamically rather than hardcoding a magic number.
    // Force the compiler to align the table structure to a 1024-byte boundary
    SB_ALIGN(1024) static uint32_t LocalVectorTable[NUM_INTERRUPTS];

    // Assign the absolute address directly to VTABLE
    HWREG(NVIC_VTABLE) = (uint32_t)LocalVectorTable;
    If you are jump-starting an application located at flash address 0x4000, ensure your application initialization explicitly states:
    HWREG(NVIC_VTABLE) = 0x00004000;
    Thanks!
  • I remove this line of code HWREG(NVIC_VTABLE) = 0X4000 << 10; but still it works.

    I think that this line of code does not matter to change the address of vector table.

    In application program address of vector table will change as i change the #define APP_BASE 0X4000 in .cmd file.

  • Hi soham patel
    Why it still works right now
    When your bootloader executes bx r0, it jumps directly to the application's Reset Handler.
    The application starts running its main loop normally because running regular code does not require the vector table. The CPU just executes instructions sequentially. As long as no interrupts occur, the CPU never needs to look at the VTABLE register.
    Thanks
  • Thanks for your respose.