Installing interrupts for a custom driver

Needell Gerald jerry.needell at unh.edu
Fri Apr 4 14:25:35 UTC 2014


Alberto,
This may not have been correct- Take a look at the     c/src/lib/libbsp/sparc/leon3/startup/setec.c function from the LEON3 BSP (RTEMS 4.9.2) - attached:
After calling rtems_catch_interrupt the LEON3 interrupt is then enabled - I install my handlers as a type=1  RTEMS interrupt.

I hope that helps
- Jerry

/*  set_vector
 *
 *  This routine installs an interrupt vector on the SPARC simulator.
 *
 *  INPUT PARAMETERS:
 *    handler - interrupt handler entry point
 *    vector  - vector number
 *    type    - 0 indicates raw hardware connect
 *              1 indicates RTEMS interrupt connect
 *
 *  OUTPUT PARAMETERS:  NONE
 *
 *  RETURNS:
 *    address of previous interrupt handler
 *
 *  COPYRIGHT (c) 1989-1998.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  Ported to LEON implementation of the SPARC by On-Line Applications
 *  Research Corporation (OAR) under contract to the European Space 
 *  Agency (ESA).
 *
 *  LEON modifications of respective RTEMS file: COPYRIGHT (c) 1995. 
 *  European Space Agency.
 *
 *  $Id: setvec.c,v 1.2 2006/01/09 10:41:21 ralf Exp $
 */

#include <bsp.h>

rtems_isr_entry set_vector(                   /* returns old vector */
  rtems_isr_entry     handler,                /* isr routine        */
  rtems_vector_number vector,                 /* vector number      */
  int                 type                    /* RTEMS or RAW intr  */
)
{
  rtems_isr_entry previous_isr;
  uint32_t      real_trap;
  uint32_t      source;

  if ( type )
    rtems_interrupt_catch( handler, vector, &previous_isr );
  else 
    _CPU_ISR_install_raw_handler( vector, handler, (void *)&previous_isr );

  real_trap = SPARC_REAL_TRAP_NUMBER( vector );

  if ( LEON_INT_TRAP( real_trap ) ) {
    
    source = LEON_TRAP_SOURCE( real_trap );

    LEON_Clear_interrupt( source );
    LEON_Unmask_interrupt( source );
  }

  return previous_isr;
}

On Apr 4, 2014, at 9:33 AM, Needell Gerald <jerry.needell at unh.edu> wrote:

