
Использование разделяемой памяти
Для использования разделяемой памяти, вы можете использовать драйвер mbuff от Томас Мотелевский: motyl@stan.chemie.unibas.ch.
Этот драйвер включен в дистрибутив и размещен в папке drivers/mbuff. Руководство пользователя включен в пакет. Здесь я только вкратце описываю основных режимов оперирования.
Во первых, модуль mbuff.o должен быть загружен в ядро. Две функции используются для размещения блоков в разделяемую память и соединения с ним и затем для удаления из памяти.
#include <mbuff.h>
void * mbuff_alloc(const char *name, int size);
void mbuff_free(const char *name, void * mbuf);
В первую очередь функция mbuff_alloc вызывается с именем блока разделяемой памяти и размером блока. Число ссылок на этот блок установлен на 1. В случае успеха, возвращается указатель размещенного блока. В случае неудачи возвращается NULL.
Если блок с определенным именем уже существует, то функция возвращает указатель на этот блок, который может быть использован для доступа к этому блоку и увеличивает число ссылок на этот блок.
Функция mbuff_free рассоединяет mbuf из определенного буфера. Число ссылок уменьшается на 1. Когда это число достигает 0, то буфер удаляется из памяти.
Эти функции доступны для использования как из процессов Linux, так из потоков ядра Linux.
Замечание. Функции mbuff_alloc и mbuff_free не могут быть использованы в потоках реального времени. Они должны быть вызваны только в функциях init_module and cleanup_module.
Обеспечение взаимных исключений
Linux реального времени поддерживает POSIX функций семейства
pthread_mutex_ family (include/rtl_mutex.h).
В настоящее время доступны следующие функции:
pthread_mutexattr_getpshared(3),
pthread_mutexattr_setpshared(3),
pthread_mutexattr_init(3),
pthread_mutexattr_destroy(3),
pthread_mutexattr_settype(3),
pthread_mutexattr_gettype(3),
pthread_mutex_init(3),
pthread_mutex_destroy(3),
pthread_mutex_lock(3),
pthread_mutex_trylock(3),
pthread_mutex_unlock(3)
Замечание. Поддерживается только mutex тип PTHREAD_MUTEX_NORMAL.
Для примера посмотрите программу examples/mutex.
Доступ из потоков реального времени
к физической памяти и портам ввода/вывода
Эти возможности необходимы для программирования аппаратных средств компьютера.
Linux реального времени, как и обычный Linux поддерживает устройств /dev/mem ( справка командой man 4 mem) для получения доступа к физической памяти из потоков реального времени.
Программа открывает файл /dev/mem, вызывает функцию mmap, и продолжает читать и писать обозначенную область.
Программа в файле examples/mmap показывает, как все это делается.
Замечание. В модуле вы можете вызывать функцию mmap только в режиме Linux (например, в функции init_module()). Вызов функции mmap в потоке реального времени невозможно.
Функции доступа к портам ввода/вывод
описано для архитектуры х86
#include <asm/io.h>
// output a byte to a port
void outb(unsigned int value, unsigned short port);
// output a word to a port
void outw(unsigned int value, unsigned short port);
// read a byte from a port
char inb(unsigned short port);
// read a word from a port
short inw(unsigned short port);
Функции с суффиксом _р (например, out_p) обеспечивают маленькую задержку после чтения или записи порта. Эта задержка необходимо для работы некоторых ISA устройств на быстрых компьютерах.
Просмотри пример в файле examples/sound чтобы увидеть как некоторые функции используются для программирования часов реального времени и динамики компьютера.
Использование операций с вещественными числами
в потоках Linux реального времени
По умолчанию, использование операций с вещественными числами в потоках Linux реального времени запрещается. Вы должны использовать следующих функций реального времени для изменения статуса операций с вещественными числами:
int pthread_setfp_np (pthread_t thread, int flag);
Для разрешения операций с вещественными числами в потоках используйте флаг 1, а для запрещения – передайте 0.
Каталог examples/fp содержит различные примеры, которые используют вещественные числа и математическую библиотеку.
Соглашения по созданию симметричных многопроцессных задач
С точки зрения планировщика потоков, для каждого активного CPU, Linux реального времени организует отдельный Unix процесс.
В общем, функции управления потоками должны быть использованы только для потоков, которые запущены в локальном CPU. Заметными исключениями являются функции:
int pthread_wakeup_np (pthread_t thread);// Разбудить остановленный поток
int pthread_delete_np (pthread_t thread);// удаляет поток */
Связывание компонентов реального времени на Linux
Потоки реального времени разделяют общее адресное пространство с ядром Linux, в принципе могут вызывать функций ядра Linux. Однако, в общем случае это не безопасно, так как потоки реального времени могут запускаться даже тогда, когда прерывания от Linux отключены. Поэтому, только функции которые не могут изменить данных ядра Linux могут быть вызваны из потоков реального времени (например, функция vsprintf).
Чтобы обходить эти ограничения Linux реального времени предоставляют два механизма выполнения с задержкой: программные прерывания и очередь задач.
Использование прерываний
В 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.