Чтение 4 мкс +5 В TTL из параллельного порта - когда использовать прерывания ядра
У меня есть экспериментальная коробка с трюками, которые каждые 100 мсек или около того выдают 4 мсек импульса + 5 В на линии TTL. Точное время, когда это происходит, заранее неизвестно, но это важно - поэтому я хотел бы использовать компьютер Red Hat 5.3, который по сути запускает эксперимент для обслуживания этого TTL, и создать прославленную временную метку.
На данный момент я подключил TTL к выводу 13 параллельного порта (STATUS_SELECT
(одна из строк ввода на параллельном порту) в окне linux, порождает процесс при запуске эксперимента, используйте chrt
изменить запланированный приоритет на 99
то есть высокий, а затем просто опрашивать параллельный порт несколько раз в while
петля, пока булавка не станет высокой. Затем я создаю точную метку времени и неблокирующим способом записываю ее на диск.
Очевидно, что это неэффективно - иногда процесс приостанавливается, и TTL будет пропущен. Поскольку сам компьютер занят другими делами (а именно сбором данных из моего экспериментального набора - МРТ-сканера!), Это происходит довольно часто. Голосовать легко, но, наверное, плохо.
Мой вопрос таков: делать что-то быстро, когда происходит TTL, похоже на обычные вычисления, но, насколько я могу судить, иметь дело с прерываниями в linux, только если вы являетесь модулем ядра. Параллельный порт может генерировать прерывания, а библиотеки, такие как paraport, позволяют относительно быстро создавать модули ядра, где вы должны предоставить свой собственный обработчик.
Это лучший способ справиться с этой проблемой и создать точные (±25 мс) временные метки для эксперимента при каждом входе в TTL - написать модуль ядра, который предоставляет список недавних прерываний, где-то в /proc, и затем прочитать их с нормальным процессом позже? Разве этот подход не сработает и будет очень неэффективным с ЦП - или откроет пакет червей, чтобы сделать с приоритетом прерывания, о котором я не знаю?
Самое главное, похоже, что это должна быть решенная проблема - так ли это, и если да, то хотят ли какие-нибудь мудрые люди указывать мне правильное направление? Честно говоря, написание модуля ядра кажется сложной, рискованной работой для чего-то, что кажется простым.
1 ответ
Предпосылка о том, что "в linux можно работать только с прерываниями, только если вы являетесь модулем ядра", отвергает некоторые довольно распространенные и эффективные стратегии.
Простой способ действий при реагировании на прерывания в пользовательском пространстве (особенно в редких случаях) состоит в том, чтобы иметь драйвер, который создал устройство ядра (или в некоторых случаях узел sysfs), где либо read(), либо, возможно, пользовательский ioctl() из пользовательского пространства будет блокировать, пока не произойдет прерывание. Вы должны проверить, поддерживает ли драйвер параллельного порта по умолчанию это, но это очень часто встречается с драйверами GPIO на платах встроенного типа, и базовая схема может быть заимствована в параллельный порт - при условии, что оборудование поддерживает истинные прерывания.
Если цель - точная синхронизация, вы можете лучше настроить модуль ядра для записи там временной метки и реализовать механизм, в котором read() из пользовательского пространства блокирует до тех пор, пока не произойдет прерывание, а затем получает уже записанную метку времени ядра как читать данные - таким образом избегая переменной задержки пробуждения пространства пользователя и обращения к ядру, чтобы получить время.
Вы также можете рассматривать истинные последовательные порты локальной шины (если они есть) как интерфейс с поддержкой альтернативных прерываний в тех случаях, когда доступный параллельный порт является частичной или косвенной реализацией, которая их не поддерживает.
В ситуациях, когда ваш единственный доступный интерфейс - это что-то непрямое и с большой задержкой, например USB, или когда вам нужна большая независимость от хоста и операционной системы, тогда может действительно иметь смысл использовать внешний микроконтроллер. В этом случае вы, вероятно, попытаетесь установить часы микроустройства из хост-системы, а затем попросите его выдавать вам сообщения о метках времени каждый раз, когда он видит событие. Если вашему эксперименту нужны только временные метки, чтобы они были относительно друг друга в рамках данного экспериментального сеанса, это должно работать хорошо. Но если вам необходимо установить абсолютную синхронизацию времени через задержку USB, вам, возможно, придется провести тщательное измерение в обе стороны и затем оценить задержку, чтобы компенсировать ее (см. NTP для крайнего примера).