#include <sys/neutrino.h>
#include <time.h>
#include <hw/inout.h>
int cnt, flag = 0, key = 0;
int timeok = 0, dateok = 1;
struct sigevent curtime;
time_t timeof;
char mtimeof[12];
const struct sigevent *handler (void* area, int id)
{
switch(key)
{
case 1:
flag = 1;
return(&curtime);
case 2:
timeok = 1;
dateok = 0;
break;
case 3:
dateok = 1;
timeok = 0;
}
cnt++;
if(cnt == 1000)
{
cnt = 0;
return(&curtime);
}
else return(NULL);
}
const struct sigevent *keyboard (void* area, int id)
{
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);
if(timeok == 1)
{
strftime(mtimeof, 12, " %T", localtime(&timeof));
printf( " %s\n", mtimeof);
}
if(dateok == 1)
{
strftime(mtimeof, 12, " %D", localtime(&timeof));
printf( " %s\n", mtimeof);
}
}
InterruptDetach( id1 );
InterruptDetach( id2 );
return 0;
}
Результат выполнения программы:
# ./interrupt5
12/17/08
12/17/08
03:24:35
03:24:36
12/17/08
12/17/08
03:24:39
03:24:40
03:24:41
03:24:42
#
# ./interrupt5&
[1] 1310756
# 12/17/08
12/17/08
12/17/08
12/17/08
03:24:54
03:24:55
03:24:56
12/17/08
12/17/08
12/17/08
03:25:00
03:25:01
03:25:02
12/17/08
12/17/08
12/17/08
[1] + Done ./interrupt5
#
Независимо от способа запуска этой программы, неизменно получаем следующее: клавиатура блокируется до завершения работы этой программы. То есть при перехвате аппаратного прерывания состояние программы не играет роли.
Дополнительные исследования:
1).Типовые уровни прерываний IRQ и приоритеты прерываний устройств для платформы x86.
Запрос преры-вания IRQ |
Приоритет прерывания |
Устройство, вызывающее прерывание |
0* |
Высший 2 |
Канал 0 аппаратного таймера, отсчитывающий системные такты с периодом ClockPeriod() |
1* |
3 |
Клавиатура |
2* |
Каскадирование прерываний (перенаправление на второй контроллер 8259) |
|
3* |
12 |
Асинхронный порт COM2 (или COM4) |
4* |
13 |
Асинхронный порт COM1 (или COM3) |
Примечания.
− Работу с прерываниями имеет право выполнять только пользователь с правами root.
− Перед обращением к ядру для обработки прерываний поток должен получить права на операции с портами ввода/вывода и изменение флага прерываний процессора с помощью вызова ThreadCtl( _NTO_TCTL_IO, 0).
− Самые приоритетные запросы прерываний на платформе x86 жёстко закреплены за аппаратным таймером (IRQ0) и клавиатурой (IRQ1) и не могут использоваться для других целей [1].
2). Клавиатура
Контроллер клавиатуры соединен с системной шиной данных (XD-шиной) с помощью двух однобайтных регистров - входного и выходного буферов. Выходной буфер доступен только для чтения через 60h порт и хранит коды сканирования, полученные от клавиатуры или данные, прочитанные по запросу (команды контроллера).
Входной буфер доступен для записи через порты 64h (запись команд) и 60h (запись) данных.
При записи команды в 64h устанавливается флаг записи команды (в регистре состояния). Байты, записанные в 60h, и не являющиеся данными для команд контроллера системного блока, отсылаются по интерфейсу клавиатуры контроллеру клавиатуры.
Скан-код - номер, идентифицирующий расположение клавиши на клавиатуре.
Скан-коды, принятые от клавиатуры, по аппаратному прерыванию IRQ1 (вектор 09h) обрабатываются, и результат обработки помещается в буфер, из которого по программному прерыванию этот результат для дальнейшей обработки может быть извлечен значительно позже. BIOS INT 9h обрабатывает прерывания, вызванные приходом кодов нажатия и отпускания клавиш, анализируя принятый скан-код с учетом состояния флагов и комбинации клавиш альтерации SHIFT, CTRL, ALT, CAPSLOCK, NUMLOCK.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.