Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

IRQ / FIQ status register general question.

IRQ / FIQ status register general question.

2006-01-27 by Dmitry Diky

Fellows,

In my application it is convenient to switch between IRQ and FIQ in some 
interrupt service routine.
As I know FIQ mode used banked r8-r14 registers and no registers have to be 
saved on stack (providing I want to have the things working :)

So, when an IRQ interrupt occurs, I immediately enter to FIQ, then process my 
interrupt request and then exit..

xxx_IRS:
	msr cpsr_c, #MODE_FIQ|FIQ_BIT|IRQ_BIT	; @ switch to FIQ with ints dsbld.
	... ISR code ...
	msr cpsr_c, #MODE_IRQ|FIQ_BIT|IRQ_BIT	; @ back to IRQ mode
	sub pc,lr,#4						; @ return from interrupt

Everything seems to be working except I am not sure what happens to CPSR of 
the user mode. As I understand, when nIRQ is asserted, CPSR being copied to 
SPSR_irq and on IRQ exit SPSR_irq -> CPSR_usr. But what happens when I switch 
to FIQ and back? Does the CPU core copy cpsr_irq to spsr_fiq and back 
or... ??? In a few words: will be user's CPSR kept alive with such IRQ 
servicing scheme?

Thanks,
Dmitry.

Re: [lpc2000] IRQ / FIQ status register general question.

2006-01-27 by Sten

Dmitry Diky wrote:
> Fellows,
> 
> In my application it is convenient to switch between IRQ and FIQ in some 
> interrupt service routine.
> As I know FIQ mode used banked r8-r14 registers and no registers have to be 
> saved on stack (providing I want to have the things working :)
> 
> So, when an IRQ interrupt occurs, I immediately enter to FIQ, then process my 
> interrupt request and then exit..
> 
> xxx_IRS:
> 	msr cpsr_c, #MODE_FIQ|FIQ_BIT|IRQ_BIT	; @ switch to FIQ with ints dsbld.
> 	... ISR code ...
> 	msr cpsr_c, #MODE_IRQ|FIQ_BIT|IRQ_BIT	; @ back to IRQ mode
> 	sub pc,lr,#4						; @ return from interrupt
> 
> Everything seems to be working except I am not sure what happens to CPSR of 
> the user mode. As I understand, when nIRQ is asserted, CPSR being copied to 
> SPSR_irq and on IRQ exit SPSR_irq -> CPSR_usr. But what happens when I switch 
> to FIQ and back? Does the CPU core copy cpsr_irq to spsr_fiq and back 
> or... ??? In a few words: will be user's CPSR kept alive with such IRQ 
> servicing scheme?
> 
> Thanks,
> Dmitry.
> 

Hi Dimitry,

Uuuuuuuuuhhhhhhh, ... Are you sure you know what you are doing?
FIQ- and IRQ-mode are dedicated modes for the two types of interrupts (FIQ and IRQ) ARM have. If you
define an interrupt as a fast-IRQ (FIQ) than you have the goal that the system automatically enters
FIQ mode and will save some additional registers when this interrupt occurs. If you define an
(normal) IRQ your system will enter IRQ-mode. In opposite to other architectures ARM can perform a
kind of hardware context switch by switching to another mode. In general you should NEVER change
those modes manually in your software! These modes are changed by core itself when raising dedicated
exceptions. There are only a few exceptions where to change it manually: e.g. after startup has
finished you can switch form supervisor-mode to system-mode or user-mode before you enter
application code. But in user-mode you will have only restricted access to system resources. This
mode is dedicated for use with a RTOS which is protecting OS-layer from (evil) user-land applications.

  Sten

-- 
/************************************************
 Do you need a tiny and efficient real time
 operating system (RTOS) with a preemtive
 multitasking for LPC2000 or AT91SAM7?

   http://nanortos.net-attack.de/

 Or some open-source tools and code for LPC2000?

   http://www.net-attack.de/

************************************************/

