процедура обслуживания прерывания в qnx?

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

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

это правильный способ обработки прерываний в 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 для трех разных обработчиков.


person user3458454    schedule 26.03.2014    source источник


Ответы (1)


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

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

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

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

person Aaron Digulla    schedule 26.03.2014
comment
большое спасибо за ответ. Не могли бы вы привести небольшой пример ?? Не могли бы вы предложить мне какой-нибудь документ (я искал и ничего не мог найти) - person user3458454; 26.03.2014
comment
Я не использую QNX сам; приведенное выше — это просто общее руководство, которое работает для каждой ОС. В этом документе приведены некоторые сведения об обработчиках IRQ: qnx.com /developers/docs/6.3.0SP3/neutrino/prog/inthandler.html - person Aaron Digulla; 26.03.2014
comment
Он говорит только об одном обработчике IRQ. но он не упомянул об очередях IRQ. любое предложение ?? - person user3458454; 26.03.2014
comment
я должен сделать что-то вроде InterruptDetach (id1); после вызова прерывания прикрепите ?? - person user3458454; 26.03.2014
comment
Как я уже сказал, вам придется проверить документацию QNX на предмет потокобезопасных очередей или задать новый вопрос. Что касается InterruptDetach: в этом нет необходимости, так как ядро ​​​​сделает это за вас, когда оно очистится после вашего процесса. Вам нужно только InterruptDetach, если вы хотите избавиться от обработчика IRQ, позволяя вашему процессу работать некоторое время дольше. - person Aaron Digulla; 26.03.2014
comment
Если процессор достаточно быстр, чтобы делать все (встроенный ПК с процессором i7), то мне также нужен обработчик прерываний с очередью ?? - person user3458454; 26.03.2014
comment
Прототип функции-обработчика: const struct sigevent* handler( void* area, int id ); Где area — указатель на область, заданную вызовом InterruptAttach(), а id — идентификатор, возвращаемый InterruptAttach(). При написании обработчика следуйте следующим рекомендациям: Во время прерывания предоставляется временный стек прерываний ограниченной глубины, поэтому избегайте размещения больших массивов или структур в кадре стека обработчика. Можно с уверенностью предположить, что доступно около 200 байт стека. Обработчик прерывания работает асинхронно с потоками в процессе. - person user3458454; 26.03.2014
comment
На это нет универсального ответа. Обработчики IRQ — особенные звери, и вам нужно знать, что вы делаете, когда используете их. Я чувствую, что вам нужно больше узнать о многопоточности, обработке IRQ и доступе к общим данным (т. е. о блокировке, очередях и атомарных операциях). Без этих базовых знаний мои слова просто не будут иметь для вас смысла. - person Aaron Digulla; 26.03.2014