Изучение принципов обработки аппаратных прерываний. Логика взаимодействия процессора и контроллера прерываний, страница 12

Результат обработки (ASCII-символ и скан-код) помещается в клавиатурный буфер, расположенный в ОЗУ. В случае переполнения буфера очередное слово не записывается и подается звуковой сигнал.

Кроме обычного способа (нажатия одной клавиши), любой символ можно ввести в буфер с помощью Alt-набора. Для этого его код в десятичной системе набирается на цифровой клавиатуре при нажатой клавише ALT, результат заносится в буфер по отпускании ALT. При таком способе в буфер будет занесен нулевой скан-код, что отличает Alt-набор от обычного ввода.

Для получения доступа к памяти устройства(клавиатура)  используют функции in*()/out*().

Кодовая таблица преобразования скан-кода в ASCII-код находится в файле /usr/include/photon/keycode.h

Пример содержимого файла keycode.h:

/*

* Keyboard codes for Key caps and Key symbols

*/

#define KEYCODE_PC_KEYS                                         UNICODE_PRIVATE_USE_AREA_FIRST + 0x1000

#define KEYCODE_PAUSE                       (KEYCODE_PC_KEYS + 0x13)

#define KEYCODE_SCROLL_LOCK                 (KEYCODE_PC_KEYS + 0x14)

#define KEYCODE_PRINT                       (KEYCODE_PC_KEYS + 0x61)

#define KEYCODE_SYSREQ                      (KEYCODE_PC_KEYS + 0x6a)

#define KEYCODE_BREAK                       (KEYCODE_PC_KEYS + 0x6b)

#define KEYCODE_ESCAPE                      (KEYCODE_PC_KEYS + 0x1b)

#define KEYCODE_BACKSPACE                   (KEYCODE_PC_KEYS + 0x08)

#define KEYCODE_TAB                         (KEYCODE_PC_KEYS + 0x09)

#define KEYCODE_BACK_TAB                    (KEYCODE_PC_KEYS + 0x89)

#define KEYCODE_KP_DELETE                   (KEYCODE_PC_KEYS + 0xae)

#define KEYCODE_F1                          (KEYCODE_PC_KEYS + 0xbe)

#define KEYCODE_F2                          (KEYCODE_PC_KEYS + 0xbf)

#define KEYCODE_F3                          (KEYCODE_PC_KEYS + 0xc0)

#define KEYCODE_CAPITAL_A                   UCS_LATIN_CAPITAL_LETTER_A

#define KEYCODE_CAPITAL_B                   UCS_LATIN_CAPITAL_LETTER_B

#define KEYCODE_CAPITAL_C                   UCS_LATIN_CAPITAL_LETTER_C

#define KEYCODE_CAPITAL_D                   UCS_LATIN_CAPITAL_LETTER_D

#define KEYCODE_I                           UCS_LATIN_SMALL_LETTER_I

#define KEYCODE_J                           UCS_LATIN_SMALL_LETTER_J

#define KEYCODE_K                           UCS_LATIN_SMALL_LETTER_K

3).  Пример использования функций InterruptAttach() c ненулевыми параметрами [2].

interrupt0.c

#include <sys/neutrino.h>

#include <time.h>

int cnt;

const struct sigevent *handler (void* arg, int id)

{

struct sigevent *hand_even = (struct sigevent *)arg;

cnt++;

if(cnt == 1000)

{

cnt = 0;

return(hand_even);

}

else  return(NULL);

}

int main()

{

time_t timeof;

char mtimeof[12];

struct sigevent event;

int id, i = 0;

ThreadCtl(_NTO_TCTL_IO, 0);

event.sigev_notify = SIGEV_INTR;

id = InterruptAttach( 0, handler, &event, sizeof(event), 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 interrupt0

cc     interrupt0.c   -o interrupt0

# ./interrupt0

00:50:22

00:50:23

00:50:24

00:50:25

00:50:26

00:50:27

00:50:28

#

4 . Выводы

Попробуем сравнить результаты работы в DOS и QNX. Низкий уровень ассемблерных приложений предоставляет весьма широкие возможности по организации перехвата аппаратных прерываний в DOS. Так мы можем получить информацию о процессе, у которого мы перехватываем контроль над прерыванием. В QNX эта информация скрыта. В QNX же сложность ОС накладывает тот отпечаток на средства API, что необходимо контролировать поведение обработчика в многопроцессной среде.

Хочется отметить наличие в API QNX очень удобной функции InterruptWait(), которая позволяет определять момент выхода из обработчика прерывания без дополнительных нагромождений из циклов проверок и контрольных флагов.

5 . Источники информации

1). Программирование приложений реального времени для исполнения в среде операционной системы реального времени QNX/Neutrino2(часть II): О.Л. Никольский – Брянск,2007.

2).

“Writing interrupt handlers”