Написание потоков реального времени Linux 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Написание потоков реального времени Linux



Потоки являются легкими процессами, которые разделяют адресное пространство ядра. В принципе поток управления ядром Linux RT (один для CPU), также является потоком Linux RT.

В Linux RT, все потоки разделяют адресное пространство ядра Linux. Для создания потока используйте функцию:

#include <pthread.h>

int pthread_create (pthread_t * thread,

pthread_attr_t * attr,

void * (*start_routine)(void *),

void * arg);

 

Замечание. Эта функция должна быть вызвана только из потока ядра Linux (например, в функции init_module()).

Поток создается путем использования объекта атрибута в параметре "attr". Если этот параметр равен NULL, то используются атрибуты по умолчанию. Посмотри также функций POSIX:

pthread_attr_init(3), pthread_attr_setschedparam(3),

pthread_attr_getschedparam(3),

и функций относящихся к RTL.

pthread_attr_getcpu_np(3), pthread_attr_setcpu_np(3)

ID созданного потока сохраняется в параметре "thread". Параметр start_routine является указателем на функцию, который определяет код потока. Параметр “arg” определяет параметров функции.

Чтобы удалить поток должна быть использована RTL-функция:

int pthread_delete_np (pthread_t thread);

Поток перестает работать немедленно.

 

Планировщик потоков

RTL определяет способ выполнения кода потока в определенные моменты времени (расписание). Linux реального времени имеет несколько таймеров, которые могут быть использованы для ведения расписания выполнения потоков. Чтобы заметить очередное чтение времени используйте функцию:

int clock_gettime (clockid_t clock_id, struct timespec *ts);

Параметр clock_id является идентификатором таймера.

Параметр ts - место для сохранения считанного значения.

struct timespec {

time_t tv_sec; /* seconds */

long tv_nsec /* nanoseconds */

};

 

Замечание. Текущие поддерживаемый таймер:

- CLOCK_UST (Unadjusted System Time). Этот таймер никогда не регулируется и не обнуляется. Этот таймер является очень чувствительным таймером.

- CLOCK_REALTIME. Стандартный таймер реального времени POSIX. В текущем состоянии этот таймер такой же, что и CLOCK_UST. Было запланировано, что этот таймер будет считать мировое время в будущих версиях RTL.

CLOCK_8254. Используется для ведения расписания в не SMP-машинах.

CLOCK_APIC. Используется в SMP-машинах. Показание этого таймера соответствует на показания таймера APIC процессора, который выполняет функцию clock_gettime. Вы не можете считывать и установить APIC-таймер других процессоров.

С помощью функции rtl_getschedclock(3) вы можете выбрать таймер, которого использует планировщик для ведения расписания

Linux реального времени использует планировщик управляемый приоритетами.

В этом планировщике, поток с наибольшим приоритетом будет выполняться первым. Если два потока имеют одинаковый приоритет, то который из них будет выбран не известен. Приоритет потока может быть изменен во время создания потока с помощью функции pthread_attr_setschedparam(3)или потом с помощью функции:

int pthread_setschedparam (pthread_t thread, int policy,

const struct sched_param *param);

Параметр policy в этих версиях RTL не используется, но должен быть определен как SCHED_FIFO для совместимости с будущими версиями.

Структура sched_param содержит объект параметра потока. Большие значения соответствуют к большему приоритету. Используйте функций

sched_get_priority_max(3) и sched_get_priority_min(3)

для определения возможных значений приоритета.

Чтобы поток реального времени выполнялся периодически используйте следующую функцию:

int pthread_setperiod_np (pthread_t thread,

const struct itimerspec *its);

 

struct itimerspec {

struct timespec it_interval; /* Период таймера */

struct timespec it_value; /* пределы таймера */

};

 

Эта функция отмечает поток как периодическим. Параметр “its” определяет время вызова потока: Поле it_value определяет время первого обращения;

Поле it_interval определяет время периода потока. Период может быть 0, который соответствует одноразовому вызову потока.

Действующее время выполнения таймера может быть получен:

int pthread_wait_np(void);

Эта функция останавливает выполнения вызова потока, до тех пор не достигнута время определенное в функции pthread_setperiod_np().

 

Простейшая программа реального времени "Hello World"

#include <rtl.h>

#include <time.h>

#include <pthread.h>

 

pthread_t thread;

 

void * start_routine (void * arg)

{

struct sched_param p;

p. sched_priority = 1;

pthread_setschedparam (pthread_self(), SCHED_FIFO, &p);

 

pthread_make_periodic_np (pthread_self(),

gethrtime(), 500 000 000);

 

while (1)

{

pthread_wait_np ();

rtl_printf("I'm here; my arg is %x\n", (unsigned) arg);

}

return 0;

}

 

int init_module (void) {

return pthread_create (&thread, NULL, start_routine, 0);

}

 

 

void cleanup_module (void) {

pthread_delete_np (thread);

}

 

Записывайте эту программу в файл hello.c, копируйте любой файл rtl.mk из дистрибутива в ту же папку и компилируй программу вызовом команды:

Make -f rtl.mk hello.o

Замечание. Для успешной компиляции и инсталляции вы должны иметь Linux реального времени.

Замечание. Эта программа может быть найдена в файле examples/hello.

 

Если на вашем компьютере загружены модули таймера (rtl_time.o) и планировщика (rtl_sched.o), то для запуска потоков вы можете использовать команду:

Insmod hello.o

Вы должны увидеть вывод сообщений потока. Для остановки программы выполните команду:

Rmmod hello

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 367; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.226.96.61 (0.008 с.)