EmbeddedRelated.com
Forums

How to move interrupt vector from 0x0 to some offset

Started by ADNAN January 7, 2010
Hello all,

I am newbie to Arm and IAR. I have develope an application using IAR5.30 and AT91SAM7S128 which has interuupt vector starting from 0x0 and rom starting from 0x5000 and when i load this application using jflash utitlity it is working fine.

On the same configuration(address) i have devloped a bootloader application. Now i want to download first application using this bootloader application. As the both bootloader application and the first application has the same interrupt vector address 0x0 so when i download it donot work.

Do i need to move the interrupt vector to some where else, ?

When i moved the interrupt vector of my application to 0x5000 , i.e. just in the start of the application, the interrupt are not working.

Kindly send your valuable advise and observation to help solving my problem.

Your kind guidence will be highly appricated.

Regards
Dani

hjh
Sent on my BlackBerry from Vodafone

-----Original Message-----
From: "ADNAN"
Date: Thu, 07 Jan 2010 21:56:23
To:
Subject: [AT91SAM] How to move interrupt vector from 0x0 to some offset

Hello all,

I am newbie to Arm and IAR. I have develope an application using IAR5.30 and AT91SAM7S128 which has interuupt vector starting from 0x0 and rom starting from 0x5000 and when i load this application using jflash utitlity it is working fine.

On the same configuration(address) i have devloped a bootloader application. Now i want to download first application using this bootloader application. As the both bootloader application and the first application has the same interrupt vector address 0x0 so when i download it donot work.

Do i need to move the interrupt vector to some where else, ?

When i moved the interrupt vector of my application to 0x5000 , i.e. just in the start of the application, the interrupt are not working.

Kindly send your valuable advise and observation to help solving my problem.

Your kind guidence will be highly appricated.

Regards
Dani
Hi Dani,

You should first understand how the interrupts in ARM are handled.
Wenn the Interrupt Controller asserts the signal, processor loads the program counter with the address 0x18.
There, you must have a branch to your actual IRQ handler.
It looks pretty much like this:

.section .vectors,"a",%progbits

resetVector:
b resetHandler /* Reset */
undefVector:
b UndefinedException /* Undefined instruction */
swiVector:
b SwiException /* Software interrupt !! should not fire!! */
prefetchAbortVector:
b PrefetchAbortException /* Prefetch abort */
dataAbortVector:
b DataAbortException /* Data abort */
reservedVector:
b reservedVector /* Reserved for future use */
irqVector:
b irqHandler /* Interrupt */
fiqVector:
b fiqVector /* FIQ */
From there on, it's all up to you, how you deal with the rest in "irqHandler".

Good luck,
Bekir

________________________________
From: A... [mailto:A...] On Behalf Of ADNAN
Sent: Thursday, January 07, 2010 10:56 PM
To: A...
Subject: [AT91SAM] How to move interrupt vector from 0x0 to some offset

Hello all,

I am newbie to Arm and IAR. I have develope an application using IAR5.30 and AT91SAM7S128 which has interuupt vector starting from 0x0 and rom starting from 0x5000 and when i load this application using jflash utitlity it is working fine.

On the same configuration(address) i have devloped a bootloader application. Now i want to download first application using this bootloader application. As the both bootloader application and the first application has the same interrupt vector address 0x0 so when i download it donot work.

Do i need to move the interrupt vector to some where else, ?

When i moved the interrupt vector of my application to 0x5000 , i.e. just in the start of the application, the interrupt are not working.

Kindly send your valuable advise and observation to help solving my problem.

Your kind guidence will be highly appricated.

Regards
Dani
--- In A..., "ADNAN" wrote:
>
> Hello all,
>
> I am newbie to Arm and IAR. I have develope an application using IAR5.30 and AT91SAM7S128 which has interuupt vector starting from 0x0 and rom starting from 0x5000 and when i load this application using jflash utitlity it is working fine.
>
> On the same configuration(address) i have devloped a bootloader application. Now i want to download first application using this bootloader application. As the both bootloader application and the first application has the same interrupt vector address 0x0 so when i download it donot work.
>
> Do i need to move the interrupt vector to some where else, ?
>
> When i moved the interrupt vector of my application to 0x5000 , i.e. just in the start of the application, the interrupt are not working.
>
> Kindly send your valuable advise and observation to help solving my problem.
>
> Your kind guidence will be highly appricated.
>
> Regards
> Dani
>

