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

Atomic Instruction Block

Altera_Forum
Honored Contributor II
1,092 Views

Is there a faster way to make a critical block of instructions atomic (not interruptible) than using the alt_irq_disable_all and alt_irq_enable_all HAL functions? 

 

Chris
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
368 Views

I don't know exactly how the hal implements it, but in the legacy SDK, I use some macro's with a direct assembler instruction. 

 

Normaly, disbling and enabling interrupts take only one instruction. 

 

And if you want to store the status from before disabling (if you want to nest enables, disables) on the stack, you need some more. 

 

The macros look like this (DWORD is an unsigned long = 32 bit): 

 

 

/** Local stack space for processor status word. 

* Must be placed in the same scope where CRITICAL() and END_CRITICAL() is used 

* \hideinitializer 

*/# define CONTAINS_CRITICAL DWORD stored_status; 

 

/** Begin critical section. 

* Interrupts will be disabled after this macro. \n 

* CRITICAL() must always be used in pair with END_CRITICAL(). 

* \hideinitializer 

*/# define CRITICAL { __asm__ volatile ("rdctl %0, status" : "=r" (stored_status));  

__asm__ volatile ("wrctl status, r0");  

 

/** End critical section. 

* Interrupts will be enabled after this macro if they were enabled before CRITICAL(). \n 

* END_CRITICAL() must always be used in pair with CRITICAL(). 

* \hideinitializer 

*/# define END_CRITICAL { __asm__ volatile ("wrctl status, %0" :: "r" (stored_status)); } 

 

 

If you want to use, do this : 

 

void foo() 

 

CONTAINS_CRITICAL 

 

// normal section 

 

CRITICAL 

//interrupts disabled here 

END_CRITICAL 

 

//normal section 

 

CRITICAL 

//interrupts disabled here 

END_CRITICAL 

 

}
0 Kudos
Altera_Forum
Honored Contributor II
368 Views

If you find a more efficient way then I'd be interested to hear it. 

 

At optimisation level -O2 these functions compile up into exactly the same code as described above:  

rdctl rx, status wrctl status, zero 

at the start and 

wrctl status, rx 

at the end (where rx is a register between r2 and r23 chosen by the compiler). 

 

Please check your objdump file to see what the compiler has generated for you.
0 Kudos
Altera_Forum
Honored Contributor II
368 Views

Fine for me http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/smile.gif  

 

Stefaan
0 Kudos
Reply