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.

fault when jumping from bootloader to application

Other Parts Discussed in Thread: TM4C1294NCPDT

My config: using TM4C1294NCPDT eval kit, CCS v6.0, TI-RTOS 2.0.1.23, SysBios 6.40.01.15, Compiler TI v5.1.5


I am getting a fault after jumping from my bootloader (exists at flash address 0x0000.0000) into my flash application (exists at flash address 0x0004.0000). 

ti.sysbios.family.arm.m3.Hwi: line 1036: E_hardFault: FORCED
ti.sysbios.family.arm.m3.Hwi: line 1081: E_memFault: IACCVIOL: Instruction Access Violation, address: e000ed34
Exception occurred in ISR thread at PC = 0x4317eb0e.
Core 0: Exception occurred in ThreadType_Task.
Task name: {unknown-instance-name}, handle: 0x2000ef48.
Task stack base: 0x2000ef98.
Task stack size: 0xc00.
R0 = 0x000507dd  R8  = 0xffffffff
R1 = 0x20014b4c  R9  = 0xffffffff
R2 = 0x00000004  R10 = 0xffffffff
R3 = 0x00000290  R11 = 0xffffffff
R4 = 0xffffffff  R12 = 0x00000000
R5 = 0xffffffff  SP(R13) = 0x20015340
R6 = 0xffffffff  LR(R14) = 0xfffffffd
R7 = 0xffffffff  PC(R15) = 0x4317eb0e
PSR = 0x60000038
ICSR = 0x00423003
MMFSR = 0x01
BFSR = 0x00
UFSR = 0x0000
HFSR = 0x40000000
DFSR = 0x0000000b
MMAR = 0xe000ed34
BFAR = 0xe000ed38
AFSR = 0x00000000
Terminating execution...

This is how I jump from my bootloader:

#define APP_START_APP_ADDRESS     0x00040000      // 256K 

// jump 
HWREG(NVIC_VTABLE) = APP_START_APP_ADDRESS;

__asm("    ldr     r1, [r0]\n"
      "    mov     sp, r1\n");

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

I am using TI RTOS in both my bootloader and the application, so maybe that is complicating things?  Can someone give me some suggestions on how to proceed.

