Здравствуйте. У меня впорос: можно ли под linux реалиовать миллисекундный интервальный таймер? Разрешение реал тайма вроде 10 000 мкс. И насколько это будет точно? Ведь если процесс запускать с высоким приоритетом всеравно возможны задержки за счет критических зон других модулей... И я вроде слышал что частота смены процессов тоже 100Hz, т.е 10 000 мкс...
Нашел такой вариант: http://kerneltrap.org/node/6750
Но как-то пока боюсь за него браться, я с uCLinux работаю недавно...
Обладатель платы LPC2478-S3E.
Думаю, реалтайм в пользовательском пространстве вряд ли получится получить, наверное лучше драйвер таймера написать/поправить - внести в него критичные для RT функции ...
Лет 5 назад пробовал поуправлять из юзерспейса железякой - требовались задержки более менее точные, ничего не получилось :) на осциллографе полный разброс был виден. Так что linux конечно не панацея для всего. Возможно что-то интересное можно найти тут http://www.xenomai.org/index.php/Main_Page или тут http://rt.wiki.kernel.org/index.php/Main_Page
правда я не знаю как они дружат с ядрами без mmu. Вообще поддерживаю Павла - так же наверно поступил бы - критичный код вынести в ядро и пользоваться свободными аппаратными таймерами с прерываниями.
Миллисекундный таймер на уровне ядра (с использованием прерывания от одного из таймеров) четко работать не будет. Я занимался портированием драйвера аналоговой телефонии DAHDI на платформу SAM9260 с полноценным Linux. В оригинале как раз использовались интервалы в 1 мс для переключения буферов DMA для захвата и воспроизведения звука, но на SAM9260 с таким интервалом наблюдалось переполнение буферов. Оказалось, что даже вызов функции printk() блокирует прерывания на время больше 1 мс.
Пришлось увеличить этот интервал до 10 мс.
А вы уверены что этот вызов вообще может что-то блокировать ? Насколько я знаю printk можно вызывать из любого контекста, даже в обработчике прерывания и она просто пишет сообщения в кольцевой буфер. Вы случайно не на консоль которая на dbgu выводили сообщения ? а то у нее наивысший приоритет судя по этому:
/*
* The default interrupt priority levels (0 = lowest, 7 = highest).
*/
static unsigned int at91sam9260_default_irq_priority[NR_AIC_IRQS] __initdata = {
7, /* Advanced Interrupt Controller */
>>> 7, /* System Peripherals */ <<<
Похоже я не прав - посмотрел kernel/printk.c - там много участков кода где отключаются прерывания. То что printk може вызываться в любом контексте - там просто восстанавливается прежнее состояние системы перед возвратом.
Действительно, сообщения выводились printk() с таким уровнем, что они попадали на консоль. Вы правы, проблема видимо в этом и есть: при выводе на консоль printk(), предварительно заблокировав все прерывания, вызывает драйвер консоли, а тот, в свою очередь, посылает их в последовательный порт DBGU. Драйвер последовательного порта в идеале должен бы работать через ПДП, чтобы не задерживать вызов printk, но похоже там все пишется посимвольно с поллингом флага - отсюда и задержка.
Действительно, сообщения выводились printk() с таким уровнем, что они попадали на консоль. Вы правы, проблема видимо в этом и есть: при выводе на консоль printk(), предварительно заблокировав все прерывания, вызывает драйвер консоли, а тот, в свою очередь, посылает их в последовательный порт DBGU. Драйвер последовательного порта в идеале должен бы работать через ПДП, чтобы не задерживать вызов printk, но похоже там все пишется посимвольно с поллингом флага - отсюда и задержка.
Действительно, сообщения выводились printk() с таким уровнем, что они попадали на консоль. Вы правы, проблема видимо в этом и есть: при выводе на консоль printk(), предварительно заблокировав все прерывания, вызывает драйвер консоли, а тот, в свою очередь, посылает их в последовательный порт DBGU. Драйвер последовательного порта в идеале должен бы работать через ПДП, чтобы не задерживать вызов printk, но похоже там все пишется посимвольно с поллингом флага - отсюда и задержка.