2008-03-07 08:12 PM
Jumping execution to an absolute address
2011-05-17 03:25 AM
I want to write a code to jump at an absolute location.
I used this code I always get hard fault exception I have already defined some code at 0x8006C00. typedef void (*appFunc)(void); void main(void) { u32 appFuncAddr; … some other code appFuncAddr = (u32)0x8006C00; ((appFunc)appFuncAddr)(); }2011-05-17 03:25 AM
Try This, I haven't tried this but I think it will work
typedef void (*appFunc)(void); void main(void) { appFunc appFuncAddr; … some other code appFuncAddr = (appFunc )0x8006C00; appFuncAddr)(); } Troy2011-05-17 03:25 AM
If you want to jump at address 0x8006C00, you must write
appFuncAddr = (appFunc )0x8006C01; Some explanations : Remember that previous ARM processors have two sets of instructions : ARM and Thumb. To go from one set to other a BX instruction is use with the form of BX Rx. If bit 0 of Rx is 0, next is ARM instructions, if bit 1 of Rx is 1, next is Thumb instructions. With Cortex-M3, there is no ARM instructions but only Thumb with Thumb2 extensions. But BX instructions is the same. If you try to go to ARM instructions you obtain an Hard Fault Exception. When you write : appFuncAddr = (appFunc )0x8006C00; appFuncAddr)(); compiler generate LDR Rx,=0x8006C00 BX Rx So bit 0 is 0 and you try to go to ARM instructions. If your code is at 0x8006C00, you must have in assembleur : LDR Rx,=0x8006C01 BX Rx So processor jump at address 0x8006C00 in Thumb mode (bit 0 is 1)2011-05-17 03:25 AM
Thanks Eric,
with your suggestions code is working. Thanks a lot!!2011-05-17 03:25 AM
With IAR assembler, bit 0 is set for label in code section (keyword 'thumb') but is reset in data section (keyword 'data').
When you declare a jump table with directive 'dc8', 'dc16' or 'dc32', you are generally in data section and so label for start of jump table don't have bit 0 set.2011-05-17 03:25 AM
Thanks Eric, your clear explanation has helped me understand a problem I was having with my assembler routine.
I'm new to ARM processors and this mode swapping scheme (called ''interworking'') took me by surprise. This was causing me trouble when trying to calculate the address into a jump table. I now understand that with the IAR assembler, all labels in code space have bit0 = 1 (because they are thumb code labels). So the following will work: ADR Rx, =Label ;where label is in code space, bit 1 is set BX Rx but the following won't work (this is what I was doing wrong): ADR Rx, =Label MOV PC, Rx ;FAIL - will try and jump to odd address The ''MOV PC, Rx'' isn't an interworking instruction (it doesn't consider bit0 as special), so it tries to jump to an odd address - causing an exception. Some assemblers apparently don't set bit0 on labels, so I will be using the following code to ensure portability: ADR Rx, Start_of_jump_table BIC Rx, Rx, #1 ;clear that tricky interworking bit ADD Rx, Rx, Ry ;add any jump table offset here MOV PC, Rx ;jump into the table So the following might work for Troy as well: LDR Rx,=0x8006C00 MOV PC, Rx Greg.