0

Scenario : Client is sending a data and the server is receving the data from client via ethernet layer (udp). When the server receives a data from the client on the ip layer (kernel). It interrupts the kernel and kernel as to execute the data by the client, so I want to create a interrupt service function to catch the interrupt from the network service card.

I am using Interruptattach api to handle the interrupt from the network interface card and sigevent structure to call the specific function. http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/lib_ref/i/interruptattach.html#HandlerFunction

is it the right way to handle interrupts in qnx ??

volatile int id1, id2, id3;
 const struct sigevent *handler1(void *area, int id1)
 {
    volatile double KernelStartExecutionTime;
     KernelStartExecutionTime = GetTimeStamp();   // calculating the time when the kernel starts executing

    TASK1(Task2ms_Raster);
    return (NULL);

 }
 const struct sigevent *handler2(void *area, int id2)
 {
     volatile double KernelStartExecutionTime;
     KernelStartExecutionTime = GetTimeStamp();   // calculating the time when the kernel starts executing

    TASK2(Task10ms_Raster);
    return (NULL);

 }

 const struct sigevent *handler3(void *area, int id3)
 {
     volatile double KernelStartExecutionTime;
     KernelStartExecutionTime = GetTimeStamp();   // calculating the time when the kernel starts executing

    TASK3(Task100ms_Raster);
    return (NULL);

 }


 /*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 ISR(void)
 {

 volatile int irq = 0;   //0 :  A clock that runs at the resolution set by ClockPeriod()

 ThreadCtl (_NTO_TCTL_IO, NULL);
 id1 = InterruptAttach(irq, &handler1, NULL, 0, 0);
 id2 = InterruptAttach(irq, &handler2, NULL, 0, 0);
 id3 = InterruptAttach(irq, &handler3, NULL, 0, 0);


 }

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

     CreateSocket();

     ISR();      //function call for ISR

     return 0;
}

another question : if I want to call another function in the sigevent structure then should I use another ISR for that (i.e. how to handle multiple function from the interrupt)?

I modified my code as above. Will it be efficient if I do like above. One ISR function with InterruptAttach API for three different handler.

user3458454
  • 291
  • 1
  • 4
  • 20

1 Answers1

0

This is a bad approach: Interrupt (IRQ) handlers are not interruptable. That means: 1. your computer will lock up when you do a lot of work in them and 2. you can't call every method.

The correct approach is to receive the IRQ, call a handler. The handler should create a memory structure, fill it with the details what needs to be done and adds this "task data" to a queue. A background thread can then wait for elements in the queue and do the work.

That way, IRQ handlers will be small and fast. Your background thread can be as complex as you like. if the thread has a bug, the worst that can happen is that it breaks (make the IRQ handler throw away events when the queue is full).

Note that the queue must be implemented in such a way that adding elements to it never blocks. Check the documentation, there should already be something that allows several threads to exchange data; the same can be used for IRQ handlers.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • thank you very much for the reply. Could you please give me a small example ?? could you suggest me some document (I searched and could not find anything) – user3458454 Mar 26 '14 at 13:42
  • I don't use QNX myself; the above is just a general guideline that works for every OS. This document gives some details about IRQ handlers: http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/prog/inthandler.html – Aaron Digulla Mar 26 '14 at 13:47
  • He is telling for only one IRQ handler. but he did not mention about IRQ queues . any suggestion ?? – user3458454 Mar 26 '14 at 14:02
  • shall i do something like InterruptDetach (id1); after calling the interrupt attach ?? – user3458454 Mar 26 '14 at 14:06
  • As I said, you'll have to check the QNX documentation for thread-safe queues or ask a new question. As for `InterruptDetach`: That shouldn't be necessary since the kernel will do that for you when it cleans up after your process. You only need `InterruptDetach` if you want to get rid of an IRQ handler while letting your process run a while longer. – Aaron Digulla Mar 26 '14 at 14:09
  • If the processor is fast enough to do everything (embedded pc target with i7 processor ) then also do i need interrupt handler with queue ?? – user3458454 Mar 26 '14 at 14:16
  • The handler function's prototype is: const struct sigevent* handler( void* area, int id ); Where area is a pointer to the area specified by the call to InterruptAttach(), and id is the ID returned by InterruptAttach(). Follow the following guidelines when writing your handler: A temporary interrupt stack of limited depth is provided at interrupt time, so avoid placing large arrays or structures on the stack frame of the handler. It's safe to assume that about 200 bytes of stack are available. The interrupt handler runs asynchronously with the threads in the process. – user3458454 Mar 26 '14 at 14:26
  • There is no generic answer to that. IRQ handlers are special beasts and you need to know what you're doing when you use them. My feeling is that you need to learn more about multi-threading, IRQ handling and shared data access (i.e. locking, queues and atomic operations). Without this basic knowledge, my words simply won't make sense for you. – Aaron Digulla Mar 26 '14 at 16:27