2013-11-30 3 views
3

Я работаю над модулем ядра Linux, который регистрирует обратный вызов для прерываний, которые поступают из пользовательской платы и помещает полученные данные в очередь за устройством char интерфейс, который будет обрабатываться приложением. Этот модуль должен постоянно контролировать и измерять прерывания и данные, поступающие с доски, даже если прерывание не поступает с платы, поэтому у него есть еще один обратный вызов, который запускается в соответствии со временем.Как добавить обратный вызов периодического таймера в модуле ядра Linux

Текущая реализация использует прерывание RTC как источник постоянного таймера. Я отключил драйверы ядра RTC (CONFIG_RTC_DRV_CMOS) и запросил IRQ 8 и перехватил обратный вызов таймера как обработчик прерываний RTC. Прерывания генерируются каждую секунду из чипа RTC.

Проблема заключается в том, что мы должны потерять часть возможностей Linux, чтобы управлять временем таким образом, потому что только один из rtc-cmos или модуль платы можно загрузить сразу (и, очевидно, мы выбрали модуль платы).

Ядро Linux от linux-source package, которое поставляется с стабилизатором Debian 7.2, которое находится в версии 3.2+46. Целевая архитектура - i386 PC.

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

  • Как-то делиться IRQ 8 между обоими модулями (может быть, как request_irq(8, rtc_handler, IRQF_SHARED, rtc_handler)?) Или обработчиками IRQ с цепью.
  • Поиск другого способа привязки обработчика от модуля ядра к прерыванию RTC, а не регистрации для IRQ 8.
  • Поиск другого источника событий таймера 1-секундного периода, который может использоваться из модуля ядра, возможно, есть стандартный API ядра для этого, я не знаю.

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

ответ

4

может быть, есть стандартное ядро ​​API для этого

Конечно есть. Необходимость таймера в модуле ядра, вероятно, не является чем-то необычным.

Я мало знаю об API, но знаю, что он существует. Если вы собираетесь написать модуль ядра правильно, вы должны получить книгу или еще что-нибудь; есть несколько. Во всяком случае, один традиционный метод был бы:

#include <linux/timer.h> 

schedule_timeout(jiffies); 

Это пассивный сон. Jiffies - это единица, основанная на 250 Гц в процессоре, хотя это может быть конфигурируемо. В этом заголовке есть и другие функции, вот a brief discussion с ядром 2.6, но я бы предположил, что 3.x все равно должен быть совместим с этим, так как большая часть источника, включая драйверы, старше этого. Конечно, есть простой способ узнать.

Jiffies, вероятно, прекрасно, если вы хотите задержать секунду. Гранулярность для пассивных сон на миллисекунде уровне - проблема с регулярным ядром из-за задержки планировщика, но также есть API-интерфейс с наносекундной гранулярностью в ktime.h (эта ссылка снова находится в ядре 2.6, но файл все еще датирован 2005 годом в 3.11 источник, поэтому не изменился).Имейте в виду, что в Linux также есть таймеры пользовательского пространства с наносекундной детализацией, но это не значит, что они действительно будут работать для синхронизации событий на этом уровне из-за задержки планировщика (и, по-видимому, это также верно для пассивных таймеров в пространстве ядра).

Вы можете получить доступ к RTC вместо того, чтобы использовать процессор/ядро ​​тикает, но есть некоторые недостатки:

  • Не все системы на самом деле есть.
  • Подходит для занятой петли.

И никаких реальных преимуществ. AFAIK RTC не считается более точным, чем клещи процессора.

Другой ресурс, который вы бы разумно использовать это Linux Kernel Mailing List (LKML), который является, где разработчики могут, и они отвечают на вопросы. Будьте осторожны, список имеет объем в сотни сообщений в день.

+0

Спасибо за отличный ответ, я перепишу и протестирую модуль с помощью таймера ядра и проинформирую вас о результатах. – aalizadeh

Смежные вопросы