Re: [lpc2000] IRQ / FIQ status register general question.

2006-01-27 by Dmitry Diky

Hi Sten,

> Uuuuuuuuuhhhhhhh, ... Are you sure you know what you are doing?

Well, I am pretty sure...
To be precise I got two possible interrupt requests: - timer and SPI ones.
I assign timer interupt to IRQ and SPI to FIQ. However, on timer interrupt, 
the SPI transfer should be initiated.

To save some interrupt processing time I initiate timer and SPI register, the 
switch to FIQ mode (via swi interrupt) and assign some peripherial regs to 
FIQ registers r8_fiq, r8_fiq, ... So, in FIQ mode I do not have to load 
complicated values (0xe0020000 for example) to the register.

However, in timer ISR I have to manipulate with timer registers and SPI 
registers which are already assigned to _fiq registers... So, why not to 
switch to FIQ mode in IRQ ISR providing no other interrupts can occur during 
IRQ processing?

> FIQ- and IRQ-mode are dedicated modes for the two types of interrupts (FIQ
> and IRQ) ARM have. If you define an interrupt as a fast-IRQ (FIQ) than you
> have the goal that the system automatically enters FIQ mode and will save
> some additional registers when this interrupt occurs.

Yes, thats why I assign FIQ to SPI - I need a counter which I keep in a 
register and therefore do not have to load it from memory...
The overall process is the following:

fiq_isr:	(located at 0x1c)
		... just maipulate with SPI
		... uses r8_fiq... r13_fiq as general-purpose registers
		
		sub pc, lr, #4	<- exit from FIQ

timer_isr:	(called via vectored interrupt controller)
		msr cpsr_c, #mode_fiq|i_bit|f_bit
		... manipulate with timer
		... start SPI transfer
		... uses r8_fiq...r13_fiq
		msr cpsr_c, #mode_irq|i_bit|f_bit

		sub pc, lr, #4




I am pretty sure, that timer interrupts can occur only when CPU is in idle 
state, except when UART transfer is in progress. However, I do not facilitate 
nested interrupts, so no problems with cpsr_c should happen...

The question is: will be cpsr_of-current-mode copied to SPSR when I manually 
switch the modes?

Thanks,
Dmitry.

Re: IRQ / FIQ status register general question.

2006-01-27 by Guillermo Prandi

Hi, Dmitry. I am no ARM7 expert, but perhaps what you're looking for 
is this:

xxx_IRS:
        msr cpsr_c, #MODE_FIQ|FIQ_BIT|IRQ_BIT   ; @ switch to FIQ 
with ints dsbld.
        ... ISR code ...
        msr cpsr_c, #MODE_IRQ|FIQ_BIT|IRQ_BIT   ; @ back to IRQ mode
        subs pc,lr,#4                           ; @ return from 
interrupt

(Notice the use of SUBS instead of SUB). The S flag to SUB tells the 
µP to restore the saved mode register, thus switching back to user 
mode.

Of course this will work only if you don't nest FIQs or IRQs.

Guille

--- In lpc2000@yahoogroups.com, Dmitry Diky <ddiky@a...> wrote:
>
> Fellows,
> 
> In my application it is convenient to switch between IRQ and FIQ in 
some 
> interrupt service routine.
> As I know FIQ mode used banked r8-r14 registers and no registers 
have to be 
> saved on stack (providing I want to have the things working :)
> 
> So, when an IRQ interrupt occurs, I immediately enter to FIQ, then 
process my 
> interrupt request and then exit..
> 
> xxx_IRS:
> 	msr cpsr_c, #MODE_FIQ|FIQ_BIT|IRQ_BIT	; @ switch to FIQ 
with ints dsbld.
> 	... ISR code ...
> 	msr cpsr_c, #MODE_IRQ|FIQ_BIT|IRQ_BIT	; @ back to IRQ mode
> 	sub pc,lr,#4						; @ 
return from interrupt
> 
> Everything seems to be working except I am not sure what happens to 
CPSR of 
> the user mode. As I understand, when nIRQ is asserted, CPSR being 
copied to 
> SPSR_irq and on IRQ exit SPSR_irq -> CPSR_usr. But what happens 
when I switch 
> to FIQ and back? Does the CPU core copy cpsr_irq to spsr_fiq and 
back 
> or... ??? In a few words: will be user's CPSR kept alive with such 
IRQ 
Show quoted textHide quoted text
> servicing scheme?
> 
> Thanks,
> Dmitry.
>

