Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

How to use interrupt?

Altera_Forum
Honored Contributor II
1,481 Views

Hello. 

 

I want to use interrupt from USER_PIO, but I don't know how to use. 

 

I tried this sample code , but it seems that ISR is not executed. 

(I modified two point. 

*definition of CYGNUM_HAL_INTERRUPT_1 

*add printf into ISR ) 

 

What is wrong? 

How can I solve it? 

 

This may be very primitive question, but I'm really newbie. 

Please help me. 

 

Thank you. 

 

#include <cyg/kernel/kapi.h> static cyg_interrupt int1; static cyg_handle_t int1_handle; static cyg_sem_t data_ready; # define CYGNUM_HAL_INTERRUPT_1 USER_PIO_IRQ  //Changed# define CYGNUM_HAL_PRI_HIGH 0 // // Interrupt service routine for interrupt 1. // cyg_uint32 interrupt_1_isr(           cyg_vector_t vector,           cyg_addrword_t data) {   // Block this interrupt from occurring until   // the DSR completes.   cyg_interrupt_mask( vector );     // Tell the processor that we have received   // the interrupt.   cyg_interrupt_acknowledge(vector);     printf("ISR\n");    //changed   // Tell the kernel that chained interrupt processing   // is done and the DSR needs to be executed next.   return(CYG_ISR_HANDLED | CYG_ISR_CALL_DSR); }   //   // Deferred service routine for interrupt 1.   // void interrupt_1_dsr(          cyg_vector_t vector,          cyg_ucount32 count,          cyg_addrword_t data) {   // Signal the thread to run for further processing.   cyg_semaphore_post(&data_ready);     // Allow this interrupt to occur again.   cyg_interrupt_unmask(vector); } // // Main starting point for the application. // void cyg_user_start(void) {   cyg_vector_t int1_vector = CYGNUM_HAL_INTERRUPT_1;   cyg_priority_t int1_priority = CYGNUM_HAL_PRI_HIGH;     // Initialize the semaphore used for interrupt 1.   cyg_semaphore_init(&data_ready,0);     //   // Create interrupt 1.   //   cyg_interrupt_create(      int1_vector,      int1_priority,      0,      &interrupt_1_isr,      &interrupt_1_dsr,      &int1_handle,      &int1);         // Attach the interrupt created to the vector.   cyg_interrupt_attach(int1_handle);     // Unmask the interrupt we just configured.   cyg_interrupt_unmask( int1_vector); }
0 Kudos
13 Replies
Altera_Forum
Honored Contributor II
542 Views

Hello. 

 

Please help me! 

 

I tried "edge" and "level" both. 

But nothing changed. 

 

I&#39;m at a loss. 

Please give me a advise. 

 

Thank you.
0 Kudos
Altera_Forum
Honored Contributor II
542 Views

Can you give me some advice? 

I am really in trouble. 

 

I use StratixII dev kit. 

So, hardware should be OK. 

But I&#39;m not sure how to use interrupt. 

 

Thank you.
0 Kudos
Altera_Forum
Honored Contributor II
542 Views

I&#39;m in the same problem as m_isshiki (and also a newbie http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif ). 

Without eCos, i used my interrupt this way: 

 

static void HandleRising1Interrupt(void *context, alt_u32 id) 

// Do the interrupt routine stuff 

// ... 

 

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_INT_RISING1_BASE, 0); 

 

void main() 

 

IOWR_ALTERA_AVALON_PIO_IRQ_MASK(PIO_INT_RISING1_BASE, 0xF); 

IOWR_ALTERA_AVALON_PIO_EDGE_CAP(PIO_INT_RISING1_BASE, 0); 

 

alt_irq_register(PIO_INT_RISING1_IRQ, (void *) 0, HandleRising1Interrupt); 

 

// The rest of the application 

// ... 

 

My interrupt is defined by the following constants in system.h: 

 

/* 

* pio_int_rising1 configuration 

*/ 

