QNX RTP Logo QNX Realtime Platform: Русский Портал QNX
Thursday, 20 Nov 2008 18:45
Меню

Проект OpenNET - все о Unix
Концепция времени в Neutrino Print E-mail
Brian Stecher, перевод qnx.org.ru team

В связи с появлением нескольких сотен тысяч новых пользователей и разработчиков, мы абсолютно уверены, что у вас появятся вопросы по программированию. Чтобы помочь вам глубже ознакомиться с технологией программирования в реальном времени, мы решили объяснить вам концепцию времени в Neutrino.

Каждый момент времени для микроядра Neutrino - это такт. Такт измеряется в миллисекундах; его начальная длительность определяется частотой вашего процессора. Если ваш процессор работает на частоте 40 Мгц или выше, то длительность одного такта - одна миллисекунда. Для более медленных процессоров длительность такта 10 миллисекунд. Изменить длительность такта программно можно функцией ClockPeriod().

Это очень важно при обращении к функциям ядра, приостанавливающим выполнение процесса. Это такие функции, как select(), alarm(), nanosleep(), nanospin(), sigaction(), delay() , это также и все функции работы с таймерами ( timer_*() ). Обычно мы используем эти функции напрямую : "Остановить на 8 секунд", "Остановить на 1 минуту" и т.д. К сожалению, если вы запросите "Остановить на 1 милисекунду , 10000 раз", вы не получите ожидаемого результата.

Выполнится ли этот код за одну секунду ?


void OneSecondPause()
{
   for ( i=0; i<1000; i++ )
    delay(1); /* Ждать 1000 милисекунд */
} 

К сожалению, нет, этот код не вернет управление через одну секунду на IBM PC. Скорее всего, он выполнится за три секунды. Фактически, когда вы вызываете функции nanosleep() или select() с аргументом в n милисекунд, это может занять от n милисекунд до бесконечности.

А почему это функция выполняется ровно за три секунды ?

То, что вы видите, называется "ошибка квантования таймера". Это столь обычно, что даже зарегистрировано в стандарте расширений реального времени POSIX (1003.1b-1993/1003.1i-1995). В нем говорится, что можно ждать дольше, но нельзя ждать меньше. Я уверен, что все вы понимаете, что преждевременное срабатывание таймера нежелательно.

Так как мы вызываем delay() асинхронно с прерываением системного таймера, это означает, что мы должны добавить один такт, чтобы убедиться, что мы отмеряем время корректно ( представьте себе, что мы этого не делаем, и однотактовая задержка была запрошена до прерывания таймера). Обычно это добавляет половину милисекунды каждый раз, но в приведенном примере мы должны синхронизироваться с таймером каждый раз, что приводит к милисекундной задержке каждый раз.

Это занимает 2 секунды, откуда берется еще одна ?

Это проблема возникает из-за того, что когда мы запрашиваем задержку в одну милисекунду, мы получаем задержку меньше - это зависит от системного таймера. На IBM PC длительность одного такта 999,847 наносекунд, То есть мы получаем:

1,000,000 ns + 999,847 ns = 1,999,847 ns реальной задержки

1,999,847 ns / 999,847 ns = 2.000153 ns - с учетом времени ожидания таймера

В итоге каждый раз delay (1) в действительности ожидает:

999,847 ns * 3 = 2,999,541 ns

Умноженное на 1000 это дает полное время 2.9999541 секунды.

А этот код будет работать ?


void OneSecondPause() 
{ 
   for ( i=0; i<100; i++ ) delay(10); 
   // Ждать 1000 милисекунд
} 

Да, вы получите очень близкое к требуемому значение, ошибка будет составлять не более 1/10 секунды.

В заключение...

Конечно, это простейшая ошибка, но скорее всего с начала вы столкнетесь именно с такими! Не позволяйте себе останавливаться на таких вещах - когда вы видите, что что-то должно работать, но не работает, а в документации об этом не сказано - обращайтесь в конференции - там вам всегда помогут! Ваши разработки будут идти гораздо лучше - ведь мы знаем, что наша документация далека от совершенства.

Original document:
http://qdn.qnx.com/support/articles/quantization.html

[Вернуться к списку]
©   2000-2003 Команда проекта QNX.ORG.RU // QNX.ORG.RU Team
Авторы проекта: Дмитрий Алексеев [dmi] и Дмитрий Васильев. Техническое сопровождение проекта: Игорь Сорокин [isorokin]. Информационное сопровождение: Дмитрий Алексеев [dmi]
QNX - зарегистрированная торговая марка QNX Software Systems, Ltd., Canada. Остальные упоминаемые на сайте торговые марки и логотипы являются исключительно собственностью их уважаемых владельцев. Ничьи права не затронуты. Материалы сайта не могут быть скопированы и где-либо использованы в той или иной форме без письменного разрешения разработчиков сайта.
Powered by Mambo Open Source