Installing interrupts for a custom driver
Alberto Parnaso
pafbat00 at yahoo.es
Fri Apr 4 15:33:15 UTC 2014
Hi Jerry, thank you very much for your response. If I have understand correctly I may have to install the interrupt not with "rtems_interrupt_catch" but using "_CPU_ISR_install_raw_handler". Is that correct? I am out of work now but I will test it on Monday and come back with the results. Thanks indeed!
Alberto.
________________________________
De: Needell Gerald <jerry.needell at unh.edu>
Para: Alberto Parnaso <pafbat00 at yahoo.es>
CC: Jerry Needell <jerry.needell at unh.edu>; RTEMS Send User List <rtems-users at rtems.org>
Enviado: Viernes 4 de abril de 2014 16:25
Asunto: Re: Installing interrupts for a custom driver
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/b12a0260/attachment.html>
More information about the users
mailing list