# define PIO_INT_RISING1_NAME "/dev/pio_int_rising1"# define PIO_INT_RISING1_TYPE "altera_avalon_pio"# define PIO_INT_RISING1_BASE 0x02000820# define PIO_INT_RISING1_IRQ 4# define PIO_INT_RISING1_DO_TEST_BENCH_WIRING 0# define PIO_INT_RISING1_DRIVEN_SIM_VALUE 0x0000# define PIO_INT_RISING1_HAS_TRI 0# define PIO_INT_RISING1_HAS_OUT 0# define PIO_INT_RISING1_HAS_IN 1# define PIO_INT_RISING1_CAPTURE 1# define PIO_INT_RISING1_EDGE_TYPE "RISING"# define PIO_INT_RISING1_IRQ_TYPE "EDGE"# define PIO_INT_RISING1_FREQ 70000000 

 

As you can see, it&#39;s defined as a "rising edge" interrupt. 

Now I&#39;m trying to do the same with eCos, using a similar code to that used by m_isshiki, but with no result. 

Could anybody please explain how to handle my interrupt with eCos? 

Thank you very much. 

 

 

--- Quote Start ---  

originally posted by m_isshiki@Dec 13 2005, 08:48 AM 

can you give me some advice? 

i am really in trouble. 

 

i use stratixii dev kit. 

so, hardware should be ok. 

but i&#39;m not sure how to use interrupt. 

 

thank you. 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=11507) 

--- quote end ---  

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
542 Views

i think you can not use printf in ISR. 

 

 

Restricted Environment 

ISRs run in a restricted environment. A large number of the HAL API 

calls are not available from ISRs. For example, accesses to the HAL file 

system are not permitted. As a general rule, when writing your own ISR, 

never include function calls that can block waiting for an interrupt. 

In addition, you should be careful when calling ANSI C standard library 

functions inside of an ISR. No calls should be made using the C standard 

library I/O API, because calling these functions can result in deadlock 

within the system, i.e., the system can become permanently blocked 

within the ISR. In particular, you should not call printf() from within an ISR without careful consideration. If stdout is mapped to a device 

driver that uses interrupts for proper operation, the printf() call can 

deadlock the system waiting for an interrupt that never occurs because 

interrupts are disabled. You can use printf() from within ISRs safely, 

but only if the device driver does not use interrupts..
0 Kudos
Altera_Forum
Honored Contributor II
542 Views

yes, you should try something like  

HAL_WRITE_UINT8(LED_ADDRESS, 0x55); //all uneven LEDs lit up 

if you want printf do so in the DSR, because it is meant to do it there.
0 Kudos
Altera_Forum
Honored Contributor II
542 Views

I&#39;m pretty sure you provided a code snippet, but I don&#39;t see you clearing the IRQ source in either the ISR or DSR which would lead to an infinite IRQ loop. 

 

How are you generating the IRQ? Are you sure you are actually generating an interrupt? 

 

Are you sure you are attaching to the correct vector number? 

 

Finally remember that printf is not re-entrant so if you have prints in regular code and DSR code you will need to protect against simultaneous accesses.
0 Kudos
Altera_Forum
Honored Contributor II
542 Views

I use the interrupt with the button pio like that: 

# include <cyg/hal/io.h> // for IOWR and IORD 

 

unsigned char ledpio;  

cyg_interrupt int_pio; 

cyg_handle_t int_pio_handle; 

 

cyg_uint32 isr_pio( cyg_vector_t vector, 

cyg_addrword_t data){ 

 

ledpio = ledpio|1; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

cyg_interrupt_mask(vector); 

cyg_interrupt_acknowledge(vector); 

 

IOWR(BUTTON_PIO_BASE , 3, 0x00); // Reset the edgecapture register 

 

ledpio = ledpio&~1; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

return(CYG_ISR_HANDLED | CYG_ISR_CALL_DSR); 

 

}  

