Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Аппаратные прерывания таймера.  (Прочитано 76427 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« : 12-01-2015 15:29 » 

Доброго вечера.

Появился вопрос, вот какой:
В консоли набираю:
   cat /proc/interrupts
Выводится следующее:

CPU0       CPU1       CPU2       CPU3       
  0:         23          0          0          0   IO-APIC-edge      timer
  1:          2          0          0          0   IO-APIC-edge      i8042
  7:          0          0          0          0   IO-APIC-edge      parport0
  8:         19          0          0          0   IO-APIC-edge      rtc0
  9:          0          0          0          0   IO-APIC-fasteoi   acpi
 14:          0          0          0          0   IO-APIC-edge      platform
 15:          0          0          0          0   IO-APIC-edge      platform
 16:      27968          0          0          0   IO-APIC-fasteoi   nouveau
 17:        142          0          0          0   IO-APIC-fasteoi   snd_hda_intel
 18:     109369          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb1, i801_smbus
 23:      38351          0          0          0   IO-APIC-fasteoi   ehci_hcd:usb3
 41:      42177          0          0          0   PCI-MSI-edge      ahci
 42:         10          0          0          0   PCI-MSI-edge      mei_me
 43:          0          0          0          0   PCI-MSI-edge      xhci_hcd
 44:     404711          0          0          0   PCI-MSI-edge      snd_hda_intel
 45:      15614          0          0          0   PCI-MSI-edge      eth0
NMI:          0          0          0          0   Non-maskable interrupts
LOC:     432749     414270     433098     389836   Local timer interrupts
SPU:          0          0          0          0   Spurious interrupts
PMI:          0          0          0          0   Performance monitoring interrupts
IWI:      32759      48261      25700      19068   IRQ work interrupts
RTR:          2          0          0          0   APIC ICR read retries
RES:     341994     590928     516623     506116   Rescheduling interrupts
CAL:         27         29         34         31   Function call interrupts
TLB:       1198       1705       1356       1873   TLB shootdowns
TRM:          0          0          0          0   Thermal event interrupts
THR:          0          0          0          0   Threshold APIC interrupts
MCE:          0          0          0          0   Machine check exceptions
MCP:         30         30         30         30   Machine check polls
ERR:          0
MIS:          0
Как я понял, значения в ячейках - это счётчики состоявшихся прерываний с начала старта системы (ядра). Собственно вопрос: почему IRQ0 - всего 23 события?? Повторные вызовы это число не меняют. То есть, либо учёт прерываний системного таймера не идёт, либо сам таймер (точнее этот его канал) не используется. Если не используется, тогда что делает обработчик timer?

Добавлено через 18 часов, 31 минуту и 59 секунд:
В общем почитал немного, как оказалось, не на всех компьютерах главным таймером является обработчик IRQ0 и 8. Если присутствует APIC, то появляется возможность его использования. Главным же таймером является Local timer (LOC).

Вопросов, тем не менее меньше не стало:
1) Как написать обработчик для LOC? Литература по этой теме имеется?
2) Ядро может динамически менять частоту вызовов LOC? Или же она неизменна для конкретной версии ядра, то есть изменить можно, но через пересборку ядра.
3) Какой из процессоров будет выполнять обработчик неясно?
« Последнее редактирование: 13-01-2015 10:01 от Aether » Записан
darkelf
Молодой специалист

no
Offline Offline

« Ответ #1 : 13-01-2015 10:55 » 

Aether, там ещё есть технология tickless (https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Power_Management_Guide/Tickless-kernel.html), которая позволяет уменьшить количество прерываний от таймера. А вообще - зачем Вам надо 1, 2 да и 3-тье?
Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 13-01-2015 13:12 » 

В пространстве пользователя можно использовать паузы, таймеры... сейчас пишу модуль, нужно обеспечить заданную скорость выполнения, например, 200 раз в секунду обновить значение такого-то порта, поэтому, самое простое, что пришло в голову использовать сис. таймер - его скорость много больше требуемой, поэтому функция обработчик ведёт свой счёт, когда он достигает заданного значения, то происходит обнуление счётчика и обновление содержимого порта. Написанная программа успешно работает на Celeron 233, там, кстати, IRQ 0 скачет десятками тысяч, однако, перенос программы на i5 изменил суть дела.
Хотелось бы не городить, а делать просто и ясно.
Записан
darkelf
Молодой специалист

no
Offline Offline

« Ответ #3 : 13-01-2015 14:03 » 

Если Вам нужно обеспечить гарантированное выполнение 200 раз в секунду, боюсь, штатный Linux Вам не подходит. Надо брать ОС РВ, или на худой конец надстройку над ядром Linux-а по типу RTLinux (http://en.wikipedia.org/wiki/RTLinux).
Btw на i5 и на Celeron233 версии ядра одинаковые?

Добавлено через 5 минут и 47 секунд:
Поискал тут, возможно, это то, что Вы ищете : ядерные таймера, вплоть до таймеров высокого разрешения.
http://www.ibm.com/developerworks/library/l-timers-list/
« Последнее редактирование: 13-01-2015 14:12 от darkelf » Записан
Aether
Специалист

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 13-01-2015 15:33 » new

гарантированное выполнение 200 раз в секунду,
Только без фанатизма) Даже, когда используется сис. таймер я пропускаю вызовы - жду ближайшего момента, то есть точно 200Гц не будет, будет очень близко, условно, 199,99, а может и грубее. И это нормально.

Btw на i5 и на Celeron233 версии ядра одинаковые?
Нет, уже, исходя из того, что на i5 - x64, а на 233 - x386. Сейчас под рукой нету, чтобы проверить, вроде: на i5 3.17, а на 233 - 2.6.
Возможно, можно как-то хитро пересобрать ядро, чтобы timer работал по-старинке, но это выглядит криво.

Код:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>

MODULE_LICENSE("GPL");

static struct timer_list my_timer;

void my_timer_callback( unsigned long data )
{
  printk( "my_timer_callback called (%ld).\n", jiffies );
}

int init_module( void )
{
  int ret;

  printk("Timer module installing\n");

  // my_timer.function, my_timer.data
  setup_timer( &my_timer, my_timer_callback, 0 );

  printk( "Starting timer to fire in 200ms (%ld)\n", jiffies );
  ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(200) );
  if (ret) printk("Error in mod_timer\n");

  return 0;
}

void cleanup_module( void )
{
  int ret;

  ret = del_timer( &my_timer );
  if (ret) printk("The timer is still in use...\n");

  printk("Timer module uninstalling\n");

  return;
}
Я не знал, что таймером можно пользоваться внутри модуля, буду пробовать. Спасибо)
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines