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

Implementation of ISR in Nios 3.20 SDK

Altera_Forum
Honored Contributor II
1,299 Views

Hello 

Could somebody tell me that the following testisr.c program is correct. The ISR “irq_handler” is installed by “nr_installuserisr” procedure. The parametr “context” is set to pointer to &stab[0] record, which contains four semaphore variables. The “->sema” variable, initially set to 0, is tested in main() subroutine until it is set to 1 in “irq_handler()” after hardware interrupt occurred. Second test is performed on “->semb” variable, which is never touched in ISR. I’m not sure that is correct way to handle critical region in Nios 3.20 environment independently on compiler options. Could you tell me which registers are stored on stack when the ISR is invoked. Do I have to be aware of any registers when I use record variables set up by pointer (->) expressions to send data between ISR and main program? 

 

 

There is the Nios testisr.c program. I use Nios 3.20 SDK under Windows 2000. Compilation is performed by invoking nios-build –O2 testisr.c. 

 

Regards 

Chris 

 

typedef struct{ 

int sema; 

int semb ; 

char semc; 

short semd; 

}s_st; 

s_st stab[2]; 

 

int main(){ 

s_st *pst; 

 

pst = &stab[0]; 

pst->sema =0; 

pst->semb =0; 

pst->semc =0; 

pst->semd =0; 

 

nr_installuserisr(IRQ_num,irq_handler,(int)&stab[0]); 

 

//we are waiting for irq... 

laba: 

if(pst->sema == 0) 

goto laba; 

if(pst->sema != 1) 

printf("Something wrong with Nios ISR?"); 

//...at isr semaphore was changed 

// and next we are in infinite loop 

 

labb: 

if(pst->semb == 0) 

goto labb; 

printf("Something wrong with Nios ISR?\n"); 

return 0; 

 

//isr 

void irq_handler(int context){ 

s_st *pst; 

pst = (s_st *)context; 

pst->sema = 1; 

}
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
518 Views

Hi chris01, 

 

> Could somebody tell me that the following testisr.c program is correct. 

 

I don't have time right now to look more closely ... but you might want to 

consider making 'pst' point to a volatile structure (either make the struct 

volatile, or make the referenced object volatile) . Your interrupt may well be 

working fine ... but your main thread may never actually access memory 

after the first read. 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
518 Views

 

--- Quote Start ---  

originally posted by chris01@Dec 29 2005, 06:58 AM 

hello 

could somebody tell me that the following testisr.c program is correct. the isr “irq_handler” is installed by “nr_installuserisr” procedure. the parametr “context” is set to pointer to &stab[0] record, which contains four semaphore variables. the “->sema” variable, initially set to 0, is tested in main() subroutine until it is set to 1 in “irq_handler()” after hardware interrupt occurred. second test is performed on “->semb” variable, which is never touched in isr. i’m not sure that is correct way to handle critical region in nios 3.20 environment independently on compiler options. could you tell me which registers are stored on stack when the isr is invoked. do i have to be aware of any registers when i use record variables set up by pointer (->) expressions to send data between isr and main program? 

 

 

there is the nios testisr.c program. i use nios 3.20 sdk under windows 2000. compilation is performed by invoking nios-build –o2 testisr.c. 

 

regards 

chris 

 

typedef struct{ 

int sema; 

int semb ; 

char semc; 

short semd; 

}s_st; 

s_st stab[2]; 

 

int main(){ 

s_st *pst; 

 

pst = &stab[0]; 

pst->sema =0; 

pst->semb =0; 

pst->semc =0; 

pst->semd =0; 

 

nr_installuserisr(irq_num,irq_handler,(int)&stab[0]); 

 

//we are waiting for irq... 

laba: 

if(pst->sema == 0) 

goto laba; 

if(pst->sema != 1) 

printf("something wrong with nios isr?"); 

//...at isr semaphore was changed 

// and next we are in infinite loop 

 

labb: 

if(pst->semb == 0) 

goto labb; 

printf("something wrong with nios isr?\n"); 

return 0; 

 

//isr 

void irq_handler(int context){ 

s_st *pst; 

pst = (s_st *)context; 

pst->sema = 1; 

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

--- quote end ---  

 

--- Quote End ---  

 

 

 

Hello Chris, 

 

I have recently overcome this hurdle. As it turns out, interrupts cannot be requested in user space. After much reading, I found out that it is necessary to make a device driver to interface to your interrupt source (usually a PIO). In trying to mimic the way interrupts work in an embedded system (the way most folks are acustomed to that is,) I requested the interrupt and set the ISR to respond in a char driver. The ISR in this case has a top and bottom half (TH, BH) which usually are used to (TH) handle the interrupt in the bare esentials, and (BH) tasklet or work queue to handle any data. Since the nature of an interrupt is (usually) to signal user code, I used asynchronous notification to a user space function (my ISR equivalent) and execute my custom code. Once the "ISR" completed, interrupts are re-enabled by writing to the PIO control (like in a vainilla ISR: disable interrupts, handle request, re-enable interrupts). There is some delay associated with this mechanism and it is inherent to uClinux but it is the fastest way to get an interrupt signal to user space. 

The device driver (of course) holds no value to anyone other than myself and my specific use and for that reason I used one of the local experimental device IDs (they are 60 - 63). 

I hope (humbly) that this help you, and if this method is outdated, rudimentary or complicated and you have a more simple one I would like to hear from you. 

 

Cheers mate, 

 

Carlos
0 Kudos
Reply