void dsr_pio( cyg_vector_t vector, 

cyg_ucount32 count, 

cyg_addrword_t data){ 

 

ledpio = ledpio|2; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

cyg_interrupt_unmask(vector); 

 

ledpio = ledpio&~2; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

void cyg_user_start(void) 

cyg_thread_create(..);  

cyg_thread_resume(..); 

 

cyg_interrupt_create( 

BUTTON_PIO_IRQ, // in /include/cyg/hal/system.h  

99, 

55, 

&isr_pio, 

&dsr_pio, 

&int_pio_handle, 

&int_pio); 

 

cyg_interrupt_attach(int_pio_handle); 

cyg_interrupt_unmask( BUTTON_PIO_IRQ); 

 

IOWR(BUTTON_PIO_BASE , 1, 0x00);// PIO in input 

IOWR(BUTTON_PIO_BASE , 3, 0x00);// Reset the edgecapture register  

IOWR(BUTTON_PIO_BASE , 2, 0x01);// unmask bit0 all other masked  

 

 

I use the Altera demo board Cyclone EP1C20F400  

with the pio core descriped in Chapter 7 of the Nios II Processor Reference Handbook
0 Kudos
Altera_Forum
Honored Contributor II
542 Views

Are you sure it is working well, because i am using your programme with just creating one single thread (led glow)but i am getting stuck after applying interrupt ,do youknow why,here is my programme, 

 

 

# include <cyg/hal/io.h> // for IOWR and IORD# include <cyg/kernel/kapi.h> 

unsigned char ledpio;  

cyg_interrupt int_pio; 

cyg_handle_t int_pio_handle; 

 

static void ledglow(cyg_addrword_t data) 

volatile char* a=0x2120890;//writing to the base of ledpio for 111 sequence 

*a=0x7; 

 

cyg_uint32 isr_pio( cyg_vector_t vector ,cyg_addrword_t data) 

 

cyg_interrupt_mask(vector); 

cyg_interrupt_acknowledge(vector); 

 

IOWR(BUTTON_PIO_BASE , 3, 0x00); // Reset the edgecapture register 

ledpio = 0x8; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

return(CYG_ISR_HANDLED); 

}  

void dsr_pio( cyg_vector_t vector,cyg_ucount32 count,cyg_addrword_t data) 

 

 

void cyg_user_start(void) 

{# define STACK_SIZE 0x1000 

static char stack[STACK_SIZE]; 

static cyg_thread thread_data; 

static cyg_handle_t thread_handle; 

 

 

cyg_thread_create(10,ledglow,0,"interrupt test",&stack[0],STACK_SIZE, &thread_handle,&thread_data);  

cyg_thread_resume( thread_handle); 

cyg_interrupt_create(BUTTON_PIO_IRQ, 99,0,&isr_pio,&dsr_pio,&int_pio_handle,&int_pio); 

cyg_interrupt_attach(int_pio_handle); 

cyg_interrupt_unmask( BUTTON_PIO_IRQ); 

IOWR(BUTTON_PIO_BASE , 1, 0x0);// PIO in input 

IOWR(BUTTON_PIO_BASE , 3, 0x00);// Reset the edgecapture register  

IOWR(BUTTON_PIO_BASE , 2, 0x01);// unmask bit0 all other masked  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

--- Quote Start ---  

originally posted by glecordier@Feb 6 2006, 06:31 AM 

i use the interrupt with the button pio like that: 

# include <cyg/hal/io.h> // for iowr and iord 

 

unsigned char ledpio;  

cyg_interrupt int_pio; 

cyg_handle_t  int_pio_handle; 

 

cyg_uint32 isr_pio( cyg_vector_t vector, 

                    cyg_addrword_t data){ 

 

    ledpio = ledpio|1; //  

    iowr (led_pio_base , 0, ledpio); 

 

  cyg_interrupt_mask(vector); 

  cyg_interrupt_acknowledge(vector); 

 

  iowr(button_pio_base , 3, 0x00);            // reset the edgecapture register 

 

    ledpio = ledpio&~1; //  

    iowr (led_pio_base , 0, ledpio); 

 

  return(cyg_isr_handled | cyg_isr_call_dsr); 

 

}  

void dsr_pio( cyg_vector_t vector, 

              cyg_ucount32 count, 

              cyg_addrword_t data){ 

 

    ledpio = ledpio|2; //  

    iowr (led_pio_base , 0, ledpio); 

 

  cyg_interrupt_unmask(vector); 

 

    ledpio = ledpio&~2; //  

    iowr (led_pio_base , 0, ledpio); 

 

void cyg_user_start(void) 

  cyg_thread_create(..);  

  cyg_thread_resume(..); 

 

cyg_interrupt_create( 

    button_pio_irq,            // in /include/cyg/hal/system.h  

    99, 

    55, 

    &isr_pio, 

    &dsr_pio, 

    &int_pio_handle, 

    &int_pio); 

 

  cyg_interrupt_attach(int_pio_handle); 

  cyg_interrupt_unmask( button_pio_irq); 

 

  iowr(button_pio_base , 1, 0x00);// pio in input 

  iowr(button_pio_base , 3, 0x00);// reset the edgecapture register  

  iowr(button_pio_base , 2, 0x01);// unmask bit0 all other masked  

 

 

i use the altera demo board cyclone ep1c20f400  

with the pio core descriped in chapter 7 of the nios ii processor reference handbook 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=12562) 

--- quote end ---  

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
542 Views

It is not exactly the same 

I use the isr and dsr routine 

The source of interrupt is masked in the isr "cyg_interrupt_mask(vector);" 

and unmasked in the dsr " cyg_interrupt_unmask(vector);" 

 

In your code you use only the isr routine 

so mask and unmask in the isr 

or do not mask the source of the interrupt,  

the edgecapture register masks for you until it is reset 

 

the isr could be :  

 

cyg_uint32 isr_pio( cyg_vector_t vector ,cyg_addrword_t data) 

 

// cyg_interrupt_mask(vector);  

cyg_interrupt_acknowledge(vector); 

 

IOWR(BUTTON_PIO_BASE , 3, 0x00); // Reset the edgecapture register 

ledpio = 0x8; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

return(CYG_ISR_HANDLED); 

}
0 Kudos
Altera_Forum
Honored Contributor II
542 Views

