We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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 ?
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 ?
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.
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,
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
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() ; }