Вход/Регистрация
Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform
вернуться

Кёртен Роб

Шрифт:

break;

 case IIR_RX:

/* Считать символ */

serial_rx = in8(base_reg + REG_RX);

break;

 case IIR_LSR:

/* Сохранить регистр состояния линии */

serial_lsr = in8(base_reg + REG_LS);

break;

 default:

break;

 }

 /* Никого не беспокоить */

 return (NULL);

}

Первое, что бросается в глаза, — что все переменные, к которым обращается ISR, должны быть объявлены как

volatile
. В с единственным процессором это делается не для блага обработчиков прерываний, а для облегчения жизни потокам, которые могут быть прерваны обработчиком прерывания в любой момент. Конечно, в многопроцессорной ЭВМ обработчики прерываний вполне могли бы выполняться одновременно с кодом потоков, и в таких случаях надо быть предельно осторожными с вещами подобного рода.

С помощью ключевого слова

volatile
мы указываем компилятору не кэшировать значения этих переменных, поскольку они могут быть изменены в любой точке выполнения программы.

Следующее, на что мы обращаем внимание — это прототип самого обработчика прерывания. Он обозначен как

const struct sigevent*
. Это говорит о том, что подпрограмма intHandler возвращает указатель на
struct sigevent
. Это стандарт для всех подпрограмм обработки прерываний.

Наконец, обратите внимание на то, что решение, передавать или не передавать событие потоку, принимает сам обработчик. Здесь мы генерируем событие только в случае прерывания по изменению регистра состояния модема (MSR) (событие определяется переменной event, которая передается обработчику прерывания в момент его подключения). Во всех других случаях мы игнорируем прерывание (и обновляем кое-какие глобальные переменные); однако, источник прерывания мы очищаем во всех случаях. Это выполняется считыванием порта ввода/вывода с помощью вызова in8.

Применение функции InterruptAttachEvent

Если бы мы должны были переписать вышеприведенную программу с применением функции InterruptAttachEvent, это бы выглядело так:

/*

 * Фрагмент int2.c

*/

#include <stdio.h>

#include <sys/neutrino.h>

#define HW_SERIAL_IRQ 3

#define REG_RX 0

#define REG_II 2

#define REG_LS 5

#define REG_MS 6

#define IIR_MASK 0x07

#define IIR_MSR 0x00

#define IIR_THE 0x02

#define IIR_RX 0x04

#define IIR_LSR 0x06

#define IIR_MASK 0x07

static int base_reg = 0x2f8;

int main(int arcgc, char **argv) {

 int intId; // Идентификатор прерывания

 int iir; // Регистр идентификации

// прерывания

 int serial_msr; // Сохраненное значение

// регистра состояния модема

 int serial_rx; // Сохраненное значение регистра

// приема

 int serial_lsr; // Сохраненное значение

// регистра состояния линии

 struct sigevent event;

 // Обычная настройка main...

 // Настроить событие

 intId = InterruptAttachEvent(HW_SERIAL_IRQ, &event, 0);

 for (;;) {

// Ждать события от прерывания

// (можно было использовать MsgReceive)

InterruptWait(0, NULL);

/*

* Определить (и очистить) источник прерывания

  • Читать дальше
  • 1
  • ...
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: