Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву
Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Программирование в режиме реального времениСодержание книги
Поиск на нашем сайте Программирование в режиме реального времени Модули Linux Эта версия Linux реального времени поддерживает загрузку программ реального времени в виде модулей Linux. Исходный файл модуля Linux является обычным С файлом, в котором функция main() заменен парой функций init/cleanup: int init_module(); Эта функция вызывается, когда модуль загружается в ядро. Она должна вернуть 0, а в случае ошибки отрицательное число. void cleanup_module(); Эта функция вызывается, когда модуль разгружается. Компилированный модуль загружается в ядро с помощью команды insmod(1).
Написание потоков реального времени 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
Использование прерываний В Linux реального времени имеется два типа прерываний: аппаратные и программные. Программные прерывания являются нормальными прерываниями ядра Linux. Они имеют преимущество, что некоторые функции ядра Linux могут быть вызваны безопасно в процедурах обработки прерывания (некоторые из них зависят от версии ядра). Однако, во многих задачах они не обеспечивают жесткого исполнения в реальном времени, они могут задерживаться чем допустимое время задержки. Аппаратные прерывания (прерывания реального времени) имеют намного меньше задержку. Однако, как и потоки реального времени, они имеют ограниченный набор функций, которые могут быть вызваны в процедурах обработки прерываний. Решением этой проблемы является разделение функциональности между аппаратными и программными прерываниями.
#include <rtl_core.h>
int rtl_request_irq (unsigned int irq, unsigned int (*handler)(unsigned int, struct pt_regs *)); int rtl_free_irq (unsigned int irq);
Эти две функции используются для инсталляции и снятия процедур обработки аппаратных прерываний для определенных прерываний. Страницы руководства пользователя описывает эту работу в подробностях. Потоки реального времени вызываемые прерываниями могут быть созданы использованием функций запуска и остановки: int pthread_wakeup_np (pthread_t thread); int pthread_suspend_np (void); Поток управляемый прерыванием вызывает функцию pthread_suspend_np и блоков. Позже, процедура обработки прерывания вызывает функцию pthread_wakeup_np для этого потока. Поток будет запущен до тех пор, пока не выполнится следующий вызов функции pthread_wakeup_np.
Программные прерывания int rtl_get_soft_irq (void (*handler)(int, void *, struct pt_regs *), const char * devname); Эта функция размещает виртуальный номер прерывания и задает для него функцию как обработчик прерывания. Позже, это виртуальное прерывание будет запущен с помощью функции: void rtl_global_pend_irq(int ix); Эта функция безопасна при использовании в потоках реального времени и в прерываниях реального времени. Функция void free_irq(unsigned int irq, void *dev_id); является функцией ядра Linux, который снимает процедуру обработки прерывания для прерывания "irq". Для программных прерываний параметр dev_id должен быть равен 0. Программные прерывания использованы в реализации FIFO в Linux реального времени (файл fifos/rtl_fifo.c).
Написание планировщика и изменение стандартного планировщика Эта сложная тема должен записываться позже. Здесь только некоторые точки для отталкивания: Планировщик реализован в файле: scheduler/rtl_sched.c и в файлах зависимых от архитектуры (папки include/arch-i386 и scheduler/i386). Решение функциональности планировщика определена в функции rtl_schedule(). Путем изменения этой функции можно изменить политику планирования. Программирование в режиме реального времени Модули Linux Эта версия Linux реального времени поддерживает загрузку программ реального времени в виде модулей Linux. Исходный файл модуля Linux является обычным С файлом, в котором функция main() заменен парой функций init/cleanup: int init_module(); Эта функция вызывается, когда модуль загружается в ядро. Она должна вернуть 0, а в случае ошибки отрицательное число. void cleanup_module(); Эта функция вызывается, когда модуль разгружается. Компилированный модуль загружается в ядро с помощью команды insmod(1).
|
||
|
Последнее изменение этой страницы: 2017-02-07; просмотров: 314; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 216.73.216.10 (0.006 с.) |