Re: IRQ / FIQ status register general question.

2006-01-27 by Guillermo Prandi

> The question is: will be cpsr_of-current-mode copied to SPSR when I 
manually 
> switch the modes?

According to the Addison Wesley's ARM Architecture Reference Manual, 
MSR will update your choice of CPSR or SPSR but not BOTH. However, 
changing modes will switch registers, so when CPSR is updated, SPSR 
will be switched to the new mode's.

You should not exit an IRQ or FIQ with SUB but with SUBS in order to 
return to the previous (user or other) mode. Otherwise, you would be 
leaving the IRQ still in IRQ mode.

The way I see it:

; Scenario: IRQ triggered when in user mode
; The µP saves user mode CPSR to spsr@IRQ, switches to IRQ mode 
(switching registers) and jumps to xxx_IRS
; spsr@FIQ has some unknown value
xxx_IRS:
msr cpsr_c, #MODE_FIQ|FIQ_BIT|IRQ_BIT ; @ switch to FIQ with ints 
dsbld.
; both spsr@FIQ and spsr@IRQ remain unchanged; you've got now 
spsr@FIQ visible, which has garbage (i.e., a previous unpredictable 
value)
... ISR code ...
msr cpsr_c, #MODE_IRQ|FIQ_BIT|IRQ_BIT ; @ back to IRQ mode
; both spsr@FIQ and spsr@IRQ remain unchanged; you've got now 
spsr@IRQ visible, which has the user mode CPSR
subs pc,lr,#4 ; @ return from interrupt
; subs copies spsr@IRQ to CPSR and now everybody is happy ;)


Guille

--- In lpc2000@yahoogroups.com, Dmitry Diky <ddiky@a...> wrote:
>
> Hi Sten,
> 
> > Uuuuuuuuuhhhhhhh, ... Are you sure you know what you are doing?
> 
> Well, I am pretty sure...
> To be precise I got two possible interrupt requests: - timer and 
SPI ones.
> I assign timer interupt to IRQ and SPI to FIQ. However, on timer 
interrupt, 
> the SPI transfer should be initiated.
> 
> To save some interrupt processing time I initiate timer and SPI 
register, the 
> switch to FIQ mode (via swi interrupt) and assign some peripherial 
regs to 
> FIQ registers r8_fiq, r8_fiq, ... So, in FIQ mode I do not have to 
load 
> complicated values (0xe0020000 for example) to the register.
> 
> However, in timer ISR I have to manipulate with timer registers and 
SPI 
> registers which are already assigned to _fiq registers... So, why 
not to 
> switch to FIQ mode in IRQ ISR providing no other interrupts can 
occur during 
> IRQ processing?
> 
> > FIQ- and IRQ-mode are dedicated modes for the two types of 
interrupts (FIQ
> > and IRQ) ARM have. If you define an interrupt as a fast-IRQ (FIQ) 
than you
> > have the goal that the system automatically enters FIQ mode and 
will save
> > some additional registers when this interrupt occurs.
> 
> Yes, thats why I assign FIQ to SPI - I need a counter which I keep 
in a 
> register and therefore do not have to load it from memory...
> The overall process is the following:
> 
> fiq_isr:	(located at 0x1c)
> 		... just maipulate with SPI
> 		... uses r8_fiq... r13_fiq as general-purpose 
registers
> 		
> 		sub pc, lr, #4	<- exit from FIQ
> 
> timer_isr:	(called via vectored interrupt controller)
> 		msr cpsr_c, #mode_fiq|i_bit|f_bit
> 		... manipulate with timer
> 		... start SPI transfer
> 		... uses r8_fiq...r13_fiq
> 		msr cpsr_c, #mode_irq|i_bit|f_bit
> 
> 		sub pc, lr, #4
> 
> 
> 
> 
> I am pretty sure, that timer interrupts can occur only when CPU is 
in idle 
> state, except when UART transfer is in progress. However, I do not 
facilitate 
> nested interrupts, so no problems with cpsr_c should happen...
> 
> The question is: will be cpsr_of-current-mode copied to SPSR when I 
manually 
Show quoted textHide quoted text
> switch the modes?
> 
> Thanks,
> Dmitry.
>

