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.

Offset Vector Table in TM4C

Other Parts Discussed in Thread: TM4C123GH6PM

Hi,

I am using TM4C123 MCU and would like to build remote firmawre upgrade feature. The process will be as below.

The memory will be divided into 2 blocks. Application 1 will reside between 0x00000000 to 0x00001FFFF and the Application 2 will reside between 0x00020000 to 0x0003FFFF.

Now how do I write the vector offset register so that I will switch to Application 1 or application 2?

Is there any method by which I can switch My vectors to the specified location?

Sincerely,

Shenoy

  • Hi Shenoy,

    You can use the VTABLE register in the Cortex-M4 Peripherals to remap. The Register address is 0xE000ED08

    Regards

    Amit

  • Hi Amit,

    Thank you for your response. As I said, I need to switch to new firmware after uploading. I am not sure whether writing to offset vector will meet my requirement.I assume as soon as I reset the offset will become 0 and thereby I may not be able to switch to desired location. Can you please suggest on this regard.

    Sincerely,

    Shenoy

  • Hi Shenoy,

    If reset is your concern then, What you need is a loader code in the Flash, which will check the validity of the image in each of the two regions and then make a jump to the correct region with the VTABLE mapped to that region. You would not be able to use 0x0 as the first region as the loader code has to reside here.

    Regards

    Amit

  • Hi Amit,

    Thank you for your immediate response.

    If I understand you correctly, I need to have a monitor code to check where the application is and then I need to write to offset register to jump to correct location.

    Let me put in my understanding:

    1. There will be a Monitor Code in 0x000

    2. Application 1 will reside in 0x001000

    3. Application 2 will reside in 0x00020000

    In Monitor  code I will get the application version from internal EEPROM (Assuming I will write the app information in EEPROM whenever it is uploaded). Now to switch to the desired application, How do I map the VTABLE?. Will it be sufficient to write the offset to VTABLE (0x1000 incase of Application 1 and 0x00020000 in case of Application 2). 

    Thanks again,

     Sincerely,

    Shenoy

  • Hi Shenoy,

    Yes that would be sufficient for you to write the VTABLE. Please note that write to the VTABLE is in privilege mode.

    Regards

    Amoit

  • Hi Amith,

    Thanks again,

    2 more points:

    1. After Changing the OFFSET address, Is there a reset applied?

    2. Can you please give example of writing to VTABLE in privilege mode. I am new to this series controller.

    Sincerely,

    Shenoy 

  • Hi Shenoy

    You do need to apply a reset and I think it should be a direct write to the VTABLE register

    Regards

    Amit

  • Hi everyone

    I want do same sort of firmware upgrading means i want to have two application code in my flash and according to my wish I want to run an application among those two already loaded application.I have tried to write In VTABLE register in my boot loader code,still I m not able to run any of my loaded application.I am a newbie in this area so I dnt know much about such things.Please help me with this.

    With regards

    Arun

  • Hi,

    There is an only one single common place where you can change the interrupt vectors and this is the SRAM, starting always at 0x20000000. The change can be made easily if your application has at least one interrupt and you call IntRegister function - this will move the whole interrupt vector to this new location. 

    Please read the documentation about that and the code to see how it is made.

    Petrei

  • hi

    Can anyone please tell me how to write to the VTABLE register in privileged mode.

  • Hello Arunabha

    Did you try writing the VTABLE in the user code and check it is getting written?

    Regards

    Amit

  • Thanks Amit for your reply.

    I did write in VTABLE register  but it is not getting updated.

  • Hello Arunabha,

    I wrote a simple code

        HWREG(NVIC_VTABLE) = 0x20000000;


    and after executing this I checked 0xE000ED08 register and it shows 0x20000000. Before that it was showing 0x0.

    Regards

    Amit

  • Hi Amit

    thanks again for ur help.This piece of ur code works.I hope u can give me little more insight about the problem I am facing.

    Ihave written one of application code and stored it in flash memory starting from 0x0010000 and my other application is residing at 0x0020000.i have written another piece of code which is starting at 0x00000000.In this piece of code I am manipulating the VTABLE register with 0x0010000 as i want to run this application after reset.i dnt have much knowledge and may be i am doing some huge mistake somewhere.My app1 is not even running after reset.can You please suggests me what can I do.

  • Hello Arunabha,

    How do you make the decision to run APP1 or APP2? Secondly in the existing code's how do you jump to the APP1 or APP2?

    Regards

    Amit

  • Hi Amit,

    I thought writing to he VTABLE register will be only needed to make my microcontroller runs from a specific section of the flash memory.And thought I know that i need to check the validity of the applications before jumping to them,but for the time being i am just trying to jump to one of the two application.To make the things simpler i did not went to check the validity of my application.But it turned out i am wrong probably.can you please guide me through this.

    Thanks

  • Hello Arunabha,

    Just writting to the VTABLE is not sufficient. The VTABLE only tells where the Interrupt vector will be kept for the APP1 and APP2. If you reset the device the VTABLE will also be reset to 0x0. If for the moment you think that the APP1 is vaild, then map the VTABLE and jump to the function for APP1. Any interrupt fired in APP1 will refer to VTABLE entry that has been updated.

    Regards

    Amit

  • Hi Amit,

    Thanks again for ur reply.Basically I want to load to app code in my flash memory in two different locations.And upon reset I want to run of these code.I read the replies u have given in similar context.Can u please tell me is this thing even possible or not and if possible what should I do.

    thanks

  • Hello Arunabha,

    It is possible to do what you have mentioned. The only things that needs to be taken care of as was mentioned in the forum post

    1. The 0x0 location must have a generic APP loader (if I may use this term), that can decide which of APP1 or APP2 to be loaded. This is because the VTABLE register will be reset to 0x0 at Power Up.

    2. The VTABLE for APP1 or APP2 should have the address where the Interrupt Vector Table for the APPs is kept so that if an interrupt occurs it goes to the corresponding APP's Interrupt table and not to the APP loader Interrupt Table. If however the Interrupt for APP1 and APP2 are identical and are no different then you can simplify the code using the existing APP loader Interrupt Table in which case VTABLE does not need to be modified.

    Regards

    Amit

  • Hi Amit

    Thanks for ur quick reply.For the time being I just want to load two separate code in locations of flash memory.i am not using any interrupts in my code for simplicity.Upon reset depending on my choice i want to run one of these code. I simply tried to load to code in two different location in my flash memory by changing the flash address in their respective startup.s files.But upon reset none of my code is running.The reason may be that none of code is stored at 0x0 of flash memory.i want to know how can  I run one of my loaded code.

  • Hello Arunabha

    That is correct. There is no code in 0x0 for the CPU to work at reset. You will have to write this code

    Regards

    Amit

  • Hi Amit,

    I am trying to write a code which will reside on 0x0 of flash memory and which will allow the processor to run one of my previously loaded code.But verily speaking I dnt have any idea how to do that.Will appreaciate ur help.

    Thanks

  • Hello Arunabha,

    A simple example would be to have in the main.c something like

    if(GPIO is set) {

    APP1();

    } else {

    APP2();

    }

    The APP1 and APP2 map to predefined Flash locations which have been made as entry point when generating the bin files for APP1 and APP2.

    Regards

    Amit

  • Hi Amit,

    I have loaded my app1 and app2 at 0x0001000 and 0x0002000 respectively.And with urs suggestions I came to know that i need to write another piece of code which is necessary to run one of my application.In this piece of code I dnt want to use aap1 and app2 as functions.I want my this code to run after reset and this code eventually should call one of my application .I looked in forum and as well data sheet also but I am not getting any clue how to do that.please help me with this.

    Thanks

  • Hi,

    I have implemented the APP1 And APP2 Conscept.

    I will explain how I have implemented:

    APP1 is at address 0x2800

    APP2 is at address 0x20000

    Monitor Code which selects the APP1 or APP2 on reset resides at 0x0000

    The APP1 or APP2 can be selected by writing the value in flash. For example I have taken 0x3FC00. If @0x3FC00 is '1' I will be switching to APP1, and if it is'2', I will be selecting the APP2.

    Below is the monitor code snap for your reference:

    unsigned char Ver_write[10];

    unsigned char Get_Block[10];
    unsigned int i=0;
    for(i=0;i<10;i++)
    Get_Block[i] = 0x00;

    // read memory Location for getting which Firmware to be used
    Read_From_Flash(0x3FC00, &Get_Block[0],4);

    // if it is 0x31 0x31 0x31 0x31 then Block 1 switch to Vector 0x2800
    if(Get_Block[0] == '1' && Get_Block[1] == '1' && Get_Block[2] == '1' && Get_Block[3] == '1')
    {
    HWREG(NVIC_VTABLE) = 0x2800;
    //
    // Load the stack pointer from the application's vector table.
    //
    __asm(" ldr r1, [r0]\n"
    " mov sp, r1");

    //
    // Load the initial PC from the application's vector table and branch to
    // the application's entry point.
    //
    __asm(" ldr r0, [r0, #4]\n"
    " bx r0\n");

    }

    // else if it is 0x32 0x32 0x32 then Block 2 Switch to Vector 0x20000
    else if(Get_Block[0] == '2' && Get_Block[1] == '2' && Get_Block[2] == '2' && Get_Block[3] == '2')
    {
    HWREG(NVIC_VTABLE) = 0x20000;
    //
    // Load the stack pointer from the application's vector table.
    //
    __asm(" ldr r1, [r0]\n"
    " mov sp, r1");
    //
    // Load the initial PC from the application's vector table and branch to
    // the application's entry point.
    //
    __asm(" ldr r0, [r0, #4]\n"
    " bx r0\n");
    }

    Hope this will help.

    Regards,

    Shenoy

  • Hi Shenoy

    thanks for ur reply.I have tried ur method.the piece of monitor code i have written ,i am uploading here.My app1 is stored at 0x0020000.


    int main()
    {

    HWREG(NVIC_VTABLE) = 0x00020000;
    __asm(" ldr r1, [r0]\n"
    " mov sp, r1");

    __asm(" ldr r0, [r0, #4]\n"
    " bx r0\n");

    // SysCtlDelay(4000000);
    //while(1);
    }

    After reset i just want to run my app1 ,which is stored in above mentioned location.But this is not happening.My app1 is not running.Will  appreciate ur help.

    Thanks

  • Hi,

    Can you please Tell me how you are loading the Program?

    I use LMflash programmer for loading.

    2 quick points:

    - Monitor Program Address should be as 0x00000 in the project.

    - APP 1 address should be 0x00020000 in the project.

    Hope You have taken Care about this.

    Create Hex file of Both.

    Open the LM Flash Programmer

    Load Monitor program hex file by Selecting Erase entire flash and Program address as 0

    Now load App1 hex file by selecting erase necessary pages and program address as 0x00020000

    After this restart the unit and check app1 is running.

    Hope you are clear

    regards,

    Shenoy

  • Hi Shenoy

    Yea I have edited the flash address at .cmd file of my app project to 0x2000.And i am doing the same as U told.but the app1 is not running.

    Thanks Arun

  • Hi Arun,

    Can you please re-confirm the app1 address. I read it as 0x20000 and here I am reading it as 0x2000. And also how did you load the program?

    Regards,

    Shenoy

  • Hi Shenoy

    Sorry for the mistake.It is 0x20000.And I am loading by lm flash programmer.I have tried with ccs also.

  • Hi Arun,

    Can you please tell me the part number of mcu. Also Can you please share the c file of the monitor code.

    Regards,

    Shenoy

  • Hi Shenoy

    I am using TM4C123gh6pm.And My monitor code is simple.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_gpio.h"
    #include "inc/hw_flash.h"
    #include "inc/hw_i2c.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_nvic.h"
    #include "inc/hw_ssi.h"
    #include "inc/hw_sysctl.h"
    #include "inc/hw_types.h"
    #include "inc/hw_uart.h"
    #include "driverlib/uart.h"
    #include "driverlib/rom.h"


    int main()
    {

    HWREG(NVIC_VTABLE) = 0x00020000;
    __asm(" ldr r1, [r0]\n"
    " mov sp, r1");

    __asm(" ldr r0, [r0, #4]\n"
    " bx r0\n");

    // SysCtlDelay(4000000);
    //while(1);
    }

    Thanks Arun

  • Hi Shenoy

    Thanks for ur help.i had done a silly mistake.Now its working properly

    With regards

    Arun

  • Hi Arun,

    Good to note you are able to achieve the end result. Keep the good work going!:)

    Regards,

    Shenoy

  • Hi,

    I am also facing similar problem. I am not able to jump to the specified (0x10000) address from my APP1.

    What can be the mistake???

    Best Regards,

    Rushikesh