> Alberto,
> If I recall correctly, rtems_interrupt_catch  installs the new interrupt handler, but does not enable it. You will also need to call rtems_interrupt_enable.
> Good luck!
> Jerry
> 
> On Apr 4, 2014, at 9:12 AM, Alberto Parnaso <pafbat00 at yahoo.es> wrote:
> 
>> Hi, I am newbie in RTEMS and I am trying to install an interrupt into the interrupt controller to be capable of using an APBUART peripheral within a LEON3 based embedded processor. I configure the system so driver manager configures at BSP Start the console and the timer. I do have two APBUART configured in the system and my intention is to use the first one with console/termios driver and the second one with my own driver. Here is a copy the output of "info sys" command:
>> 
>> 
>> <<
>> grmon2> info sys
>>           cpu0          Aeroflex Gaisler  LEON3 SPARC V8 Processor    
>>                   AHB Master 0
>>           ahbjtag0  Aeroflex Gaisler  JTAG Debug Link    
>>                       AHB Master 1
>>           mctrl0    European Space Agency  LEON2 Memory Controller    
>>                       AHB: 00000000 - 20000000
>>                       AHB: 20000000 - 40000000
>>                       AHB: 40000000 - 80000000
>>                       APB: 80000000 - 80000100
>>                       32-bit prom @ 0x00000000
>>                       32-bit static ram: 2 * 512 kbyte @ 0x40000000
>>           apbmst0   Aeroflex Gaisler  AHB/APB Bridge    
>>                   AHB: 80000000 - 80100000
>>           dsu0      Aeroflex Gaisler  LEON3 Debug Support Unit    
>>                    AHB: 90000000 - A0000000
>>           CPU0:  win 8, hwbp 2, V8 mul/div, lddel 1, GRFPU-lite
>>                   stack pointer 0x400ffff0
>>                           icache 1 * 4 kB, 32 B/line 
>>                   dcache 1 * 4 kB, 32 B/line 
>>           uart0        Aeroflex Gaisler  Generic UART    
>>                   APB: 80000100 - 80000200
>>                   IRQ: 2
>>                   Baudrate 38343
>>           irqmp0    Aeroflex Gaisler  Multi-processor Interrupt Ctrl.    
>>                   APB: 80000200 - 80000300
>>           gptimer0  Aeroflex Gaisler  Modular Timer Unit    
>>                   APB: 80000300 - 80000400
>>                   IRQ: 8
>>                   8-bit scalar, 2 * 32-bit timers, divisor 50
>>           uart1     Aeroflex Gaisler  Generic UART    
>>                   APB: 80000900 - 80000A00
>>                   IRQ: 3
>>                   Baudrate 38343
>>           gpio0     Aeroflex Gaisler  General Purpose I/O port    
>>                   APB: 80000B00 - 80000C00
>> >>
>> 
>> I have wrote a testing app to check if both UARTs work and also to try to install a handler for RX on the second UART. Here is my code:
>> 
>> <<
>> #include <rtems.h>
>> 
>> rtems_task Init( rtems_task_argument argument);    /* forward declaration needed */
>> 
>> /* configuration information */
>> #define CONFIGURE_INIT
>> #include <bsp.h> /* for device driver prototypes */
>> 
>> 
>> #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
>> #define CONFIGURE_MAXIMUM_TASKS             4
>> #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
>> #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
>> #include <rtems/confdefs.h>
>> 
>> #include <stdio.h>
>> #include <stdlib.h>
>> 
>> #include <sys/types.h>
>> #include <sys/stat.h>
>> #include <unistd.h>
>> #include <errno.h>
>> #include <apbuart.h>
>> 
>> // Global Variable to check if Interrupt has been signaled.
>> unsigned char uc_intr_flag;
>> 
>> // Interrupt handler for APBUART peripheral 
>> void UARTInterruptHandler ()
>> {
>>     uc_intr_flag = 1;
>> }
>> 
>> rtems_task Init (rtems_task_argument ignored)
>> {
>> 
>>     int i;
>>     rtems_status_code ret_status;
>>     rtems_isr_entry old_handler;
>>     volatile int *apbuart1 = (int*)0x80000900;
>>     volatile int aux;
>> 
>>     // Reset Interrupt Flag
>>     uc_intr_flag = 0;
>> 
>>     printf("APB UART TEST with Interrupts\n");
>> 
>>     aux = apbuart1[1];
>>     printf("APBUART1 STATUS: 0x%08X\n", aux);
>>     aux = apbuart1[2];
>>     printf("APBUART1 CONTROL: 0x%08X\n", aux);
>>     
>>     // Install UARTInterruptHandler at vector number 3 
>>     ret_status = rtems_interrupt_catch(
>>             (rtems_isr_entry)UARTInterruptHandler,
>>             (rtems_vector_number)3,
>>             &old_handler);
>>     switch (ret_status)
>>     {
>>            case RTEMS_SUCCESSFUL :
>>               printf("rtems_interrupt_catch: OK. New Interrupt installed for IRQ 3 - APBUART 2.\n");
>>           break ;
>> 
>>            case RTEMS_INVALID_NUMBER :
>>               printf("rtems_interrupt_catch: RTEMS_INVALID_NUMBER.\n");
>>               break ;
>> 
>>            case RTEMS_INVALID_ADDRESS :
>>                printf("rtems_interrupt_catch: RTEMS_INVALID_ADDRESS.\n");
>>                break ;
>> 
>>         default :
>>               printf("rtems_interrupt_catch: Unknown error.\n");
>>               break ;
>>     }
>> 
>>     // Tell uart hardware to initialize directly
>>     /* Enable receiver (with interrupts) & Transmitter */
>>     apbuart1[2] = APBUART_CTRL_RE | APBUART_CTRL_TE | APBUART_CTRL_RI;
>>     aux = apbuart1[1];
>>     printf("UART1 STATUS: 0x%02X\n", aux);
>>     aux = apbuart1[2];
>>     printf("UART1 CONTROL: 0x%08X\n", aux);
>> 
>>     // Write a character though APBUART1 to test it
>>     apbuart1[0] = 0xD8;
>> 
>>     while (1)
>>     {       // Perform some active wait time
>>         for (i = 2000000; i > 0; i--);
>> 
>>         printf("Hello World\n");
>>         apbuart1[0] = 0xD8;
>>         // If interrupt received, read from APBUART
>>         if (uc_intr_flag == 1)
>>         {
>>             uc_intr_flag = 0;
>>             aux = apbuart1[0];
>>             printf("Interrupt received from UART: data = %X\n", aux);
>>         }
>>     }
>> 
>>     exit (0);
>> }
>> >>
>> 
>> First UART (ie. debug UART) works fine and output data through STDOUT properly. Data sent through second UART is received also by another external terminal, and in other test I have been capable of receiving too. However UARTInterruptHandler is never signaled, thus I guess I am missing something with the interrupt instalation. 
>> 
>> Could any one see anything missing in this code? I would very much appreciate some help. Any clue on how to properly use interrupts will help me a lot!
>> 
>> Thanks!
>> Alberto.
>> 
>> _______________________________________________
>> rtems-users mailing list
>> rtems-users at rtems.org
>> http://www.rtems.org/mailman/listinfo/rtems-users
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20140404/a7fa786d/attachment.html>


More information about the users mailing list