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.

CC1310: Change default reset vector table address NoRtos, IAR

Part Number: CC1310

Hello.

I'm using CC1310 custom boards for my project.

I'm using IAR ide for development.

I'm using Nortos in my project. I've seen the Bim examples provided in the ble stack directory and have successfully achieved creating 2 separate projects and jump between both the projects situated at different flash locations.

Let's say App1 is at 0x00 and App2 is at 0x100. I've defined the app start address and vector table start addresses as follows.

For App1 Vector table start is @ 0x00 and App2 vector table start os @0x100. Both applications run just fine and I'm able to switch between them but let's say suppose my execution is in App2 and there's a POR then after resuming the controller starts running App1.

This behavior indicates that I'll have to change more things than just the vector table addresses. I read the reference manual which says that by default after reset controller will switch the execution to 0x00.

My question is

1. Is there a way to change this default jump address?

I've also read about Vector table offset register which can be changed.

2. So is Vtor the solution to my problem?

3. If yes can anyone tell me which function will let me write to this register?

Also while searching about related question i came across m3hwi.resetvectoraddress which needs to be changed in one of the .cfg file. But that question was related to ccs and I'm using IAR.

4. So can we change the default vector address by changing it's value in a file before builiding the project? If yes then how?

Regards,

Nishit.

  • Hi Nishit,

    Could you maybe share some code on what you are doing? The BIM does the jump to an image by pointing to different resetISRs, not changing vector tables. If the system does not boot into the correct image following a POR, I would assume you need to add in additional checks in your bootloader to handle this (after all, how could the device after a POR know what state anything is in as the device has been reseted?).

    There is no way of changing the default vector table address at 0x0 without actually writing to VTOR. There is no file you can change to simply build this into the NoRTOS project that I'm aware of.

    I would need more information to answer question 2, but if you would be to alter the VTOR register you would have to do this by direct register access:

    dev.ti.com/.../CPU_SCS.html
  • Hello M-W.

    In this link and other places that I've read, we need to change m3Hwi.resetVectorAddress to change the reset vector address for the controller to JUMP to that address after POR.

    Link to once such question is as follows. 

    So is there any such thing in the SDK for IAR and NoRtos configuration?

    And does VTOR do the same thing as m3Hwi.resetVectorAddress = some address does?

    Regards,

    Nishit.

  • Hi Nishit,

    It would be the same thing, you would still have to distinguish resetVectorAddress and vectorTableAddess and how these work together:

    dev.ti.com/.../

    There is no similar configuration for NoRTOS, NoRTOS is simply a small DPL layer that lets you re-use the TI-Drivers that is available (while also supporting semaphores and some other features).

    Still I'm not sure I really understand your issue, maybe you could elaborate on this abit more? You have a working bootloader that can jump between two separate project as expected. Exactly what behavior are you expecting to see after the POR? The POR will be a complete reset, this means you would end up in the same scenario as powering the device on the first time.
  • Hello.

    Okay fine I'll explain you the scenario once again.

    I've 2 codes, one which blinks RED LED and other which blinks GREEN LED. (APP1 and APP2 respectively ).

    When in APP1, a button press should switch the control to APP2. Similarly button press in APP2 should transfer the execution to APP1.

    While building APP1, configurations in the rfEasyLinkEchoTx_CC1310_LAUNCHXL_NoRtos.icf are as follows.

    define symbol __intvec_start__ = 0x00000000;
    /*-Memory Regions-*/
    define symbol ROM_start__ = 0x00000000;   /* 0 - 40 Kbytes */
    define symbol ROM_end__   = 0x00009FFF;   /* 40 Kbytes code size */
    define symbol RAM_start__ = 0x20000000;
    define symbol RAM_end__   = 0x20004FFF;

    While building APP2, configurations in the rfEasyLinkEchoTx_CC1310_LAUNCHXL_NoRtos.icf file are as follows

    define symbol __intvec_start__ = 0x0000A000;
    /*-Memory Regions-*/
    define symbol ROM_start__ = 0x0000A000;   /* 40 - 80 Kbytes */
    define symbol ROM_end__   = 0x00013FFF;   /* 40 Kbytes code size */
    define symbol RAM_start__ = 0x20000000;
    define symbol RAM_end__   = 0x20004FFF;

    APP1 button press routine:

       PIN_close(pinHandle);
    	
       HWREG(NVIC_DIS0) = 0xFFFFFFFF;
       HWREG(NVIC_DIS1) = 0xFFFFFFFF;
       HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY |NVIC_APINT_VECT_CLR_ACT  ;
       
       asm("MOV R0, #0x0000A000");
       asm("LDR R1,[R0,#0x4]");
       asm("LDR SP, [R0,#0x0]");
       asm(" Bx R1 ");

    APP2 button press routine:

       PIN_close(pinHandle);
    	
       HWREG(NVIC_DIS0) = 0xFFFFFFFF;
       HWREG(NVIC_DIS1) = 0xFFFFFFFF;
       HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY |NVIC_APINT_VECT_CLR_ACT  ;
       
       asm("MOV R0, #0x00000000");
       asm("LDR R1,[R0,#0x4]");
       asm("LDR SP, [R0,#0x0]");
       asm(" Bx R1 ");

    Now, for downloading the codes I'm using SmartRF flash programmer2.

    Doing a mass erase at the beginning.

    Selecting Erase pages in image option so only the pages which are there in the image file are erased.

    Selecting APP2 file and downloading it from address 0x0000A000 and then selecting APP1 and downloading it from address 0x00000000.

    Now RED LED starts blinking, meaning APP1 is getting executed. 

    On button press (APP1) GREEN LED starts blinking which indicates a jump on APP2.

    On button press (APP2) RED LED starts blinking which indicates a jump on APP1.

    Now the discrepancy. When in APP2 I press the reset button APP1 starts to execute.

    This means after reset, controller Jumps to 0x000000 and starts fetching the instruction.

    Page 232 of the reference manual says the following

    On system reset, the resetVectorAddress is fixed at address 0x0000 0000. Privileged software can write to the Vector Table Offset Register (CPU_SCS:VTOR) to relocate the vector table start address to a different memory location, in the range 0x0000 0200 to 0x3FFF FE00. When configuring the CPU_SCS:VTOR register, the offset must be aligned on a 512-byte boundary.

    So how can i change the Vector Table offset while in APP2 so that after reset it jumps to 0x0000A000 and not 0x00000000.


    If VTOR is what i need, which CPU function will help me write to this register successfully as reference manual mentions that only priviledged software can write into this register.

    Please let me know if you do not understand any of the part.

    Regards,

    Nishit.

     

     

     

  • Hi Nishit,

    What the reference manual says is that following a system reset, the device will go expect the reset vector table at 0x0000 0000. Following the reset, you can then later relocate the vector table using VTOR (note the difference in reset vector table and vector table). Using TI-RTOS, you can see that the .cfg files relocate the vector table to RAM so that it may be changed during run-time. The reset vector table is however still 0x0000 0000. During a system reset, the whole CPU domain is power cycled meaning all registers will reset as well, thus the VTOR will again have to be programmed -> It is not retained during a reset.

    This means you still would have to, at every reset/startup, reconfigure VTOR again to move the vector table. Keep in mind here that both TI-RTOS and NoRTOS per default will try to relocate the vector table to RAM (otherwise there is no way to dynamically change the interrupt vectors) and you should not need to do this yourself.

    To do what you describe, you typically write a default bootloader to handle the case, located at the first page of the flash. This bootloader then takes the decision to either jump to app1 or app2. There is no way of simply changing the reset behavior of the MCU as you hope for.
  • Hello M-W.

    Thanks a lot for the insight. I first tried to keep a Bootlaoder Application as you mentioned at 0x00000000 location but I'm using Ti drivers in my application and because of them just the Nortos Init and Board Init takes upto 12 - 13 Kbytes of flash size. So to reduce that size I incorporated the Bootloader Application code inside my main Application code.

    Can you suggest any way we can opt out the use of drivers and do bare metal register level code which as far as I assume, will take less code memory.

    M-W said:
    reconfigure VTOR again to move the vector table.

    I'm not getting how should I write to VTOR. Can you elaborate on this if you know?

    Regards,

    Nishit.

  • Hi Nishit,

    If you opt out of using the TI Drivers your option is to either set everything up yourself using the direct register access or by using DriverLib. The later is a very low-level abstraction on register access, it is basically bare metal.

    Not using the TI Drivers and NoRTOS dpl also mean you will have to implement all the power saving functionality yourself (that you get for free with the TI Drivers) which can be a complicated task itself.

    You would write to VTOR using direct register access, if unsure on how this i done I again recommend looking at the available DriverLib:

    dev.ti.com/.../group__cpu__api.html

    You can see the source code of each of these functions which should give you a hint on how you would write to VTOR (also in the CPU_SCS region).

    Regarding the vector table, VTOR is set by the interrupt.h driver lib when the first interrupt is registered. As long as you are using DriverLib for your implementation, you should not need to configure VTOR yourself.
  • Hello M-W.

    Thanks for the information.

    So if I opt for using the Driverlib, do I need to implement the power saving functionality on my own? Like can I use both; Ti drivers for some modules and Driverlib functions where required?

    I'll read the Driverlib documentation which you've provided and try to change VTOR while using TI drivers.

    Regards,
    Nishit.
  • Hi Nishit,

    Yes you would have to implement the power saving logic yourself. I would not recommend mixing TI Drivers and DriverLib unless you really need to, stick with one of the two if possible. Using TI Drivers also makes it easier for us to support you and you will not have to bother about all power saving issues (turning domains off and on in correct order, waking up in time etc.).

    I still want to put emphasis on that you should not try to change VTOR unless you really know what you are doing. As this is something done by the low-level interrupt DriverLib itself when registering an interrupt, changing this further manually could screw your whole application up.

    What you have to do, in terms of bootloader, is to jump to the resetVectorTable of the application (be that 0x0000A000 for App2 if that is where you have located it). If you are then using either DriverLib to configuring interrupts or depending on TI Drivers (Hwi / Swi) to do this, the vector table will be moved to RAM by the application itself.

    The only real reason I can see where you would have to do this yourself is if you do not use either DriverLib or Ti Drivers, but instead develop the whole application using direct register access.
  • Hello M-W.

    Okay fine. It seems that the more correct way to proceed for me is by making a Bootloader code which will have a logic to decide the jump. Thanks for the support.

    Also a little more of your time. Right now for my application and the time constraints I'll be using the Ti Drivers. But for future I'm curious to use DriverLib or Direct Register level acccess methods as this will give me knowledge about how to fully configure and learn about this exceptional Microcontroller. So can you show from where can I start to learn all the basics of this controller from scratch and what all things do I need to look into and in what sequence ? Because I've seen that there are a lot of links and documentation available online like TI's Resource Explorer, Driverlib library documentation, Simplelink etc. But in what sequence one should refer what things is not properly documented anywhere as far as I've searched.
    So can you provide some insight in that direction?

    Regards,
    Nishit.
  • Hi Nishit,

    I think that will save you headache in the future if you make a proper bootloader for you application :)

    Regarding the basics (on a bare metal level) I would say the best approach you can take is to work with DriverLib and look on how this is built up as it is basically direct memory access. It is also easy to follow as all the source for each DriverLib function is available in the documentation with links to the register maps. This together with the Technical reference manual is what you can use to explore this direction, I'm not aware of any other documentation that would be more helpful then this.

    You can also always look into how the TI Drivers are built up around DriverLib in order to figure out how different peripheral can be used.

  • Hello.

    M-W said:
    You can also always look into how the TI Drivers are built up around DriverLib

    Is the source code for TI drivers available ? If yes then where can I find it as I'll be in a better state to use the functions used in the drivers if I get a look at the what Driverlib functions the drivers are using and in which sequence. And from that sequence I can refer the reference manual and Driverlib manual to see exactly what each line of code is used for.

    Regards,

    Nishit.

  • Yes, all TI Driver and DriverLib source code is available inside the SDK, look under the source directory inside the SDK installation folder.