This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

JUMP Problem when using RTX RTOS

Hi all ,

Using Uvision4 & LPC1768 & RTX RTOS ,
I want to jump to 0x10000 of the flash.
Before running RTX , there is no problem but after using os_sys_init(APP_TaskStart) , when trying to jump , there is a hardfault . How could I jump while RTX is running ?

By the way , Is there a way to disable RTX ?

Parents
  • The document says :
    “A hard fault is an exception that occurs because of an error during exception
    processing, or because an exception cannot be managed by any other exception
    mechanism “

    This is my code :

    __disable_irq();
    SCB->VTOR = 0x10000;
    user_code_entry = (void (*)(void))(0x00010000 | 0x00000001);
    user_code_entry();
    


    Exactly at the "SCB->VTOR = 0x10000" line the hard fault occurs .
    Probably this means an exception has occurred while SCB->VTOR has changed .
    Probably this exception is The SystemTick exception .
    SO if I disable SystemTick exception the problem is solved . Isn’t this true ?
    But the problem is __disable_irq() doesn’t have any effect on SystemTick apparently.

    How could I handle this problem ?

Reply
  • The document says :
    “A hard fault is an exception that occurs because of an error during exception
    processing, or because an exception cannot be managed by any other exception
    mechanism “

    This is my code :

    __disable_irq();
    SCB->VTOR = 0x10000;
    user_code_entry = (void (*)(void))(0x00010000 | 0x00000001);
    user_code_entry();
    


    Exactly at the "SCB->VTOR = 0x10000" line the hard fault occurs .
    Probably this means an exception has occurred while SCB->VTOR has changed .
    Probably this exception is The SystemTick exception .
    SO if I disable SystemTick exception the problem is solved . Isn’t this true ?
    But the problem is __disable_irq() doesn’t have any effect on SystemTick apparently.

    How could I handle this problem ?

Children
  • Are your boot loader _really_ so advanced that it needs to run an RTOS?

    If you do have very complicated code in the boot loader that you want to use RTOS, why not then have the boot loader decide if it should just boot an application (do that without use of RTX) or decide that the boot loader needs to do advanced communiaction.

    You could then always perform download of a new application and when everything is completed you can force a watchdog reset, and then have the boot loader directly start the application.

    But in reality, a boot loader using RTX sounds like a violation of the KISS principle.

  • Not in privileged mode? Maybe you need to execute an SVC first.

  • Are your boot loader _really_ so advanced that it needs to run an RTOS?

    RTOS has its place, but I have seen more cases of a RTOS used where it should not be, than cases where a RTOS was not used but should be.

    also a very complicated bootloader is more likely to suffer from the one unexcusable bootloader fault: "If power fails at point x, the system is hung".

    ANY bootloader that can not be restarted if interrupted by ANYTHING such as noise, power failure or whatever is a piece of crap. The criticl place, of course, is the transition from boot to app.

    Erik

  • Thanks ,

    RTX wasn’t in privileged mode so I checked it’s check box and now it’s in privileged mode .
    Now when jumping to 0x10000 there is a hard fault again but it’s position has changed from the vector table of bootloader to the vector table of the application .
    In fact this time the the bootloader has been able to remap the vector table but the hard fault persists like before .
    How could I get rid of this hard fault ?

  • Are your boot loader _really_ so advanced that it needs to run an RTOS?
    I can solve this problem by resetting the system but I need to jump from the application to the bootloader for reprogramming command again and the application program is in RTX OS too .
    So I need to jump again .
    Apart from that the jump problem through RTX must be solved for my future projects .

  • The best I can do is show you how one of my bootloaders jumps to another bootloader (analogous to your aplication):

    void execute_user_code(void)
    {
            // remap interrupt vectors
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAIN_BOOT_FLASH_START);
    
        jump_to_application() ;
    }
    
    /* One major difference between an ARM7 device and a Cortex-M3 is the content of the vector table:
       when you jump to application in an ARM7, you can expect code inside the vector table, so you
       can jump to its beginning and know you are correct. The vector table of a Cortex-M3 needs to be
       dereferenced in order to retrieve the entry point to the application. */
    __asm void jump_to_application(void)
    {
        ; program stack pointer of main bootloader
        LDR     R0, =0x1000 ;=MAIN_BOOT_START
        LDR     SP, [R0]
    
        ; extract entry point into main bootloader
        LDR     R0, =0x1004 ;=MAIN_BOOT_START+4
    
        ; jump
        LDR     PC, [R0]
    }
    

    where

    #define MAIN_BOOT_FLASH_START    0x1000
    

  • One thing here - you should really deactivate every single interrupt before you try to remap the interrupt vector table. How fun is it that you have given the interrupt vector controller actual pointers to ISR functions, when you then invalidate the right to make use of these functions...

    But in response to:
    "I can solve this problem by resetting the system but I need to jump from the application to the bootloader for reprogramming command again and the application program is in RTX OS too ."

    The normal route is to just take a watchdog reset, and the boot loader will then check the state. Leave it a flag that tells the boot loader that you want to swap applications. Depending on your design, you either make use of a rather complicated flag in RAM (complicated to make sure that random RAM contents doesn't also look like your flag) or write the flag into flash or EEPROM so the boot loader even after a power off can see "current app is #1, wanted app is #2".

    Just as Erik mentions - make sure that every step in the reprogramming sequence is allowed to fail at any stage from a power loss. The boot loader should be able to detect if there are valid firmware or not. It should be able to detect if it has only half-updated the device and either wait for the data again (if direct update through cable) or restart the programming in case you have a design with two memory regions to allow one app to run while next app gets downloaded.

  • Thanks my friends ,

    Finally I used watchdog reset to get rid of this problem
    At the first line of the bootloader I check one address of the flash .
    If it is 0xFF then I go to the bootloader program and if is something else (0xAA) go to the application.
    At the start of programming , the mentioned flash address is set to 0xFF .
    if the bootloader has been able to completely program the application , at the final transmission , the mentioned flash address is set to 0xAA .

    Thanks again

  • void execute_user_code(void)
    {
            // remap interrupt vectors
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAIN_BOOT_FLASH_START);
    
        jump_to_application() ;
    }
    


    if a power failure or similar event happens during this you are screwed

  • is in the start vector to have ONE bit/byte/word that directs the reset to app or boot. change the ONE bit/byte/word and reset the processor to switch

    Erik

  • Erik,

    Please explain what you mean exactly?

  • You don't know what you are doing. You write as if you know but what you write gives you away.

    I am far better than you and I am not going to waste any more time with you.

  • Bighead Posted
    I am far better than you

    how fitting

    Erik

    PS I'd like to know who 'you' is, there are many posters in this thread.

  • Tamir,

    the code you posted will work IF no power interruption happens while the snippet you posted is executing.

    e.g.

    void execute_user_code(void)
    {
            // remap interrupt vectors
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAIN_BOOT_FLASH_START);if power dies here you will have
    //                                                                    the boot with some app vectors
    //if power dies here you will have the boot with the app vectors
        jump_to_application() ;
    }
    

  • if NVIC_SetVectorTable set the reset vector first, then

    void execute_user_code(void)
    {
            // remap interrupt vectors
        NVIC_SetVectorTable(NVIC_VectTab_FLASH, MAIN_BOOT_FLASH_START);if power dies here you will have
    //                                                                    the app with some boot vectors
       jump_to_application() ;
    }