m3rk
Интересующийся
Сообщений: 7
|
 |
« : 18 Ноябрь, 2014, 01:37:31 » |
|
Подскажите пожалуйста можно ли вставлять в обработчик прерываний свои функции, не скажется ли это на производительности? Рекомендуют делать обработчик прерываний как можно короче и это понятно, но что если есть повторяющаяся операция в обработчике для разных прерываний, которую хотелось бы определить в виде функции, чтобы не нагромождать сильно код.
|
|
|
Записан
|
|
|
|
Олег Большаков
Администратор
Житель форума
Сообщений: 3133
|
 |
« Ответ #1 : 18 Ноябрь, 2014, 07:59:02 » |
|
Да, можно вызывать свою собственную функцию из обработчика прерывания. Ограничения у функции будут те же, что и у функции-обработчика. Существенно на производительности это сказаться не должно, но в общем случае производительность будет зависеть от Вашего кода.
|
|
|
Записан
|
|
|
|
m3rk
Интересующийся
Сообщений: 7
|
 |
« Ответ #2 : 18 Ноябрь, 2014, 23:06:29 » |
|
Спасибо Вам большое за развернутый ответ!
|
|
|
Записан
|
|
|
|
m3rk
Интересующийся
Сообщений: 7
|
 |
« Ответ #3 : 25 Ноябрь, 2014, 08:46:18 » |
|
Подскажите пожалуйста еще по такому вопросу об обработчике: недавно встретил в коде, что обработчик возвращает пид прокси процесса или 0. Взаимодействие с прерыванием идет через прокси. Если обработчик прерывания вызывается аппаратно, то есть в я явном виде он не вызывается нигде в коде, куда может возвращаться значение - в какую переменную, был на оф сайте http://www.qnx.com/developers/docs/qnx_4.25_docs/qnx4/sysarch/microkernel.html но здесь с примерами кода как-то совсем туго.
|
|
|
Записан
|
|
|
|
Олег Большаков
Администратор
Житель форума
Сообщений: 3133
|
 |
« Ответ #4 : 25 Ноябрь, 2014, 13:05:13 » |
|
Посмотрите описание функции qnx_hint_attach() в штатной справочной системе. Там приведён пример установки обработчика и ожидания proxy. Если требуется передача данных из обработчика прерывания, то сделать это можно, например, через глобальные переменные.
|
|
|
Записан
|
|
|
|
m3rk
Интересующийся
Сообщений: 7
|
 |
