Using InterruptAttach for IRQ8 ISR

Hi,

I am new to QNX programming and would appreciate your help with a
problem I have in my ISR execution.

I am trying to write an ISR which can service a RTC interrupt on IRQ8.
Most of my code has been extracted from the clock program available at
ftp://ftp.qnx.org.ru/pub/projects/ed1k/clock.tgz

The code extract from this link uses InterruptAttachEvent() and runs
successfully. However, when I try to use InterruptAttach(), the code
does not terminate. I cannot identify the mistake I am making in the
ISR which leads to this condition.

The code is attached below. Thanks for your help!
Ninad


#include <sys/neutrino.h>
#include <sys/siginfo.h>
#include <hw/inout.h>
#include <stdio.h>
#include <stdlib.h>

#include “ISR_test_Ninad_clock_IntAttach.h”
// header file functions have been used successfully in IAE()
scenario

#define IRQ8 8
int interruptID;

const struct sigevent *IRQ8handler(void *area, int id)
{


//Read status C register and clear interrupt request as well

out8(RTC_ADDR_REG, RTC_STATUS_C); // clear interrupt
line

//Unmask our interrupt (it masked by system for us)
InterruptUnmask(RTC_INTR, interruptID);

InterruptNum++;

return (NULL);
}



// MAIN
// ----
int main(void) {

struct sigevent event;


//Check for root privilegies and notificate the kernal
if( ThreadCtl(_NTO_TCTL_IO, 0) == -1 ) {
printf(“Process doesn’t have superuser
capabilities.\n”);
return EXIT_FAILURE;
}

//Check out the RTC status
if( GetRTCStatus() != 0 ) {
printf("Sorry, there is one or few reasons to
exit:\n\

  1. there is no RTC in your hardware,\n\
  2. RTC isn’t reachable in standard x86 way,\n\
  3. your hardware is quite old and battery is
    dead.\n");
    return EXIT_FAILURE;
    }

//Periodic timer prepare
SetRTCPeriod(Hz128); // selects 7.8125 mS period


//Attach interrupt event
SIGEV_INTR_INIT(&event);

interruptID= InterruptAttach(IRQ8, IRQ8handler, &event,
sizeof(event), _NTO_INTR_FLAGS_END);


//Clear pending interrupts
ClearRTCIntrLine();

//Enable interrupts from RTC
EnableRTCPeriodInt();

//Wait for interrupt event

while(InterruptNum<50)
{
InterruptWait(0,NULL);
InterruptNum++;


}

//Disable RTC interrupts
DisableRTCPeriodInt(); // from header file, working
function

fprintf(stdout,"\n Interrupt Routine Successful
\n");

//End of main
return EXIT_SUCCESS;
}

With InterruptAttach() the interrupt is not masked by the system.

For more details about interrupt in QNX have a look at this link:

http://www.qnx.com/developers/docs/6.3.0SP2/neutrino/prog/inthandler.html

Armand


ninadpradhan wrote:

Hi,

I am new to QNX programming and would appreciate your help with a
problem I have in my ISR execution.

I am trying to write an ISR which can service a RTC interrupt on IRQ8.
Most of my code has been extracted from the clock program available at
ftp://ftp.qnx.org.ru/pub/projects/ed1k/clock.tgz

The code extract from this link uses InterruptAttachEvent() and runs
successfully. However, when I try to use InterruptAttach(), the code
does not terminate. I cannot identify the mistake I am making in the
ISR which leads to this condition.

The code is attached below. Thanks for your help!
Ninad


#include <sys/neutrino.h
#include <sys/siginfo.h
#include <hw/inout.h
#include <stdio.h
#include <stdlib.h

#include “ISR_test_Ninad_clock_IntAttach.h”
// header file functions have been used successfully in IAE()
scenario

#define IRQ8 8
int interruptID;

const struct sigevent *IRQ8handler(void *area, int id)
{


//Read status C register and clear interrupt request as well

out8(RTC_ADDR_REG, RTC_STATUS_C); // clear interrupt
line

//Unmask our interrupt (it masked by system for us)
InterruptUnmask(RTC_INTR, interruptID);

InterruptNum++;

Counter incremented in the ISR

return (NULL);
If you return NULL the InterruptWait() won’t unblock
}



// MAIN
// ----
int main(void) {

struct sigevent event;


//Check for root privilegies and notificate the kernal
if( ThreadCtl(_NTO_TCTL_IO, 0) == -1 ) {
printf(“Process doesn’t have superuser
capabilities.\n”);
return EXIT_FAILURE;
}

//Check out the RTC status
if( GetRTCStatus() != 0 ) {
printf("Sorry, there is one or few reasons to
exit:\n\

  1. there is no RTC in your hardware,\n\
  2. RTC isn’t reachable in standard x86 way,\n\
  3. your hardware is quite old and battery is
    dead.\n");
    return EXIT_FAILURE;
    }

//Periodic timer prepare
SetRTCPeriod(Hz128); // selects 7.8125 mS period


//Attach interrupt event
SIGEV_INTR_INIT(&event);

interruptID= InterruptAttach(IRQ8, IRQ8handler, &event,
sizeof(event), _NTO_INTR_FLAGS_END);


//Clear pending interrupts
ClearRTCIntrLine();

//Enable interrupts from RTC
EnableRTCPeriodInt();

//Wait for interrupt event

The while loop is clearly a pooling which is bad because it consume CPU

time for nothing. Use a static variable in the ISR which count until 50
and then return a SIGEV_INTR which will unblock the InterruptWait().

while(InterruptNum<50)
{
InterruptWait(0,NULL);
InterruptNum++;

Counter incremented in the normal context (suspicious since it’s also
incremented in the ISR)

}

//Disable RTC interrupts
DisableRTCPeriodInt(); // from header file, working
function

fprintf(stdout,"\n Interrupt Routine Successful
\n");

//End of main
return EXIT_SUCCESS;
}

hi,

Thanks! The AttachEvent code works on returning a SIGEV_INTR from the
ISR.

However, when I use the following code fragment inside my interrupt
processing thread:

while(InterruptNum<5)
{
InterruptWait(0,NULL);
InterruptNum++;
}

the above loop does not seem to terminate, and the program execution
ends only after my main function’s sleep command running in the
backgroundhas finished ticking away those seconds.

Is there a particular reason for this non-termination of the loop?
Ninad

On Mon, Apr 10, 2006 at 05:58:44AM +0000, ninadpradhan wrote:

hi,

Thanks! The AttachEvent code works on returning a SIGEV_INTR from the
ISR.

However, when I use the following code fragment inside my interrupt
processing thread:


while(InterruptNum<5)
{
InterruptWait(0,NULL);
InterruptNum++;
}


the above loop does not seem to terminate, and the program execution
ends only after my main function’s sleep command running in the
backgroundhas finished ticking away those seconds.

Is there a particular reason for this non-termination of the loop?
Ninad

I think that InterruptWait() will only work if the calling thread is the
one who called InterruptAttach() in the first place. Could that be your
problem?


Gilles

Hi Ninand:

You also need to unmask the interrupt (otherwise the interrupt stays
masked and is never asserted again) when you’ve cleared the interrupt
cause. Take a look at the InterruptUnmask function.

Good luck,
Robert.
Gilles Roy wrote:

On Mon, Apr 10, 2006 at 05:58:44AM +0000, ninadpradhan wrote:

hi,

Thanks! The AttachEvent code works on returning a SIGEV_INTR from the
ISR.

However, when I use the following code fragment inside my interrupt
processing thread:


while(InterruptNum<5)
{
InterruptWait(0,NULL);
InterruptNum++;
}


the above loop does not seem to terminate, and the program execution
ends only after my main function’s sleep command running in the
backgroundhas finished ticking away those seconds.

Is there a particular reason for this non-termination of the loop?
Ninad



I think that InterruptWait() will only work if the calling thread is the
one who called InterruptAttach() in the first place. Could that be your
problem?


Gilles