Installing interrupt handlers on ARM7TDMI

Charles Steaderman charlies at poliac.com
Tue Jul 16 21:11:35 UTC 2002



Jay Monkman wrote:

>The interrupt handling that is in the current snapshots is broken. It
>doesn't save all the registers it needs to. I have new code that I
>think works (for interrupt handling - it has other problems). I'm
>working on a patch right now, and will send it out this afternoon.
>  
>
I would agree with this. I was able to "grossly" hack things to get 
clock interrupts to occur, but time based task switching doesn't seem to 
work.

>The default handler (_ISR_Handler) is in
>libbsp/arm/shared/irq/irq_asm.S, and is installed in
>libbsp/arm/shared/irq/irq_init.c 
>
>Here's how the ARM vectors get installed:
>   _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _ISR_Handler, NULL);
>
I traced the implementation of _CPU_ISR_install_vector and it places 
_ISR_Handler in memory at an offset of ARM_EXCEPTION_IRQ (0x18) + number 
of interrupt sources (correctly 8 in this case) * 4 (0x20). This places 
_ISR_Handler at 0x38 NOT 0x18. In addition, it places the address of 
_ISR_Handler at 0x38, NOT a brach to _ISR_Handler instruction. I still 
need a branch instruction at 0x18 which would somehow load the address 
at 0x38 and jump there. I got things to work by declaring an exception 
table in my start.S file and copying it to address 0x0 in my bsp_init 
function. It is a huge hack, and very non-robust, but I wanted to get 
**something** working. I will look into a better way to dynamically get 
a vector table into remapped ram at address 0x0 later (unless someone 
else knows a neat way to do it :-)).

>
>_ISR_Handler is the function that will call the BSP specific handler
>for every IRQ assertion.
>
>Here's an example of installing the handler for one of the muxed IRQ
>sources:
>/********************************************************************/
>static void clock_isr_on(const rtems_irq_connect_data *unused);
>static void clock_isr_off(const rtems_irq_connect_data *unused);
>static int clock_isr_is_on(const rtems_irq_connect_data *irq);
>
>rtems_irq_connect_data clock_isr_data = {INT_TM1,
>                                   Clock_isr,
>                                   clock_isr_on,
>                                   clock_isr_off,
>                                   clock_isr_is_on,
>                                   3,
>                                   0 };
>
>static void clock_isr_on(const rtems_irq_connect_data *unused)
>{
>    printk("clock_isr_on\n");
>}
>
>static void clock_isr_off(const rtems_irq_connect_data *unused)
>{
>    printk("clock_isr_off\n");
>}
>
>static int clock_isr_is_on(const rtems_irq_connect_data *irq)
>{
>    printk("clock_isr_is_on\n");
>    return 1;
>}
>/********************************************************************/
>
>Most of the fields in rtems_irq_connect_data are ignored. I believe
>the only important ones are the the first two (INT_TM1 and Clock_isr)
>in this example.
>  
>
>I think the vegaplus BSP is a better example for interrupts than the
>others.
>  
>
I "borrowed" the bsp specific assembly interrupt code from the vegaplus 
bsp, although it looks as though it is using an external PIC. In 
addition, it performs a number of switches from INT mode to SVC mode and 
back again which didn't seem to be very robust in my test case. I took 
out the mode switches and things seemed to run better, but still no time 
based task switches. Knowing now that the interrupt handling doesn't 
properly save all states, perhaps that is more of the problem. It the 
mode switching **really** necessary? Is it primarily for stack management?

>
>  
>
Thanks for the update. I will try to paste some of the hair back in my 
head, and wait patiently for patched interrupt handing code.

- Charlie

-- 
Charlie Steaderman
charlies at poliac.com
VP Engineering
Poliac Research Corporation
Phone: 952.707.6245
Cel: 612.242.6364






More information about the users mailing list