_NTO_INTR_FLAGS_TRK_MSK - на время выполнения обработчика маскировать прерывания;
При решении стоящих перед нами задач: перехват прерываний таймера и клавиатуры аргумент intr будет соответственно принимать значения 0 и 1. Так как в рассматриваемом простейшем случае использование сложных механизмов неоправданно, аргументы area и size примут значения NULL. Аналогично им – flags.
#include <sys/neutrino.h>
Int InterruptMask( int intr, int id);
Функция маскирования аппаратных прерываний.
intr номер маскируемого прерывания
id идентификационный номер маскируемого обработчика
В отличие от DOS, у нас есть возможность замаскировать отдельный обработчик, что повышает гибкость программного обеспечения.
#include <sys/neutrino.h>
int InterruptUnmask( int intr, int id);
Функция демаскирования аппаратного прерывания. Значение аргументов аналогично InterruptMask().
#include <sys/neutrino.h>
int InterruptWait( int flags, const uint64_t * timeout);
Функция ожидания произвольного аппаратного прерывания. Аргументы должны быть 0 и NULL – зарезервированы для будущего использования.
Рассмотрим теперь примеры работы с аппаратными прерываниями в QNX.
3.1. Транзитная программа вывода текущего времени
interrupt1.c
#include <sys/neutrino.h>
#include <time.h>
int cnt;
struct sigevent curtime;
time_t timeof;
char mtimeof[12];
//обработчик аппаратного прерывания: возвращает указатель на связанную с этим //прерванием структуру
const struct sigevent * handler (void* area, int id)
{
cnt++;
// обработчик вызывается раз в 1 мс(используем программный делитель)
if(cnt == 1000)
{
cnt = 0;
return(&curtime);
}
else return(NULL);
}
int main()
{
int id, i = 0;
// для работы с аппаратными прерываниями нить должна получить особые полномочия I/O
ThreadCtl(_NTO_TCTL_IO, 0);
// прерыванию соответствует специфический тип оповещения, указываемый в приписанном // к нему объекту структуры sigevent
curtime.sigev_notify = SIGEV_INTR;
id = InterruptAttach( 0, &handler, NULL, NULL, 0);
for (i=0; i<7; i++)
{
InterruptWait(0, NULL);
timeof = time(NULL);
strftime(mtimeof, 12, " %T", localtime(&timeof));
printf( " %s\n", mtimeof);
}
InterruptDetach( id );
return 0;
}
Результат выполнения программы:
# make interrupt1
cc interrupt1.c -o interrupt1
# ./interrupt1
01:19:25
01:19:26
01:19:27
01:19:28
01:19:29
01:19:30
01:19:31
#
3.2. Перехват прерывания от клавиатуры
Модификация транзитной программы вывода текущего времени, выход осуществляется по нажатию клавишы «Esc».
interrupt2.c
#include <sys/neutrino.h>
#include <time.h>
#include <hw/inout.h>
int cnt, flag = 0, key = 0;
struct sigevent curtime;
time_t timeof;
char mtimeof[12];
const struct sigevent *handler (void* area, int id)
{
if( key == 1) // нажата клавиша ‘Esc’
{
flag = 1;
return(&curtime);
}
cnt++;
if(cnt == 1000)
{
cnt = 0;
return(&curtime);
}
else return(NULL);
}
// обработчик прерывания от клавиатуры
const struct sigevent *keyboard (void* area, int id)
{
// получение скан-кода нажатой клавиши по опросу 8-битного порта 0x60
key = in8(0x60);
return(NULL);
}
int main()
{
int id1, id2, i = 0;
ThreadCtl(_NTO_TCTL_IO, 0);
curtime.sigev_notify = SIGEV_INTR;
id1 = InterruptAttach( 0, &handler, NULL, NULL, 0);
id2 = InterruptAttach( 1, &keyboard, NULL, NULL, 0);
while(1)
{
if( flag == 1) break;
InterruptWait(0, NULL);
timeof = time(NULL);
strftime(mtimeof, 12, " %T", localtime(&timeof));
printf( " %s\n", mtimeof);
}
InterruptDetach( id1 );
InterruptDetach( id2 );
return 0;
}
Результат выполнения программы:
# make interrupt2
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.