Implimenting ISR using InterruptAttach

Hi,
I am trying to create my ISR using interruptAttach

this is what I need

//**********************************************************
#include <stdio.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>
#include <semaphore.h>
#include <pthread.h>

#define IRQ1 1
uint64_t global_data;

volatile unsigned counter;
sem_t end;

const struct sigevent *
handler (void *arg, int id)
{
struct sigevent *event = (struct sigevent )arg;
/

* I do something with the global_data
*/
global_data = SYSPAGE_ENTRY(qtime);

return event;

}

/*

  • Assume there are some interrupt IRQs defined in a array
    */
    void * int_thread(void * cookie){
    int i;
    int id;
    struct sigevent event;

    printf(“setting notification mode\n”);
    event.sigev_notify = SIGEV_INTR;
    for (i = 0; i < MAX_IRQ; i++) {
    id=InterruptAttach(irq_arr[i], &handler, &event, sizeof(event), 0 );
    }

    for( i = 0; i < 10; ++i ) {
    InterruptWait( 0, NULL );
    printf( “key hit\n” );
    InterruptUnmask(IRQ1, id);
    }
    // Disconnect the ISR handler

    InterruptDetach(id);
    sem_post(&end);
    return NULL;
    }

Apart from this I create another thread which actually does the interrupt handling and processing. I need to use the intterupAttach so that I capture some values in the ISR and then trigger the worker thread.
However, with the above implementation, ISR is invoked but the worker thread is not invoked and thus the interrupt remains uncleared and unmasked leaving the system in non-responsive state.

Is there anything I am missing here?

Thanks
Sen

Sen,

Is there a reason you are attaching to every interrupt (1-15) in the system?

for (i = 0; i < MAX_IRQ; i++) { 
id=InterruptAttach(irq_arr[i], &handler, &event, sizeof(event), 0 ); 
} 

Especially since you only unmask 1 interrupt here:

for( i = 0; i < 10; ++i ) { 
InterruptWait( 0, NULL ); 
printf( "key hit\n" ); 
InterruptUnmask(IRQ1, id); 
} 

Leaving 14 others that you’ve attached to but never unmask.

For testing, just attach to the timer interrupt instead of trying to attach to every interrupt (ie you don’t need the ‘for’ loop for attaching). I suspect this is what makes your system hang.

Tim

You said apart from this - I create another thread which actually does the interrupt handling and processing. What is the another thread for ??

I am also doing same kind of activity. Could you please help me ??

const struct sigevent *handler1(void *area, int id1)
{
volatile double KernelStartExecutionTime;
struct sigevent *event = (struct sigevent *)area;
KernelStartExecutionTime = GetTimeStamp(); // calculating the time when the kernel starts executing
measurements[18] = KernelStartExecutionTime ;
//return (NULL);
return event;

}

/*kernel calls attach the interrupt function handler to the hardware interrupt specified by intr(i.e irq) */
// InterruptAttach() : Attach an interrupt handler to an interrupt source
// interrupt source is handler1 for this example
void configureISR(void) //void *ISR (void arg)
{
/
the software must tell the OS that it wishes to associate the ISR with a particular source of interrupts.

  • On x86 platforms, there are generally 16 hardware Interrupt Request lines (IRQs) */
    volatile int irq = 0; //0 : A clock that runs at the resolution set by ClockPeriod()
    struct sigevent event;
    event.sigev_notify = SIGEV_INTR;

ThreadCtl (_NTO_TCTL_IO, NULL); // enables the hardware interrupt
id1 = InterruptAttach(irq, &handler1, &event, sizeof(event), 0); // handler1 is the ISR

InterruptWait( 0, NULL );
InterruptUnmask(irq, id1);

InterruptDetach( id1);

}

int main(int argc, char *argv[])
{

 CreateSocket(); // receiving the data from client

 configureISR();      

// pthread_create (NULL, NULL, ISR, NULL);
 return 0;

}

Client/server communication - client is sender and server is receiver.

When the server receives the data on the ethernet interface(UDP) the kernel in the server is triggered. I am using real time QNX on the server side. Server (i.e. embedded pc target) is handling interrupts to trigger the embedded pc target (containing QNX) to gain the attention to execute the newly arrived data.

So the above code is a interrupt service routine to handle the interrupts from client.

Well, it’s hard to know where to start. You seem to be very confused about things. Let me start in the most obvious place.

If the event(s) you are reacting to are the receive of UDP packets, then you don’t want to write an ISR nor do you want to attach to an IRQ. The way this all works is that there’s a NIC driver. It attaches to an IRQ and has an ISR. When it receives a packet, it passes it on. If it’s a UDP packet, the TCP/IP software handles it. If you are waiting for a UDP packet, it sends the data to your process and your code that is waiting wakes up. No ISR’s, no attaching to IRQ’s.

In general, the reason to attach an ISR to an IRQ is because you have a piece of hardware which you are handling, making your code a hardware driver. Otherwise the OS has drivers to deal with the hardware for you, so you don’t have to.

One exception that comes up now and then has to do with attaching to the timer interrupt at IRQ 0. This is usually avoidable and should be, by using a periodic timer. However you could attach an ISR to this IRQ and your ISR will wake up periodically. Of course your ISR should do nothing but return an event that will wake up a thread. Well you could do a very small amount of processing in your ISR, like incrementing a counter, but handling the timer hardware is already taken care of another ISR that the OS provides.

I hope this helps.

If all you want to do is measure performance for some experiment you could use the system profiler.

You should explain what you want to do exacly and why you want to do it. You might be looking at this all wrong.

could you please tell me how do i know, where should I take the timestamp ??
when the client sends a data to the server, server (EMBEDDED PC : FIT PC2) should handle the interrupt and I have to take the timestamp where the interrupt occurs.
I also want to take the timestamp when the handler starts executing that . could you please tell me how to do that ??

@mario : could you please give your email id ??

If you want to know when the interrupt occurs, you need an external hardware device to monitor the interrupt line level. There is no way to know in software alone.

You can use private messages, but it’s best for everyone to have open discussion as everybody gets to learn from one another.

I am not able to send a private message. Could you please mail me to : hemanthjkv@ymail.com. I am having a deadline to handle the interrupt in QNX by friday. So please, I need your help.

If you want to know when the interrupt occurs, you need an external hardware device to monitor the interrupt line level. There is no way to know in software alone.

This is true you need hardware - but the hardware can be onboard. Consider a legacy serial port (yes, many boards don’t have them anymore.) You can trigger an interrupt in software - and measure the response time to the interrupt.

  1. setup the uart to interrupt on a control signal (do NOT load devc-ser8250 - you must program the uart yourself)
  2. setup an interrupt handler plus a thread which calls InterruptWait()
  3. put a loopback connector on the port so an OUTPUT control signal is attached to an INPUT control signal on the same port (RTS to CTS (or DSR to DTR)
  4. in your software raise the output control signal and read “the clock” to start a measurement
  5. in your interrupt handler, read “the clock” - the difference is the ISR latency
  6. when your thread wakes, read “the clock” - the difference from control signal to thread is the interrupt thread latency

You will want to run the measurement in a loop keeping track of average and “worst” cases.

“the clock” I have used is the 8254 “PIT” which is used to drive the QNX o/s tick clock (0.838us per count - 1193 counts per 1ms)

For accurate results, you must run on a “quiet” system. You will also want to guarantee that the measurement runs “between” o/s ticks so that the o/s timer latency is not a factor.