Thank You.

  • Hello Hiowatha

    Using a RTOS will make things a little bit more complex. In a simple code I have always used the below allowing me to change execution locations.

    __asm("    movw    r0, #0x0000;"
        "movt    r0, #0x0040;"
        "ldr     sp, [r0, #0];"
        "ldr     pc, [r0, #4];");

    Also before doing the switch, always disable the NVIC handler.

    Amit

  • Hi, Hiowatha

    Maybe, I think that the exception is occurred because thumb bit is not set.

    Try changing the address of application to  0x00040001.

    Thank you.

  • Thank you both for your suggestions, I appreciate it.

    This is how it currently  "seems" to be working: (need to test it more)

    HWREG(NVIC_DIS0) = 0xffffffff;
    HWREG(NVIC_DIS1) = 0xffffffff;
    HWREG(NVIC_DIS2) = 0xffffffff;
    HWREG(NVIC_DIS3) = 0xffffffff;
    HWREG(NVIC_DIS4) = 0xffffffff;
    	
    HWREG(NVIC_VTABLE) = APP_START_ADDRESS;
    
    __asm("    ldr     r1, [r0]\n"
          "    mov     sp, r1\n");
    
    __asm("    ldr     r0, [r0, #4]\n"
          "    bx      r0\n");

    I will admit that I am not 100% sure why though.

    HWREG(NVIC_DIS0) = 0xffffffff;
    HWREG(NVIC_DIS1) = 0xffffffff;
    HWREG(NVIC_DIS2) = 0xffffffff;
    HWREG(NVIC_DIS3) = 0xffffffff;
    HWREG(NVIC_DIS4) = 0xffffffff;

    The example code I saw this in was jumping from an application in flash to the ROM bootloader.  The comments say that it is disabling all interrupts by doing this before the jump.

    Amit, 

          What did you mean by disabling the NVIC handler?

    Thanks again!

  • Hello hiowatha,

    Well you did that already as shown in the code post below...

    HWREG(NVIC_DIS0) = 0xffffffff;
    HWREG(NVIC_DIS1) = 0xffffffff;
    HWREG(NVIC_DIS2) = 0xffffffff;
    HWREG(NVIC_DIS3) = 0xffffffff;
    HWREG(NVIC_DIS4) = 0xffffffff;

    Regards

    Amit

  • Hello Amit,

    According to the manual of cortex-m, there is restriction that is bit0 of branch address must be 1.

    (Refer to http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABEFHAE.html)

    So, I think that the address of application must be 0x00040001 in the sample code posted by hiowatha.

    Is it  wrong?

    Regards

    Kyoman

  • Hello Kyoman,

    You are right that LSB has to be 1. But when compiled through standard compilers like the one in CCS, IAR, Keil, the compiler and linkers take care of the same. In this case Hiowatha is using a compiled image and loading the PC with the content of the Address in the 0x4 location which will have the correct PC value +1

    Regards

    Amit

  • Hi, Amit,

    what do you mean by "Using a RTOS will make things a little bit more complex"?

    I am using TivaC1294NCPDT, and I also need to bootloader to APP with RTOS. I think I have done everything, but it just doesn't work. The attached are: 1.The map of app. 2.Bin of app. 3.cmd of app and boot. 4.boot loader code.

    When I step into the bootloader, it looks to me the Jump2App is not correct. Here is what I see about the values of R0 and R1:

    1. After "HWREG(NVIC_VTABLE) = __Flash_Start_App_Run;", R0 is 0x20023C88 and R1 is 0xE000ED08

    2. After the first two asm, R0 is still 0x20023C88 and R1 is changed to 0xBEBEBEBE (I think this is not a valid value)

    3. After the next asm ("ldr     r0, [r0, #4]"), R0 is changed to 0xBEBEBEBE.

    4. And then, PC becomes "0xBEBEBEBE", which of course it not a correct address.

    I think the final R0 should be "0002caa1", which is "ENTRY POINT SYMBOL: "_c_int00"  address: 0002caa1" in map file.

    The application code could run normally with debugger.

    Could you help me check this issue? Thanks

     BootAndAP.zip

  • Hello Jianyi,

    The application's address must have the SP and PC mapped to the first two location of the application address space. The r0 shall contain the address of the application so that the ldr then load the sp with content of r0 and then load r0 with r0+0x4 and branch to r0.

    Regards
    Amit
  • Thanks, Amit. I wonder why the asm code from hiowatha doesn't work for me. I am not good at asm code, so could you please take a look for me?
  • I found the issue. It should be " HWREG(NVIC_VTABLE) = &__Flash_Start_App_Run", rather than " HWREG(NVIC_VTABLE) = __Flash_Start_App_Run".
    Thanks
  • hiowatha,

    I'm coming across this same problem that you were having. My bootloader and application is RTOS and I tried using the same code you have above but it's still failing. It'll jump to the application but then a fault is generated. Did you have to do anything on the VTABLE for the application to get it to work? Because if I use a simple application without interrupts or RTOS, then the jump works. So I'm guessing once the application generated an interrupt, the application faulted.

    Thanks.
  • If my memory serves me right... I believe this was answered in another post related to this problem:
    e2e.ti.com/.../347628

    Again going off of memory, for me the fix was to disable interrupts prior to jumping the application's address:

    here's how the current code looks like now:


    #define FLASH_DEFAULT 0xFFFFFFFF

    // disable all interrupts
    HWREG(NVIC_DIS0) = FLASH_DEFAULT;
    HWREG(NVIC_DIS1) = FLASH_DEFAULT;
    HWREG(NVIC_DIS2) = FLASH_DEFAULT;
    HWREG(NVIC_DIS3) = FLASH_DEFAULT;
    HWREG(NVIC_DIS4) = FLASH_DEFAULT;

    // reset vector table to application starting address
    HWREG(NVIC_VTABLE) = i_address;

    // jump (note: does not return from this point)
    __asm(" ldr r1, [r0]\n"
    " mov sp, r1\n");

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

    hope that helps!
  • hiowatha,

    Thanks for the response. I did see the previous thread and I'm using basically the same code to perform the jump but I'm getting a fault when the application starts executing. I'm thinking that it has something to do with the VTABLE. Do you recall if there was anything special you had to do with the VTABLE in defining the interrupts, like offsetting the address of the handler or changing the vtable memory from the default RAM_BASE?

    Thanks.