okey now i am using ur programme only with creating one thread which will glow led ,so here initially the thread will runnig and when interrupt will come it will go to the isr and then dsr that i can see with the help of leds but after dsr it iwill not come again back to the thread..so here what should be the reason.? 

i am a newbie,please give some suggestions,. 

 

NIrav 

 

# include <cyg/hal/io.h> // for IOWR and IORD# include <cyg/kernel/kapi.h> 

unsigned char ledpio;  

cyg_interrupt int_pio; 

cyg_handle_t int_pio_handle; 

 

cyg_uint32 isr_pio( cyg_vector_t vector, 

cyg_addrword_t data){ 

 

ledpio = 0x1; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

cyg_interrupt_mask(vector); 

cyg_interrupt_acknowledge(vector); 

 

IOWR(BUTTON_PIO_BASE , 3, 0x00); // Reset the edgecapture register 

 

ledpio = 0x8; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

return( CYG_ISR_CALL_DSR); 

 

}  

void dsr_pio( cyg_vector_t vector, 

cyg_ucount32 count, 

cyg_addrword_t data){ 

 

ledpio = 0x7; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

cyg_interrupt_unmask(vector); 

 

ledpio = 0x3; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

static void ledglow(cyg_addrword_t data) 

ledpio = 0x8; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

void cyg_user_start(void) 

# define STACK_SIZE 0x1000 

static char stack[STACK_SIZE]; 

static cyg_thread thread_data; 

static cyg_handle_t thread_handle; 

 

 

cyg_thread_create(10,ledglow,0,"interrupt test",&stack[0],STACK_SIZE, &thread_handle,&thread_data);  

cyg_thread_resume( thread_handle); 

 

 

 

cyg_interrupt_create( 

BUTTON_PIO_IRQ, // in /include/cyg/hal/system.h  

99, 

55, 

&isr_pio, 

&dsr_pio, 

&int_pio_handle, 

&int_pio); 

 

cyg_interrupt_attach(int_pio_handle); 

cyg_interrupt_unmask( BUTTON_PIO_IRQ); 

 

IOWR(BUTTON_PIO_BASE , 1, 0x00);// PIO in input 

IOWR(BUTTON_PIO_BASE , 3, 0x00);// Reset the edgecapture register  

IOWR(BUTTON_PIO_BASE , 2, 0x01);// unmask bit0 all other masked  

 

----------------------------------------------------------------------------------------- 

 

 

 

 

 

 

 

 

 

 

 

 

--- Quote Start ---  

originally posted by glecordier@Feb 8 2006, 04:29 AM 

it is not exactly the same 

i use the isr and dsr routine 

the source of interrupt is masked in the isr "cyg_interrupt_mask(vector);" 

and unmasked in the dsr      " cyg_interrupt_unmask(vector);" 

 

in your code you use only the isr routine 

so mask and unmask in the isr 

or do not mask the source of the interrupt,  

the edgecapture register masks for you until it is reset 

 

the isr could be :  

 

cyg_uint32 isr_pio( cyg_vector_t vector ,cyg_addrword_t data) 

 

// cyg_interrupt_mask(vector);  

cyg_interrupt_acknowledge(vector); 

 

iowr(button_pio_base , 3, 0x00); // reset the edgecapture register 

ledpio = 0x8; //  

iowr (led_pio_base , 0, ledpio); 

 

return(cyg_isr_handled); 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=12626) 

