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++

interupt disabled in ISR

Altera_Forum
Honored Contributor II
1,180 Views

In the Nios II Software developer's handbook: 

"the HAL system library disables interupts when it dispatches an ISR". 

I've examine the file alt_irq_entry.S and alt_irq_handler.c but no presence of interupts disabling. 

Could anybody tell me where are disabled interupts? 

thank u in advance.
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
345 Views

When an exception is generated, the processor performs the following 

steps automatically: 

■ Copies the contents of the status register (ctl0) to the estatus 

register (ctl1), saving the pre-exception status of the processor 

■ Clears the PIE bit of the status register, disabling further hardware 

interrupts 

■ Stores the address of the instruction after the exception to the ea 

register (r29), providing the return address for the exception 

handler to return to 

■ Vectors to the exception address
0 Kudos
Altera_Forum
Honored Contributor II
345 Views

thank u for the answer David_Cai. 

This is the code of alt_irq_entry.S: 

 

 

 

/* 

* This is the interrupt exception entry point code, which saves all the 

* registers and calls the interrupt handler. It should be pulled in using 

* a .globl from alt_irq_register.c. This scheme is used so that if an 

* interrupt is never registered, then this code will not appear in the 

* generated executable, thereby improving code footprint. 

*/ 

 

/* 

* Explicitly allow the use of r1 (the assembler temporary register) 

* within this code. This register is normally reserved for the use of 

* the compiler. 

*/ 

.set noat 

 

/* 

* Pull in the exception handler register save code. 

*/ 

.globl alt_exception 

 

.globl alt_irq_entry 

.section .exceptions.entry.label, "xa" 

alt_irq_entry: 

 

/* 

* Section .exceptions.entry is in alt_exception_entry.S 

* This saves all the caller saved registers and reads estatus into r5 

*/ 

 

.section .exceptions.irqtest, "xa" 

# ifdef ALT_CI_EXCEPTION_VECTOR_N 

/* 

* Use the exception vector custom instruction if present to accelerate 

* this code. 

* If the exception vector custom instruction returns a negative 

* value, there are no interrupts active (estatus.pie is 0 

* or ipending is 0) so assume it is a software exception. 

*/ 

custom ALT_CI_EXCEPTION_VECTOR_N, et, r0, r0 

blt et, r0, .Lnot_irq# else 

/* 

* Test to see if the exception was a software exception or caused  

* by an external interrupt, and vector accordingly. 

*/ 

rdctl r4, ipending 

andi r2, r5, 1 

beq r2, zero, .Lnot_irq 

beq r4, zero, .Lnot_irq# endif /* ALT_CI_EXCEPTION_VECTOR_N */ 

 

.section .exceptions.irqhandler, "xa" 

/* 

* Now that all necessary registers have been preserved, call  

* alt_irq_handler() to process the interrupts. 

*/ 

 

call alt_irq_handler 

 

.section .exceptions.irqreturn, "xa" 

 

br .Lexception_exit 

 

.section .exceptions.notirq.label, "xa" 

 

.Lnot_irq: 

 

/* 

* Section .exceptions.exit is in alt_exception_entry.S 

* This restores all the caller saved registers 

*/ 

 

.section .exceptions.exit.label 

.Lexception_exit: 

 

 

 

 

Which are the instruction that save registers and clears PIE bit? 

Probably I miss something. 

Thank u
0 Kudos
Altera_Forum
Honored Contributor II
345 Views

 

--- Quote Start ---  

originally posted by soin@Sep 13 2006, 02:21 AM 

which are the instruction that save registers and clears pie bit? 

probably i miss something. 

thank u 

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

--- quote end ---  

 

--- Quote End ---  

 

As David Cai wrote this is automatically done by the processor, not the software. If you want nested interrupts you have to explicitly re-enable interrupts in your ISR.
0 Kudos
Altera_Forum
Honored Contributor II
345 Views

ok, perfect. I didn&#39;t understood clearly that. 

thank u all
0 Kudos
Altera_Forum
Honored Contributor II
345 Views

and just to be crystal clear, presumably all that needs to be done is something like the following: 

 

#include <io.h># include <system.h># include "sys/alt_irq.h" // ---------------------------------------------------------------------------- alt_irq_context IRQ_ALLOW_ESSENTIAL_START (alt_u32 id,  alt_u32* pActive) {  alt_irq_context Ctrl0;  alt_u32 irq_mask;   //mask out own IRQ and all others having lower priority level    irq_mask = ~(0x0FFFFFFFF << id); // alternatively, mask out self and IRQs 32-29, 28-26    irq_mask = (~(1 << id)) & 0x01FFFFFFF;    *pActive = alt_irq_active;    alt_irq_active &= irq_mask;    NIOS2_WRITE_IENABLE (alt_irq_active); /*  alternatively......  alt_irq_disable (id);                    //Prevent re-entry  alt_irq_disable (<a lower priority interrupt that can wait>);  alt_irq_disable (<another lower priority interrupt that can wait>);  alt_irq_disable (<yet another lower priority interrupt that can wait>); */    NIOS2_READ_STATUS (Ctrl0);    Ctrl0 |= NIOS2_STATUS_PIE_MSK;    NIOS2_WRITE_STATUS (Ctrl0);    return (Ctrl0); } // ---------------------------------------------------------------------------- void IRQ_ALLOW_ESSENTIAL_FINISH (alt_irq_context Ctrl0,  alt_u32 id,  alt_u32 Active) {    Ctrl0 &= ~NIOS2_STATUS_PIE_MSK;    NIOS2_WRITE_STATUS (Ctrl0); /*  alt_irq_enable (<yet another lower priority interrupt that can wait>);  alt_irq_enable (<another lower priority interrupt that can wait>);  alt_irq_enable (<a lower priority interrupt that can wait>);  alt_irq_enable (id); */    alt_irq_active = Active;    NIOS2_WRITE_IENABLE (Active); } // ---------------------------------------------------------------------------- static void MyInterruptibleISR (void* context, alt_u32 id) {  alt_irq_context Ctrl0;  alt_u32 Active; <time-critical section, e.g. reading registers>  Ctrl0 = IRQ_ALLOW_ESSENTIAL_START (id, &Active); <non-time-critical section, e.g. stuffing in buffers>  IRQ_ALLOW_ESSENTIAL_FINISH (Ctrl0, id, Active); } // ----------------------------------------------------------------------------
0 Kudos
Reply