Прерывание обслуживания рутины в qnx?

Сценарий: клиент отправляет данные, а сервер получает данные от клиента через уровень Ethernet (udp). Когда сервер получает данные от клиента на уровне ip (ядро). Он прерывает ядро ​​и ядро, чтобы выполнить данные клиентом, поэтому я хочу создать функцию обслуживания прерываний, чтобы перехватывать прерывания с карты сетевой службы.

Я использую API-интерфейс Interruptattach для обработки прерывания от сетевой карты и структуры sigevent для вызова определенной функции. http://www.qnx.com/developers/docs/6.3.0SP3/neutrino/lib_ref/i/interruptattach.html

это правильный способ обработки прерываний в 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;
}

Другой вопрос: если я хочу вызвать другую функцию в структуре sigevent, тогда я должен использовать другой ISR для этого (то есть, как обрабатывать несколько функций из прерывания)?

Я изменил свой код, как указано выше. Будет ли это эффективно, если я сделаю, как указано выше. Одна функция ISR с InterruptAttach API для трех разных обработчиков.

1 ответ

Это плохой подход: обработчики прерываний (IRQ) не прерываются. Это означает, что: 1. ваш компьютер будет заблокирован, когда вы выполняете в нем много работы, и 2. вы не можете вызывать каждый метод.

Правильный подход - получить IRQ, вызвать обработчик. Обработчик должен создать структуру памяти, заполнить ее сведениями о том, что необходимо сделать, и добавить эти "данные задачи" в очередь. Затем фоновый поток может ожидать элементы в очереди и выполнять работу.

Таким образом, обработчики IRQ будут маленькими и быстрыми. Ваш фоновый поток может быть настолько сложным, насколько вам нравится. если у потока есть ошибка, худшее, что может случиться, - это ее разрыв (заставить обработчик IRQ выбрасывать события, когда очередь заполнена).

Обратите внимание, что очередь должна быть реализована таким образом, чтобы добавление элементов в нее никогда не блокировалось. Проверьте документацию, там уже должно быть что-то, что позволяет нескольким потокам обмениваться данными; то же самое можно использовать для обработчиков IRQ.

Другие вопросы по тегам