Программирование микросекундных задержек в Linux

Форум для линуксоидов

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Программирование микросекундных задержек в Linux

Post by Shaos »

Представим что мы работаем в Linux на PC и нам нужны задержки с точностью до единиц микросекунд (напомню, что микросекунда - это которых один миллион в одной секунде) - скажем для того чтобы выдерживать нужные промежутки времени для управления программатором пиков. Как это сделать если точность клоков и шедулеров в Linux всего 4 миллисекунды (напомню, что миллисекунда - это которых одна тысяча в одной секунде) или говоря на языке частот 250 Гц?...

Вот решение полученное мной после нескольких часов мучительных блужданий и поисков ;)

Code: Select all

#include <time.h>

long int max_timer_error = 0;
long int firstsec = 0;

unsigned long int myclock(void)
{
 int r;
 struct timespec ts;
 ts.tv_sec = 0;
 ts.tv_nsec = 0;
 r = clock_gettime(CLOCK_REALTIME,&ts);
 if(firstsec==0) firstsec = ts.tv_sec;
 ts.tv_sec -= firstsec;
// printf("clock_gettime -> %i %is %ins\n",r,ts.tv_sec,ts.tv_nsec);
 return ts.tv_sec*1000000 + ts.tv_nsec/1000;
}

void us_delay(int us)
{
 struct timespec ts,tts;
 unsigned long int time_us,stop_us;
 if(us<=0) return;
 time_us = myclock();
 stop_us = time_us + us;
 while(time_us < stop_us)
   time_us = myclock();
 time_us -= stop_us;
 if(time_us > max_timer_error)
   max_timer_error = time_us;
}

void ms_delay(int ms) 
{
 us_delay(ms*1000);
}
us_delay(us) - задержка в микросекундах
ms_delay(ms) - задержка в миллисекундах

при сборке надо указать ключик -lrt

в коце работы программы можно напечатать ошибку в микросекундах - max_timer_error - она может быть достаточно большой (до нескольких миллисекунд) если системе во время работы задерживательных функций зачем-то понадобилось что-то поделать - при этом управление у нашей программы отбирается на некоторое непредсказуемое количество времени разумной длины (не в реал-тайм системе работаем однако) - но для работы программатора пиков и этого оказалось достаточно :lol:
Я тут за главного - если что шлите мыло на me собака shaos точка net
Romanich
Banned
Posts: 608
Joined: 12 Oct 2006 16:44

Post by Romanich »

а не судьба использовать 64-битный счётчик тактов ядра CPU? ;)
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Romanich wrote:а не судьба использовать 64-битный счётчик тактов ядра CPU? ;)
Ну во-первых такой счётчик есть только начиная с Pentium (я именно его и использовал в России когда делал точные таймеры в программе противоаварийной автоматики в промконтроллерах на основе MicroPC), а во-вторых такой подход не выглядит стандартным - это ведь должно по возможности работать везде где запускается Линукс ;)
Я тут за главного - если что шлите мыло на me собака shaos точка net
Romanich
Banned
Posts: 608
Joined: 12 Oct 2006 16:44

Post by Romanich »

Shaos wrote: Ну во-первых такой счётчик есть только начиная с Pentium
ИМХО старые машины нет смысла поддерживать! Давайте теперь для ATmega128 писать софт, работающий на AT90S2313 :) Где приемущества современных CPU тогда?
Shaos wrote: во-вторых такой подход не выглядит стандартным - это ведь должно по возможности работать везде где запускается Линукс ;)
разве проблемно в линухе подобное сделать? или в 0-й уровень он не пустит? ;)
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Romanich wrote:
Shaos wrote: во-вторых такой подход не выглядит стандартным - это ведь должно по возможности работать везде где запускается Линукс ;)
разве проблемно в линухе подобное сделать? или в 0-й уровень он не пустит? ;)
Линух не только на x86 работает ;)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24083
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Post by Shaos »

Shaos wrote:
Romanich wrote:а не судьба использовать 64-битный счётчик тактов ядра CPU? ;)
Ну во-первых такой счётчик есть только начиная с Pentium (я именно его и использовал в России когда делал точные таймеры в программе противоаварийной автоматики в промконтроллерах на основе MicroPC), а во-вторых такой подход не выглядит стандартным - это ведь должно по возможности работать везде где запускается Линукс ;)
Вспомнил ещё один аргумент против - чтобы правильно рассчитать время в таком методе надо точно знать частоту процессора - на той работе я использовал константу т.к. наши MicroPC использовали одну и ту же материнскую плату с впаянным намертво процом - в случае Линукс это уже не прокатит.
Я тут за главного - если что шлите мыло на me собака shaos точка net