Re: [lpc2000] IRQ / FIQ status register general question.

2006-01-27 by Sten

Dmitry Diky wrote:
> Hi Sten,
> 
> 
>>Uuuuuuuuuhhhhhhh, ... Are you sure you know what you are doing?
> 
> 
> Well, I am pretty sure...
> To be precise I got two possible interrupt requests: - timer and SPI ones.
> I assign timer interupt to IRQ and SPI to FIQ. However, on timer interrupt, 
> the SPI transfer should be initiated.
> 

Hi Dimitry,

but this is not what the guys from ARM intended. It seems to be working hack for your special case. ;-)

-- 
/************************************************
 Do you need a tiny and efficient real time
 operating system (RTOS) with a preemtive
 multitasking for LPC2000 or AT91SAM7?

   http://nanortos.net-attack.de/

 Or some open-source tools and code for LPC2000?

   http://www.net-attack.de/

************************************************/

Re: IRQ / FIQ status register general question.

2006-01-28 by jayasooriah

As you are entering and leaving the exception in the same mode, and
given you are allowed to change modes when you have the privilege, I
do not see anything wrong with your code.

I do someting similar to stash context informatinon in FIQ bank (so
that the code is RAM independent) and had no problems with exceptions,
although I have no FIQ/IRQ type of exceptions.

--- In lpc2000@yahoogroups.com, Dmitry Diky <ddiky@a...> wrote:
> Everything seems to be working except I am not sure what happens to
CPSR of 
> the user mode. As I understand, when nIRQ is asserted, CPSR being
copied to 
> SPSR_irq and on IRQ exit SPSR_irq -> CPSR_usr. But what happens when
I switch 
Show quoted textHide quoted text
> to FIQ and back? Does the CPU core copy cpsr_irq to spsr_fiq and back 
> or... ??? In a few words: will be user's CPSR kept alive with such IRQ 
> servicing scheme?

RE: [lpc2000] IRQ / FIQ status register general question.

2006-01-31 by Bruce Paterson

> Dmitry Diky wrote:
> > As I know FIQ mode used banked r8-r14 registers and no 
> registers have 

Steb replied:
> Uuuuuuuuuhhhhhhh, ... Are you sure you know what you are doing?
> ..... (normal) IRQ your system will enter IRQ-mode. In opposite to 
> other architectures ARM can perform a kind of hardware 
> context switch by switching to another mode. In general you 
> should NEVER change those modes manually in your software! 

I haven't used an FIQ myself yet so excuse the possibly silly question.
Surely if you are using an alternate register set in an FIQ, at some
early stage, somewhere, you'd want to initialise those registers (eg.
Setup a pointer at the start of a circular buffer). How would you
achieve this if you aren't able to/allowed to switch modes manually ?

Cheers,
Bruce

Re: [lpc2000] IRQ / FIQ status register general question.

2006-01-31 by Sten

