Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Altera_Forum
Honored Contributor I
1,074 Views

questions about nios interrupts

hi everyone. 

there are 2 interrupts in my project  

interrupt A has lower poriority than interrupt B 

i think if the interrupt B comes when the code is executing the interrupt A's handler, the code should go to the interrupt B's handler.the code return to the interrupt A's handler after finish the interrupt B's handler. 

 

 

but in my project, in debug mode, i set a breakpoint at the begining of interrupt A's handler, i resume the code (F8), then i let interrupt A happen, so the code stop at the break point, then i let interrupt B happen, i press F5, let the code run single step, the code did not go to interrupt B's handler, and i find the code go to interrupt B's handler untill finish the interrupt A's handler. 

 

 

why this happed? 

 

 

 

 

 

 

 

 

 

 

 

 

 

# include "alt_types.h"# include "altera_avalon_pio_regs.h"# include "sys/alt_irq.h"# include "system.h"# include <stdio.h># include <unistd.h> 

 

 

alt_u8 find_zero_counter=0;  

alt_32 zero_position[255]={0};  

 

 

void ft245_interrupt() //lower poriority interrupt 

// 

alt_u32 i=0; 

alt_u16 j=0; 

alt_u16 a=0; 

i=alt_irq_enabled();// 

j=IORD_16DIRECT(FT245_IRQ_1_0_BASE,0x0); // 

a=(j|0x4000); 

IOWR_16DIRECT(FT245_IRQ_1_0_BASE,0,0xc000); //clear interrupt 

for(;;) 

 

 

j=IORD_16DIRECT(FT245_IRQ_1_0_BASE,0x0); 

if ((j&0xc000)==0) break; 

 

 

 

 

IOWR_16DIRECT(FT245_IRQ_1_0_BASE,0,0x8000); //tell ft245_driver to read from ft245 

void encoder_find_zero() //higher poriority interrupt 

alt_u32 i=0; 

alt_32 xifen=0,forward=0,backward=0; 

i=alt_irq_enabled();// 

IOWR_32DIRECT(INC_CALC_0_BASE,0,0xc0000000); // clear interrupt 

while(1) 

i=IORD_32DIRECT(INC_CALC_0_BASE,0);// 

if ((i&0xf0000000)==0x0) break; // 

IOWR_32DIRECT(INC_CALC_0_BASE,0,0x60000000); // prepare S_inc_xifen_at_zero_reg, S_inc_forward_at_zero_reg,S_inc_backward_at_zero_reg, return S_inc_xifen_at_zero_reg,nios should read after interrupt 

while(1) 

xifen=IORD_32DIRECT(INC_CALC_0_BASE,0);// 

if ((xifen&0xf0000000)==0x0) break; // 

if ((i&0xf0000000)==0xf0000000) break;// 

 

 

int main() 

alt_u32 i=0; 

alt_u32 error_signal_address=0; 

alt_u16 j=0; 

alt_u32 moire_sin[256]={0}; 

alt_u32 moire_cos[256]={0}; 

alt_32 xifen=0,forward=0,backward=0,position=-5; 

alt_u16 a=0; 

i=alt_irq_enabled(); 

//register interrupt handler of lower poriority interrupt 

alt_ic_isr_register (FT245_IRQ_1_0_IRQ_INTERRUPT_CONTROLLER_ID,  

FT245_IRQ_1_0_IRQ, 

ft245_interrupt, 

NULL, 

NULL); 

//register interrupt handler of higher poriority interrupt 

alt_ic_isr_register (INC_CALC_0_IRQ_INTERRUPT_CONTROLLER_ID, 

INC_CALC_0_IRQ, 

encoder_find_zero, 

NULL, 

NULL); 

//enable interrupt 

j=alt_ic_irq_enable(FT245_IRQ_1_0_IRQ_INTERRUPT_CONTROLLER_ID,FT245_IRQ_1_0_IRQ);// 

j=alt_ic_irq_enable(INC_CALC_0_IRQ_INTERRUPT_CONTROLLER_ID,INC_CALC_0_IRQ);// 

i=alt_irq_enabled(); 

IOWR_16DIRECT(FT245_IRQ_1_0_BASE,0,0x8000); //tell ft245_driver to read from ft245 

while (1) 

 

 

return 0; 

}
0 Kudos
2 Replies
Altera_Forum
Honored Contributor I
80 Views

i find the  

alt_irq_interruptible(); 

alt_irq_non_interruptible(); 

can be used to make nested interrupts 

 

but during debug, i find that only if the higher poriority interrupt happpens before alt_irq_interruptible(), then the code goto higher poriority interrupt handler. 

but if the higher poriority interrupt happpens after alt_irq_interruptible(), then the code still in the lower poriority interrupt handler . 

 

can the nios interrupt system works like the MCU?
Altera_Forum
Honored Contributor I
80 Views

The internal interrupt controller of Nios does not allow interrupt preemption. You will need to upgrade to external interrupt controller and add the Altera Vectored Interrupt Controller (VIC), which is a Nios peripheral that allow better interrupt handling including interrupt masking. 

 

Refer to section 32: https://www.altera.com/content/dam/altera-www/global/en_us/pdfs/literature/ug/ug_embedded_ip.pdf 

 

With the VIC, you can set interrupt B to be non-maskable so that it can take over the lower priority interrupt (interrupt A). Which means that interrupt B ISR can be entered even when interrupt A is being serviced.
Reply