--- quote end ---  

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
542 Views

your thread runs once and then dies 

you need a infinite loop in  

 

static void ledglow(cyg_addrword_t data) 

while (1){ 

ledpio = ledpio^0x10; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

}
0 Kudos
Altera_Forum
Honored Contributor II
542 Views

thanks i can understand,but in the following simple progamme with two thread,highest priority thread runs continuouslly ,it never dies...so here no need for infinite loop..? 

 

# include <cyg/hal/hal_arch.h># include <cyg/kernel/kapi.h># include <cyg/hal/io.h>  

unsigned char ledpio; 

// These numbers depend entirely on your application# define NUMBER_OF_WORKERS 4# define PRODUCER_PRIORITY 18# define WORKER_PRIORITY 17# define PRODUCER_STACKSIZE CYGNUM_HAL_STACK_SIZE_TYPICAL# define WORKER_STACKSIZE (CYGNUM_HAL_STACK_SIZE_MINIMUM + 1024) 

 

static unsigned char producer_stack[PRODUCER_STACKSIZE]; 

static unsigned char worker_stacks[NUMBER_OF_WORKERS][WORKER_STACKSIZE]; 

static cyg_handle_t producer_handle, worker_handles[NUMBER_OF_WORKERS]; 

static cyg_thread producer_thread,worker_threads[NUMBER_OF_WORKERS];  

static void 

producer(cyg_addrword_t data) 

ledpio = 0x8; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

 

static void 

worker(cyg_addrword_t data) 

ledpio = 0x1; //  

IOWR (LED_PIO_BASE , 0, ledpio); 

void cyg_user_start(void) 

{  

 

int i; 

 

cyg_thread_create(PRODUCER_PRIORITY, &producer, 0, "producer", 

producer_stack, PRODUCER_STACKSIZE, 

&producer_handle, &producer_thread); 

cyg_thread_resume(producer_handle); 

for (i = 0; i < NUMBER_OF_WORKERS; i++) { 

cyg_thread_create(WORKER_PRIORITY, &worker, i, "worker", 

worker_stacks, worker_stacksize, 

&(worker_handles), &(worker_threads)); 

cyg_thread_resume(worker_handles); 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

--- Quote Start ---  

originally posted by glecordier@Feb 8 2006, 06:45 AM 

your thread runs once and then dies 

you need a infinite loop in  

 

static void ledglow(cyg_addrword_t data) 

  while (1){ 

    ledpio = ledpio^0x10; //  

    iowr (led_pio_base , 0, ledpio); 

  } 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=12630) 

--- quote end ---  

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
542 Views

 

--- Quote Start ---  

originally posted by glecordier@Feb 6 2006, 06:31 AM 

i use the interrupt with the button pio like that: 

# include <cyg/hal/io.h> // for iowr and iord 

 

unsigned char ledpio;  

cyg_interrupt int_pio; 

cyg_handle_t  int_pio_handle; 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=12562) 

--- quote end ---  

 

--- Quote End ---  

 

 

Thank you, All. 

Especially GLecordier, thank you for showing your code. 

 

Now I can use interrupt as I expect. 

The reasons are 

(1) I tried to use printf in ISR. 

(2) I didn&#39;t unmask the interrupt. 

 

Thank you, very much.
0 Kudos
Reply