Bruce Paterson wrote:
>>Dmitry Diky wrote:
>>
>>>As I know FIQ mode used banked r8-r14 registers and no 
>>
>>registers have 
> 
> 
> Steb replied:
> 
>>Uuuuuuuuuhhhhhhh, ... Are you sure you know what you are doing?
>>..... (normal) IRQ your system will enter IRQ-mode. In opposite to 
>>other architectures ARM can perform a kind of hardware 
>>context switch by switching to another mode. In general you 
>>should NEVER change those modes manually in your software! 
> 
> 
> I haven't used an FIQ myself yet so excuse the possibly silly question.
> Surely if you are using an alternate register set in an FIQ, at some
> early stage, somewhere, you'd want to initialise those registers (eg.
> Setup a pointer at the start of a circular buffer). How would you
> achieve this if you aren't able to/allowed to switch modes manually ?

Hi Bruce,

it is allowed to switch context manually, during starup for example. But I think it is not
recommended to do this in application code. You must initialize all modes you want to use (FIQ, IRQ,
USR, SVR, SYS) or modes that might be used (for you) (ABT, UND) during startup.

  Sten

-- 
/************************************************
 Do you need a tiny and efficient real time
 operating system (RTOS) with a preemtive
 multitasking for LPC2000 or AT91SAM7?

   http://nanortos.net-attack.de/

 Or some open-source tools and code for LPC2000?

   http://www.net-attack.de/

************************************************/

Re: IRQ / FIQ status register general question.

2006-01-31 by jayasooriah

When doing data transfers on FIQ and using FIQ bank (eg a pointers and
a byte count), then you have no choice but to set up, and/or examine
these in "application code" (meaning code not running in FIQ context).

Often completion of transfer triggers a (lower priority) IRQ, and in
this case, the code running in IRQ context peeks/pokes registers in
the FIQ bank by switching to FIQ and then back to IRQ.

Summary: there is nothing wrong at all with switching banks in any
code segment (not just in startup code) provided you leave the
exception in the same state that you entered in.  (You can leave in a
different mode if you know what you are doing but I am not sure the
behaviour can be generalised across all ARM implementations.)

--- In lpc2000@yahoogroups.com, Sten <list@n...> wrote:
Show quoted textHide quoted text
> it is allowed to switch context manually, during starup
> for example. But I think it is not recommended to do this
> in application code. You must initialize all modes you
> want to use (FIQ, IRQ, USR, SVR, SYS) or modes that might
> be used (for you) (ABT, UND) during startup.

Re: [lpc2000] Re: IRQ / FIQ status register general question.

2006-02-01 by Sten

Hi,

in your case it works. No doubt!

jayasooriah wrote:
> When doing data transfers on FIQ and using FIQ bank (eg a pointers and
> a byte count), then you have no choice but to set up, and/or examine
> these in "application code" (meaning code not running in FIQ context).
This is a special case in which you must setup FIQ state to use it.

> 
> Often completion of transfer triggers a (lower priority) IRQ, and in
> this case, the code running in IRQ context peeks/pokes registers in
> the FIQ bank by switching to FIQ and then back to IRQ.
Ok, I think I understood! You want to modify your special pointers/counters, used by the FIQ, from a
IRQ for example. This is quite tricky!

> 
> Summary: there is nothing wrong at all with switching banks in any
> code segment (not just in startup code) provided you leave the
> exception in the same state that you entered in.  (You can leave in a
> different mode if you know what you are doing but I am not sure the
> behaviour can be generalised across all ARM implementations.)
> 
> --- In lpc2000@yahoogroups.com, Sten <list@n...> wrote:
> 
>>it is allowed to switch context manually, during starup
>>for example. But I think it is not recommended to do this
>>in application code. You must initialize all modes you
>>want to use (FIQ, IRQ, USR, SVR, SYS) or modes that might
>>be used (for you) (ABT, UND) during startup.
> 


-- 
/************************************************
 Do you need a tiny and efficient real time
 operating system (RTOS) with a preemtive
 multitasking for LPC2000 or AT91SAM7?

   http://nanortos.net-attack.de/

 Or some open-source tools and code for LPC2000?

   http://www.net-attack.de/

************************************************/

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.