Но куда интереснее у них возможность: можем писать realtime приложения в стандартном API POSIX, когда Xenomai маскирует многие системные вызовы Linux.
Она у них появилась, похоже, только в последние годы ... из 15 лет развития Xenomai...
Идея состоит в том, что основные системные вызовы (man -s2 xxx) поступают не в Linux kernel, а для них написаны оболочки (wrappers) и они перенаправляются в микроядро Xenomai, там модифицируются, после чего отправляются в ядро Linux.
Код: Выделить всё
root@raspberrypi:/usr/xenomai/include/cobalt# cat *.h | grep COBALT_DECL
COBALT_DECL(int, open(const char *path, int oflag, ...));
COBALT_DECL(int, open64(const char *path, int oflag, ...));
COBALT_DECL(int, fcntl(int fd, int cmd, ...));
COBALT_DECL(mqd_t, mq_open(const char *name,
COBALT_DECL(int, mq_close(mqd_t qd));
COBALT_DECL(int, mq_unlink(const char *name));
COBALT_DECL(int, mq_getattr(mqd_t qd,
COBALT_DECL(int, mq_setattr(mqd_t qd,
COBALT_DECL(int, mq_send(mqd_t qd,
COBALT_DECL(int, mq_timedsend(mqd_t q,
COBALT_DECL(ssize_t, mq_receive(mqd_t q,
COBALT_DECL(ssize_t, mq_timedreceive(mqd_t q,
COBALT_DECL(int, mq_notify(mqd_t q,
COBALT_DECL(int, pthread_attr_init(pthread_attr_t *attr));
COBALT_DECL(int, pthread_create(pthread_t *ptid_r,
COBALT_DECL(int, pthread_getschedparam(pthread_t thread,
COBALT_DECL(int, pthread_setschedparam(pthread_t thread,
COBALT_DECL(int, pthread_mutex_init(pthread_mutex_t *mutex,
COBALT_DECL(int, pthread_mutex_destroy(pthread_mutex_t *mutex));
COBALT_DECL(int, pthread_mutex_lock(pthread_mutex_t *mutex));
COBALT_DECL(int, pthread_mutex_timedlock(pthread_mutex_t *mutex,
COBALT_DECL(int, pthread_mutex_trylock(pthread_mutex_t *mutex));
COBALT_DECL(int, pthread_mutex_unlock(pthread_mutex_t *mutex));
COBALT_DECL(int, pthread_cond_init (pthread_cond_t *cond,
COBALT_DECL(int, pthread_cond_destroy(pthread_cond_t *cond));
COBALT_DECL(int, pthread_cond_wait(pthread_cond_t *cond,
COBALT_DECL(int, pthread_cond_timedwait(pthread_cond_t *cond,
COBALT_DECL(int, pthread_cond_signal(pthread_cond_t *cond));
COBALT_DECL(int, pthread_cond_broadcast(pthread_cond_t *cond));
COBALT_DECL(int, pthread_kill(pthread_t ptid, int sig));
COBALT_DECL(int, pthread_join(pthread_t ptid, void **retval));
* COBALT_DECL(). Since Cobalt also routes pthread_yield() to its own
COBALT_DECL(int, pthread_yield(void));
COBALT_DECL(int, pthread_setname_np(pthread_t thread, const char *name));
COBALT_DECL(int, sched_yield(void));
COBALT_DECL(int, sched_get_priority_min(int policy));
COBALT_DECL(int, sched_get_priority_max(int policy));
COBALT_DECL(int, sched_setscheduler(pid_t pid, int policy,
COBALT_DECL(int, sched_getscheduler(pid_t pid));
COBALT_DECL(int, sem_init(sem_t *sem,
COBALT_DECL(int, sem_destroy(sem_t *sem));
COBALT_DECL(int, sem_post(sem_t *sem));
COBALT_DECL(int, sem_wait(sem_t *sem));
COBALT_DECL(int, sem_timedwait(sem_t *sem,
COBALT_DECL(int, sem_trywait(sem_t *sem));
COBALT_DECL(int, sem_getvalue(sem_t *sem, int *value));
COBALT_DECL(sem_t *, sem_open(const char *name, int oflags, ...));
COBALT_DECL(int, sem_close(sem_t *sem));
COBALT_DECL(int, sem_unlink(const char *name));
COBALT_DECL(int, sigpending(sigset_t *set));
COBALT_DECL(int, sigwait(const sigset_t *set, int *sig));
COBALT_DECL(int, sigwaitinfo(const sigset_t *set, siginfo_t *si));
COBALT_DECL(int, sigtimedwait(const sigset_t *set, siginfo_t *si,
COBALT_DECL(int, kill(pid_t pid, int sig));
COBALT_DECL(int, sigqueue(pid_t pid, int sig,
COBALT_DECL(int, vfprintf(FILE *stream, const char *fmt, va_list args));
COBALT_DECL(int, __vfprintf_chk(FILE *stream, int level,
COBALT_DECL(int, __vprintf_chk(int flag,
COBALT_DECL(int, __printf_chk(int flag, const char *fmt, ...));
COBALT_DECL(int, __fprintf_chk(FILE *fp, int flag, const char *fmt, ...));
COBALT_DECL(int, vprintf(const char *fmt, va_list args));
COBALT_DECL(int, fprintf(FILE *stream, const char *fmt, ...));
COBALT_DECL(int, printf(const char *fmt, ...));
COBALT_DECL(int, puts(const char *s));
COBALT_DECL(int, fputs(const char *s, FILE *stream));
COBALT_DECL(int, putchar(int c));
COBALT_DECL(int, fputc(int c, FILE *stream));
COBALT_DECL(size_t,
COBALT_DECL(int, fclose(FILE *stream));
COBALT_DECL(void, free(void *ptr));
COBALT_DECL(void *, malloc(size_t size));
COBALT_DECL(void, syslog(int priority, const char *fmt, ...));
COBALT_DECL(void, vsyslog(int priority,
COBALT_DECL(void, __vsyslog_chk(int priority, int level,
COBALT_DECL(void, __syslog_chk(int pri, int flag,
COBALT_DECL(int, clock_getres(clockid_t clock_id,
COBALT_DECL(int, clock_gettime(clockid_t clock_id,
COBALT_DECL(int, clock_settime(clockid_t clock_id,
COBALT_DECL(int, clock_nanosleep(clockid_t clock_id,
COBALT_DECL(time_t, time(time_t *t));
COBALT_DECL(int, nanosleep(const struct timespec *rqtp,
COBALT_DECL(int, timer_create(clockid_t clockid,
COBALT_DECL(int, timer_delete(timer_t timerid));
COBALT_DECL(int, timer_settime(timer_t timerid,
COBALT_DECL(int, timer_gettime(timer_t timerid,
COBALT_DECL(int, timer_getoverrun(timer_t timerid));
COBALT_DECL(ssize_t, read(int fd, void *buf, size_t nbyte));
COBALT_DECL(ssize_t, write(int fd, const void *buf, size_t nbyte));
COBALT_DECL(int, close(int fildes));
COBALT_DECL(unsigned int, sleep(unsigned int seconds));
#define COBALT_DECL(T, P) \
При этом мы пишем приложение совершенно в POSIX API ... всё зависит от того как мы его собираем (Makefile): с Xenomai - это буде realtime приложение, без - обычное Linux приложение, полностью эквивалентное.