« Ответ #5 : 18 Февраль, 2015, 00:16:35 » |
|
Добрый вечер, недавно всплыла проблема с регистрацией обработчика прерывания ( http://users.pja.edu.pl/~jms/qnx/help/watcom/clibref/qnx/qnx_hint_attach.html), а именно не совсем понятно назначение третьего аргумента функции - ds, он же data segment. Как я понял это сегмент данных обработчика прерываний, который начинается зачастую с объявления первой глобальной переменной. Поправьте меня пожалуйста, если я ошибаюсь, просто хочется внести окончательную ясность в данный вопрос. Заранее спасибо.
|
|
|
Записан
|
|
|
|
Олег Большаков
Администратор
Житель форума
Сообщений: 3133
|
 |
« Ответ #6 : 18 Февраль, 2015, 16:53:08 » |
|
m3rk, Вы, в общем, правильно понимаете. Сегмент данных требуется, т.к. обработчик прерывания работает, грубо говоря, в контексте ядра, а не в контексте процесса, который установил этот обработчик. В общем случае, Вы можете создать отдельный сегмент данных для обработчика, но на практике это требуется редко.
|
|
|
Записан
|
|
|
|
m3rk
Интересующийся
Сообщений: 7
|
 |
« Ответ #7 : 19 Февраль, 2015, 02:25:48 » |
|
Такая ситуация есть обработчик собственно. #include <unistd.h> #include <conio.h>
#include "../headers/core_isr.h" #include "../headers/core_Constants.h" #include "../headers/core_Workcycle.h"
volatile unsigned char flag_irq; ///< Флаг прерывания volatile unsigned char int_84h; ///< Признак прерывания 84h - "Готовы данные о физич.подкл.МВВ" volatile unsigned char kls_int; ///< Признак активации прерывания, считывается из STATUS volatile unsigned char kls_word; ///< Причина прерывания volatile unsigned char cnt_irq; ///< Счетчик прерываний volatile unsigned int cnt[30];
unsigned char segment_num; ///< Номер СЛС unsigned count_timeout; unsigned char busy[4] = { 0x10, 0x20, 0x40, 0x80 }; int isr_error; ///< Индикация ошибки в обработчике прерывания unsigned char table_modules[MAX_SEGMENTS][MAX_NUM_MODULES];
#pragma check_stack (off)
// Add far pointer pid_t far HandlerIRQ_kls(void) { /* ... */ return proxy_IRQ; }
И его заголовочный файл #include <unistd.h>
#define KLS_STATUS_PORT 0x340 ///< Адрес регистра состояния готовности каналов(busy1..busy3) ///< и признаков указателей каналов-источников прерываний (int1..int3) #define KLS_WORD_PORT 0x341 ///< Адрес регистра для чтения причины прерывания #define KLS_RESREG_PORT 0x344 ///< Адрес регистра для сброса КЛС(используется при инициализации/перезагрузке) #define KLS_DATA_PORT 0x345 ///< Адрес регистра для передачи кода команды и данных #define IRQ_KLS 10 ///< Номер прерывания (для fm5 10е прерывание)
extern pid_t far HandlerIRQ_kls(void); ///< Обработчик прерывания
extern volatile unsigned char flag_irq; ///< Флаг прерывания extern volatile unsigned char int_84h; ///< Признак прерывания 84h - "Готовы данные о физич.подкл.МВВ" extern volatile unsigned char kls_int; ///< Признак активации прерывания, считывается из STATUS extern volatile unsigned char kls_word; ///< Причина прерывания extern volatile unsigned char cnt_irq; ///< Счетчик прерываний extern volatile unsigned int cnt[30];
[/size] При попытке записи например в 345 регистр 1 байта без прерывания система зависает, хотя не должна и это при зарегистрированном обработчике, если его не регистрировать, то все проходит успешно. Обработчик из-за этого соответственно также не функционирует. Грешу пока только на ds, то есть дефайн для адресов регистров выше в заголовочном чем глобальная переменная, которую передаю как ds в qnx_hint_attach(). Буду рад любому замечанию и совету по данной проблеме. Ниже скриншот ошибки и падения системы. 
|
|
|
Записан
|
|
|
|
Олег Большаков
Администратор
Житель форума
Сообщений: 3133
|
 |
« Ответ #8 : 19 Февраль, 2015, 12:22:26 » |
|
При попытке записи например в 345 регистр 1 байта без прерывания система зависает, хотя не должна и это при зарегистрированном обработчике, если его не регистрировать, то все проходит успешно. Одна из причин такого поведения может быть в том, что при записи в регистр генерируется прерывание, а в обработчике оно не сбрасывается. Грешу пока только на ds, то есть дефайн для адресов регистров выше в заголовочном чем глобальная переменная, которую передаю как ds в qnx_hint_attach(). Непонятно, что именно Вы передаёте в качестве третьего параметра функции qnx_hint_attach(). Это должен быть селектор сегмента данных, обычно используется значение, возвращаемое my_ds(). На мой взгляд, вопрос вышел за рамки форума. Предлагаю Вам обратиться к нам на электронный адрес технической поддержки или через форму обратной связи. Потребуется исходный код обработчика прерывания и его установки.
|
|
|
Записан
|
|
|
|
m3rk
Интересующийся
Сообщений: 7
|
 |
« Ответ #9 : 19 Февраль, 2015, 20:58:21 » |
|
Извините забыл написать, регистрация обработчика выглядит так: qnx_hint_attach(IRQ_KLS, &HandlerIRQ_kls, FP_SEG(&flag_irq)); где flag_irq это объявление первой глобальной переменной в обработчике, делал собственно по примеру из документации http://users.pja.edu.pl/~jms/qnx/help/watcom/clibref/qnx/qnx_hint_attach.html там используют переменную counter и еще сюда смотрел http://www.qenesis.com/support/interrupts.html. Спасибо Вам большое за наводку про my_ds попробую ее. А как в обработчике можно сбросить прерывание, не подскажете если Вас не затруднит. Пытался найти в интернетах про сброс но ничего не нашел путного.
|
|
|
Записан
|
|
|
|
Олег Большаков
Администратор
Житель форума
Сообщений: 3133
|
 |
« Ответ #10 : 20 Февраль, 2015, 16:48:17 » |
|
А как в обработчике можно сбросить прерывание, не подскажете если Вас не затруднит. Пытался найти в интернетах про сброс но ничего не нашел путного. Имеется в виду сброс источника прерывания в том, устройстве, с которым Вы работаете. Способ сброса зависит от устройства и должен быть описан в спецификации на устройство. Иногда достаточно прочитать регистр статуса прерываний (самого устройства), либо записать в этот регистр какое-то значение. Могут быть и другие варианты.
|
|
|
Записан
|
|
|
|
m3rk
Интересующийся
Сообщений: 7
|
 |
« Ответ #11 : 21 Февраль, 2015, 20:50:17 » |
|
Спасибо Вам большое за детальные развернутые ответы!
|
|
|
Записан
|
|
|
|
|