Hi Dani,

The SAM7/SAM9 devices have a module called the AIC. You only need to provide an irq_handler that jumps to the AIC_IVR register. The exception vectors can be fixed.

If you really have to have a different set of exception vectors (the only reason I can think of is you are using fiq_handler) then you will have to remap SRAM to address zero and copy the exception vectors from Flash to SRAM.

Regards
Michael

Hi Bakir,

Thanks for your reply.

I am using CMX Rtos for both of my codes, 1, bootloader and other is the actualy application. The cmx handler for IRQ is as follows,
SECTION .text:CODE:NOROOT:REORDER(2)
ARM
IRQ_Wrapper:
SUB LR,LR,#4 ; adj for proper CMX return
STMFD SP!,{R0-R12,LR} ; save the registers

ldr r14, =AT91C_BASE_AIC
ldr r0, [r14, #AIC_IVR] ; get vector address
str r14, [r14, #AIC_IVR]

MRS R9,SPSR ; save the SPSR
STMFD SP!,{R9}
LDR R2,=int_count ; get int_count
MRS R3,CPSR
MOV R4,R3
ORR R4,R4,#Int_Bits ; disable interrupts
MSR CPSR_c,R4
LDRB R1,[R2] ; incr the count
ADD R1,R1,#1
STRB R1,[R2]
MSR CPSR_c,R3 ; restore interrupts

cmp r0, #0 ; handler available?
beq irq_ack ; no, ack interrupt and exit

MSR CPSR_c, #SYS_MODE ; SYS mode, interrupts enabled
STMFD sp!,{R0-R12,lr} ; Save registers.
mov lr,pc
BX R0 ; call specified handler
LDMFD SP!,{R0-R12,lr} ; restore registers.
MSR CPSR_c, #IRQ_MODE|I_Bit|F_Bit ; Switch to IRQ mode, no interrupts

irq_ack
ldr r1, =AT91C_BASE_AIC ; Ack End of Interrupt
str r1, [r1, #AIC_EOICR]

B K_OS_Intrp_Exit
This handler works nice when i place intvec at 0x0 or 0x100000, but stops working when i change address of intvec to 0x5000 or 0x105000 i dont know why,

The cStartup is as follows,

MODULE ?cstartup

SECTION IRQ_STACK:DATA:NOROOT(3)
SECTION FIQ_STACK:DATA:NOROOT(3)
SECTION UND_STACK:DATA:NOROOT(3)
SECTION ABT_STACK:DATA:NOROOT(3)
SECTION SVC_STACK:DATA:NOROOT(3)
SECTION CSTACK:DATA:NOROOT(3)

SECTION .intvec:CODE:NOROOT(2)

PUBLIC __vector
PUBLIC __vector_0x14
PUBLIC __iar_program_start
EXTERN Undef_Wrapper
EXTERN SWI_Wrapper
EXTERN Prefetch_Wrapper
EXTERN Abort_Wrapper
EXTERN IRQ_Wrapper
EXTERN FIQ_Wrapper

ARM

;;
Hi,

You are right. Now tell me what should i do to change the interrupt vector and exception vector address from 0x0 to 0x5000 or 0x105000 so that my application alos works from there.

Regards
Dani
--- In A..., "Icli, Bekir" wrote:
>
> Hi Dani,
>
> It makes perfect sense, that it works when you load it to 0x0 or 0x100000.. Apparently these two memory locations are mirrored.. (means they are pointing to the same physical memory)..
> As I stated in my former mail, you HAVE TO load your exception vectors (with that I mean irq and the other exception vectors) to 0x0..
> In your case:
> __vector:
>
> LDR PC,Reset_Addr ; Reset
> LDR PC,Undefined_Addr ; Undefined instructions
> LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
> LDR PC,Prefetch_Addr ; Prefetch abort
> LDR PC,Abort_Addr ; Data abort
> __vector_0x14:
> DCD 0 ; RESERVED
> LDR PC,IRQ_Addr ; IRQ
> LDR PC,FIQ_Addr ; FIQ
> should be placed to 0x0..
> Because processor does not know where your handler is, he just jumps to 0x18 and continues with execution..
> If you have a debugger, set a break point at 0x18 and you'll see what I mean.. and check after that, if your LDR PC, IRQ_Addr is there.. ;)
>
> Best,
> Bekir
>
> ________________________________
> From: A... [mailto:A...] On Behalf Of ADNAN
> Sent: Friday, January 08, 2010 12:09 PM
> To: A...
> Subject: [AT91SAM] Re: How to move interrupt vector from 0x0 to some offset
>
> Hi Bakir,
>
> Thanks for your reply.
>
> I am using CMX Rtos for both of my codes, 1, bootloader and other is the actualy application. The cmx handler for IRQ is as follows,
> SECTION .text:CODE:NOROOT:REORDER(2)
> ARM
> IRQ_Wrapper:
> SUB LR,LR,#4 ; adj for proper CMX return
> STMFD SP!,{R0-R12,LR} ; save the registers
>
> ldr r14, =AT91C_BASE_AIC
> ldr r0, [r14, #AIC_IVR] ; get vector address
> str r14, [r14, #AIC_IVR]
>
> MRS R9,SPSR ; save the SPSR
> STMFD SP!,{R9}
> LDR R2,=int_count ; get int_count
> MRS R3,CPSR
> MOV R4,R3
> ORR R4,R4,#Int_Bits ; disable interrupts
> MSR CPSR_c,R4
> LDRB R1,[R2] ; incr the count
> ADD R1,R1,#1
> STRB R1,[R2]
> MSR CPSR_c,R3 ; restore interrupts
>
> cmp r0, #0 ; handler available?
> beq irq_ack ; no, ack interrupt and exit
>
> MSR CPSR_c, #SYS_MODE ; SYS mode, interrupts enabled
> STMFD sp!,{R0-R12,lr} ; Save registers.
> mov lr,pc
> BX R0 ; call specified handler
> LDMFD SP!,{R0-R12,lr} ; restore registers.
> MSR CPSR_c, #IRQ_MODE|I_Bit|F_Bit ; Switch to IRQ mode, no interrupts
>
> irq_ack
> ldr r1, =AT91C_BASE_AIC ; Ack End of Interrupt
> str r1, [r1, #AIC_EOICR]
>
> B K_OS_Intrp_Exit
>
> This handler works nice when i place intvec at 0x0 or 0x100000, but stops working when i change address of intvec to 0x5000 or 0x105000 i dont know why,
>
> The cStartup is as follows,
>
> MODULE ?cstartup
>
> SECTION IRQ_STACK:DATA:NOROOT(3)
> SECTION FIQ_STACK:DATA:NOROOT(3)
> SECTION UND_STACK:DATA:NOROOT(3)
> SECTION ABT_STACK:DATA:NOROOT(3)
> SECTION SVC_STACK:DATA:NOROOT(3)
> SECTION CSTACK:DATA:NOROOT(3)
>
> SECTION .intvec:CODE:NOROOT(2)
>
> PUBLIC __vector
> PUBLIC __vector_0x14
> PUBLIC __iar_program_start
> EXTERN Undef_Wrapper
> EXTERN SWI_Wrapper
> EXTERN Prefetch_Wrapper
> EXTERN Abort_Wrapper
> EXTERN IRQ_Wrapper
> EXTERN FIQ_Wrapper
>
> ARM
>
> ;;
Hi,

Actually I want to write a bootloader that will download and execute another placed in some area of ROM.How it can be possible.?

My idea is to have vector table of bootloader to be at the start of
the ROM at 0x0 and of my application to be at the start of rom at 0x5000.
What do you think? I have tried this way bootloader try starting application but application dont works.

Regards
Dani

--- In A..., "Icli, Bekir" wrote:
>
> You cannot change the irq and excp vec. addresses.. I told you they are fixed.. 0x0 thru 0x20
> What you can do is, let the code run from 0x5000 and relocate (simply copy) your vector handlers
> > __vector:
> >
> > LDR PC,Reset_Addr ; Reset
> > LDR PC,Undefined_Addr ; Undefined instructions
> > LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
> > LDR PC,Prefetch_Addr ; Prefetch abort
> > LDR PC,Abort_Addr ; Data abort
> > __vector_0x14:
> > DCD 0 ; RESERVED
> > LDR PC,IRQ_Addr ; IRQ
> > LDR PC,FIQ_Addr ; FIQ
> to 0x0.. that should solve the problem..
>
> Best,
> Bekir
>
> ________________________________
> From: A... [mailto:A...] On Behalf Of ADNAN
> Sent: Friday, January 08, 2010 2:47 PM
> To: A...
> Subject: [AT91SAM] Re: How to move interrupt vector from 0x0 to some offset
> Hi,
>
> You are right. Now tell me what should i do to change the interrupt vector and exception vector address from 0x0 to 0x5000 or 0x105000 so that my application alos works from there.
>
> Regards
> Dani
>
> --- In A..., "Icli, Bekir" wrote:
> >
> > Hi Dani,
> >
> > It makes perfect sense, that it works when you load it to 0x0 or 0x100000.. Apparently these two memory locations are mirrored.. (means they are pointing to the same physical memory)..
> > As I stated in my former mail, you HAVE TO load your exception vectors (with that I mean irq and the other exception vectors) to 0x0..
> > In your case:
> > __vector:
> >
> > LDR PC,Reset_Addr ; Reset
> > LDR PC,Undefined_Addr ; Undefined instructions
> > LDR PC,SWI_Addr ; Software interrupt (SWI/SVC)
> > LDR PC,Prefetch_Addr ; Prefetch abort
> > LDR PC,Abort_Addr ; Data abort
> > __vector_0x14:
> > DCD 0 ; RESERVED
> > LDR PC,IRQ_Addr ; IRQ
> > LDR PC,FIQ_Addr ; FIQ
> > should be placed to 0x0..
> > Because processor does not know where your handler is, he just jumps to 0x18 and continues with execution..
> > If you have a debugger, set a break point at 0x18 and you'll see what I mean.. and check after that, if your LDR PC, IRQ_Addr is there.. ;)
> >
> > Best,
> > Bekir
> >
> > ________________________________
> > From: A... [mailto:A...] On Behalf Of ADNAN
> > Sent: Friday, January 08, 2010 12:09 PM
> > To: A...
> > Subject: [AT91SAM] Re: How to move interrupt vector from 0x0 to some offset
> >
> >
> >
> > Hi Bakir,
> >
> > Thanks for your reply.
> >
> > I am using CMX Rtos for both of my codes, 1, bootloader and other is the actualy application. The cmx handler for IRQ is as follows,
> > SECTION .text:CODE:NOROOT:REORDER(2)
> > ARM
> > IRQ_Wrapper:
> > SUB LR,LR,#4 ; adj for proper CMX return
> > STMFD SP!,{R0-R12,LR} ; save the registers
> >
> > ldr r14, =AT91C_BASE_AIC
> > ldr r0, [r14, #AIC_IVR] ; get vector address
> > str r14, [r14, #AIC_IVR]
> >
> > MRS R9,SPSR ; save the SPSR
> > STMFD SP!,{R9}
> > LDR R2,=int_count ; get int_count
> > MRS R3,CPSR
> > MOV R4,R3
> > ORR R4,R4,#Int_Bits ; disable interrupts
> > MSR CPSR_c,R4
> > LDRB R1,[R2] ; incr the count
> > ADD R1,R1,#1
> > STRB R1,[R2]
> > MSR CPSR_c,R3 ; restore interrupts
> >
> > cmp r0, #0 ; handler available?
> > beq irq_ack ; no, ack interrupt and exit
> >
> > MSR CPSR_c, #SYS_MODE ; SYS mode, interrupts enabled
> > STMFD sp!,{R0-R12,lr} ; Save registers.
> > mov lr,pc
> > BX R0 ; call specified handler
> > LDMFD SP!,{R0-R12,lr} ; restore registers.
> > MSR CPSR_c, #IRQ_MODE|I_Bit|F_Bit ; Switch to IRQ mode, no interrupts
> >
> > irq_ack
> > ldr r1, =AT91C_BASE_AIC ; Ack End of Interrupt
> > str r1, [r1, #AIC_EOICR]
> >
> > B K_OS_Intrp_Exit
> >
> > This handler works nice when i place intvec at 0x0 or 0x100000, but stops working when i change address of intvec to 0x5000 or 0x105000 i dont know why,
> >
> > The cStartup is as follows,
> >
> > MODULE ?cstartup
> >
> > SECTION IRQ_STACK:DATA:NOROOT(3)
> > SECTION FIQ_STACK:DATA:NOROOT(3)
> > SECTION UND_STACK:DATA:NOROOT(3)
> > SECTION ABT_STACK:DATA:NOROOT(3)
> > SECTION SVC_STACK:DATA:NOROOT(3)
> > SECTION CSTACK:DATA:NOROOT(3)
> >
> > SECTION .intvec:CODE:NOROOT(2)
> >
> > PUBLIC __vector
> > PUBLIC __vector_0x14
> > PUBLIC __iar_program_start
> > EXTERN Undef_Wrapper
> > EXTERN SWI_Wrapper
> > EXTERN Prefetch_Wrapper
> > EXTERN Abort_Wrapper
> > EXTERN IRQ_Wrapper
> > EXTERN FIQ_Wrapper
> >
> > ARM
> >
> > ;;
--- In A..., "ADNAN" wrote:
>
> Hello all,
>
> I am newbie to Arm and IAR. I have develope an application using IAR5.30 and AT91SAM7S128 which has interuupt vector starting from 0x0 and rom starting from 0x5000 and when i load this application using jflash utitlity it is working fine.
>
> On the same configuration(address) i have devloped a bootloader application. Now i want to download first application using this bootloader application. As the both bootloader application and the first application has the same interrupt vector address 0x0 so when i download it donot work.
>
> Do i need to move the interrupt vector to some where else, ?
>
> When i moved the interrupt vector of my application to 0x5000 , i.e. just in the start of the application, the interrupt are not working.
>
> Kindly send your valuable advise and observation to help solving my problem.
>
> Your kind guidence will be highly appricated.
>
> Regards
> Dani
>
Although I am not familiar with this device, I believe that there is a 'remap' command, which maps the internal ram to address 0x0000. After reset the internal flash is mapped to address 0x0000. The flash is also always mapped to address 0x100000 & the ram is always mapped to address 0x200000.

Chris.

> I am newbie to Arm and IAR. I have develope an application using
> IAR5.30 and AT91SAM7S128 which has interuupt vector starting from
> 0x0 and rom starting from 0x5000 and when i load this application
> using jflash utitlity it is working fine.

Dani,

This is from the AT91SAM7S manual:

-----

18.3.2.2 Internal Memory Area 0

The first 32 bytes of Internal Memory Area 0 contain the ARM processor
exception vectors, in particular, the Reset Vector at address 0x0.

Before execution of the remap command, the on-chip Flash is mapped
into Internal Memory Area 0, so that the ARM7TDMI reaches an
executable instruction contained in Flash. After the remap command,
the internal SRAM at address 0x0020 0000 is mapped into Internal
Memory Area 0. The memory mapped into Internal Memory Area 0 is
accessible in both its original location and at address 0x0.

-----

In short, the address of 0x0 is hard-coded into the ARM architecture.
If you want to change the vectors that are there, you can do that, as
long as you have SRAM memory in that location (see the following
section, 18.3.3 for details), but you can't change the address from
0x0 to 0x5000. The only reason that 0x00100000 works is because that
is the default address where the internal Flash is replicated. If you
had used 0x00200000 instead, you'd be accessing the default address
for the SRAM and it wouldn't work -- or at least, it wouldn't change
the behavior.

*If* the vectors at 0x0 use the AIC, then you should be able to
reprogram where things go for certain exceptions like the IRQ and
FIQ. Or, if the code at the addresses listed in your listing
(__iar_program_start, IRQ_Wrapper, etc) happens to be in RAM, you
could overwrite these routines with your own routines.

Other than that, you will have to change the 32 bytes of data at
address 0x0, and you can only do that if you've remapped the SRAM.

Greg