Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
1c0c2c3
Reapply "Rtapi cleanup"
hdiethelm Apr 9, 2026
15dba0c
Cleanup: Library doesn't need a hardcoded path
hdiethelm Apr 9, 2026
c9664ce
Cleanup: Get rid of global task_array and add static where possible
hdiethelm Apr 11, 2026
176b63a
Cleanup: Get rid of globals ruid/euid
hdiethelm Apr 11, 2026
2dc8794
Cleanup: Rename libs
hdiethelm Apr 11, 2026
7442887
Cleanup: Get rid of globals find_rt_cpu_number / set_namef
hdiethelm Apr 11, 2026
b407dde
Cleanup: Review: const std::string &
hdiethelm Apr 12, 2026
f86dae0
Cleanup: Correct sizeof()
hdiethelm Apr 12, 2026
85729d0
Cleanup: Correct _exit
hdiethelm Apr 12, 2026
a276f7c
Cleanup: Review: get_fifo_path nicer
hdiethelm Apr 13, 2026
70e2cbb
Cleanup: Review: Fix timeout
hdiethelm Apr 13, 2026
7f7677a
Cleanup: Improve get_fifo_path_to_addr
hdiethelm Apr 14, 2026
e379b78
Cleanup: Rewrite socket protocol
hdiethelm Apr 14, 2026
76eef57
Cleanup: Run clang-format
hdiethelm Apr 14, 2026
ee79b7b
Cleanup: Signal handler: Use only allowed functions
hdiethelm Apr 14, 2026
125f16f
Cleanup: Signal handler: Fix coredump
hdiethelm Apr 15, 2026
4617389
Cleanup: Review: Doc protocol / const
hdiethelm Apr 15, 2026
7f585bc
Cleanup: recv_args: No need for push_back: more efficient
hdiethelm Apr 15, 2026
c5c8127
Cleanup: signal_handler: Replace define by function
hdiethelm Apr 18, 2026
a729270
Cleanup: remove run_threads
hdiethelm Apr 18, 2026
29e8841
Cleanup: socket protocol: fully checked send/recv
hdiethelm Apr 20, 2026
8e06505
Cleanup: socket protocol: improve error messages
hdiethelm Apr 20, 2026
3ece0a3
Cleanup: socket protocol: fix send_args
hdiethelm Apr 20, 2026
715c427
Cleanup: socket protocol: Set recive timeout in master
hdiethelm Apr 20, 2026
4087083
Cleanup: socket protocol: args to big is not a bug
hdiethelm Apr 20, 2026
5584903
Cleanup: socket protocol: bounds checking
hdiethelm Apr 20, 2026
994ee45
Cleanup: Remove unused code
hdiethelm Apr 21, 2026
ab79dee
Cleanup: Naming and remove out of place struct keyword
hdiethelm Apr 21, 2026
69c0eb8
Cleanup: Use const and proper indexing in do_comp_args
hdiethelm Apr 27, 2026
79716c4
Fix rtapi_app: Sanitize name for module
hdiethelm Apr 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions src/rtapi/Submakefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ $(patsubst ./rtapi/%,../include/%,$(RTAPIINCS)): ../include/%.h: ./rtapi/%.h
ifeq ($(BUILD_SYS),uspace)

RTAPI_APP_SRCS := \
rtapi/uspace_rtapi_main.cc \
rtapi/uspace_rtapi_app.cc \
rtapi/uspace_rtapi_parport.cc \
rtapi/uspace_rtapi_string.c \
Expand All @@ -43,39 +44,48 @@ $(call TOOBJSDEPS, $(RTAPI_APP_SRCS)): EXTRAFLAGS += -DSIM \
-UULAPI -DRTAPI -pthread
../bin/rtapi_app: $(call TOOBJS, $(RTAPI_APP_SRCS))
$(ECHO) Linking $(notdir $@)
$(Q)$(CXX) -rdynamic -o $@ $^ $(LIBDL) -pthread -lrt $(LIBUDEV_LIBS) -ldl $(LDFLAGS)
$(Q)$(CXX) -rdynamic -o $@ $^ $(LIBDL) -pthread -lrt -lfmt $(LIBUDEV_LIBS) -ldl $(LDFLAGS)
TARGETS += ../bin/rtapi_app
endif

USPACE_POSIX_SRCS := rtapi/uspace_posix.cc
USERSRCS += $(USPACE_POSIX_SRCS)
$(call TOOBJSDEPS, $(USPACE_POSIX_SRCS)): EXTRAFLAGS += -pthread -fPIC
../lib/liblinuxcnc-uspace-posix.so.0: $(call TOOBJS, $(USPACE_POSIX_SRCS))
$(ECHO) Linking $(notdir $@)
$(Q)$(CXX) -shared $(LDFLAGS) -o $@ $^ -Wl,-soname,$(notdir $@)
TARGETS += ../lib/liblinuxcnc-uspace-posix.so.0
TARGETS += ../lib/liblinuxcnc-uspace-posix.so

ifeq ($(CONFIG_USPACE_RTAI),y)
USPACE_RTAI_SRCS := rtapi/uspace_rtai.cc
USERSRCS += $(USPACE_RTAI_SRCS)
$(call TOOBJSDEPS, $(USPACE_RTAI_SRCS)): EXTRAFLAGS += -pthread -fPIC $(filter-out -Wstrict-prototypes,$(RTAI_LXRT_CFLAGS))
../lib/libuspace-rtai.so.0: $(call TOOBJS, $(USPACE_RTAI_SRCS))
../lib/liblinuxcnc-uspace-rtai.so.0: $(call TOOBJS, $(USPACE_RTAI_SRCS))
$(ECHO) Linking $(notdir $@)
$(Q)$(CXX) -shared $(LDFLAGS) -o $@ $^ $(RTAI_LXRT_LDFLAGS) -Wl,-soname,$(notdir $@)
TARGETS += ../lib/libuspace-rtai.so.0
TARGETS += ../lib/libuspace-rtai.so
TARGETS += ../lib/liblinuxcnc-uspace-rtai.so.0
TARGETS += ../lib/liblinuxcnc-uspace-rtai.so
endif

ifeq ($(CONFIG_USPACE_XENOMAI),y)
USPACE_XENOMAI_SRCS := rtapi/uspace_xenomai.cc
USERSRCS += $(USPACE_XENOMAI_SRCS)
$(call TOOBJSDEPS, $(USPACE_XENOMAI_SRCS)): EXTRAFLAGS += -fPIC $(XENOMAI_CFLAGS)
../lib/libuspace-xenomai.so.0: $(call TOOBJS, $(USPACE_XENOMAI_SRCS))
../lib/liblinuxcnc-uspace-xenomai.so.0: $(call TOOBJS, $(USPACE_XENOMAI_SRCS))
$(ECHO) Linking $(notdir $@)
$(Q)$(CXX) -shared $(LDFLAGS) -o $@ $^ $(XENOMAI_LDFLAGS) -Wl,-soname,$(notdir $@)
TARGETS += ../lib/libuspace-xenomai.so.0
TARGETS += ../lib/libuspace-xenomai.so
TARGETS += ../lib/liblinuxcnc-uspace-xenomai.so.0
TARGETS += ../lib/liblinuxcnc-uspace-xenomai.so
endif

ifeq ($(CONFIG_USPACE_XENOMAI_EVL),y)
USPACE_XENOMAI_EVL_SRCS := rtapi/uspace_xenomai_evl.cc
USERSRCS += $(USPACE_XENOMAI_EVL_SRCS)
$(call TOOBJSDEPS, $(USPACE_XENOMAI_EVL_SRCS)): EXTRAFLAGS += -fPIC $(XENOMAI_EVL_CFLAGS)
../lib/libuspace-xenomai-evl.so.0: $(call TOOBJS, $(USPACE_XENOMAI_EVL_SRCS))
../lib/liblinuxcnc-uspace-xenomai-evl.so.0: $(call TOOBJS, $(USPACE_XENOMAI_EVL_SRCS))
$(ECHO) Linking $(notdir $@)
$(Q)$(CXX) -shared $(LDFLAGS) -o $@ $^ $(XENOMAI_EVL_LDFLAGS) -Wl,-soname,$(notdir $@)
TARGETS += ../lib/libuspace-xenomai-evl.so.0
TARGETS += ../lib/libuspace-xenomai-evl.so
TARGETS += ../lib/liblinuxcnc-uspace-xenomai-evl.so.0
TARGETS += ../lib/liblinuxcnc-uspace-xenomai-evl.so
endif
2 changes: 1 addition & 1 deletion src/rtapi/rtapi_pci.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include <rtapi.h>
#include <rtapi_pci.h>
#include <rtapi_firmware.h>
#include "rtapi_uspace.hh"
#include "uspace_rtapi_app.hh"

#include <dirent.h>
#include <errno.h>
Expand Down
5 changes: 3 additions & 2 deletions src/rtapi/uspace_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <sys/time.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/utsname.h>
#include <string.h>
#include <unistd.h>
Expand All @@ -39,7 +40,7 @@ static msg_level_t msg_level = RTAPI_MSG_ERR; /* message printing level */
#include "config.h"

#ifdef RTAPI
#include "rtapi_uspace.hh"
#include "uspace_rtapi_app.hh"
#endif

typedef struct {
Expand Down Expand Up @@ -115,7 +116,7 @@ int rtapi_shmem_new(int key, int module_id, unsigned long int size)
*/
/* ensure the segment is owned by user, not root */
if(geteuid() == 0) {
stat.shm_perm.uid = ruid;
stat.shm_perm.uid = WithRoot::getRuid();
res = shmctl(shmem->id, IPC_SET, &stat);
if(res < 0) perror("shmctl IPC_SET");
}
Expand Down
246 changes: 246 additions & 0 deletions src/rtapi/uspace_posix.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
/* Copyright (C) 2006-2014 Jeff Epler <jepler@unpythonic.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "config.h"
#include "rtapi.h"
#include "uspace_rtapi_app.hh"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdexcept>
#ifdef HAVE_SYS_IO_H
#include <sys/io.h>
#endif

namespace {
struct PosixTask : RtapiTask {
PosixTask() : RtapiTask{}, thr{} {
}

pthread_t thr; /* thread's context */
};

struct PosixApp : RtapiApp {
PosixApp(int policy = SCHED_FIFO) : RtapiApp(policy), do_thread_lock(policy != SCHED_FIFO) {
pthread_once(&key_once, init_key);
if (do_thread_lock) {
pthread_once(&lock_once, init_lock);
}
}

RtapiTask *do_task_new() {
return new PosixTask;
}

int task_delete(int id) {
auto task = ::rtapi_get_task<PosixTask>(id);
if (!task)
return -EINVAL;

pthread_cancel(task->thr);
pthread_join(task->thr, 0);
task->magic = 0;
task_array[id] = 0;
delete task;
return 0;
}

int task_start(int task_id, unsigned long period_nsec) {
auto task = ::rtapi_get_task<PosixTask>(task_id);
if (!task)
return -EINVAL;

task->period = period_nsec;
struct sched_param param;
memset(&param, 0, sizeof(param));
param.sched_priority = task->prio;

// limit PLL correction values to +/-1% of cycle time
task->pll_correction_limit = period_nsec / 100;
task->pll_correction = 0;

int nprocs = sysconf(_SC_NPROCESSORS_ONLN);

pthread_attr_t attr;
int ret;
if ((ret = pthread_attr_init(&attr)) != 0)
return -ret;
if ((ret = pthread_attr_setstacksize(&attr, task->stacksize)) != 0)
return -ret;
if ((ret = pthread_attr_setschedpolicy(&attr, policy)) != 0)
return -ret;
if ((ret = pthread_attr_setschedparam(&attr, &param)) != 0)
return -ret;
if ((ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) != 0)
return -ret;
if (nprocs > 1) {
const static int rt_cpu_number = find_rt_cpu_number();
rtapi_print_msg(RTAPI_MSG_INFO, "rt_cpu_number = %i\n", rt_cpu_number);
if (rt_cpu_number != -1) {
#ifdef __FreeBSD__
cpuset_t cpuset;
#else
cpu_set_t cpuset;
#endif
CPU_ZERO(&cpuset);
CPU_SET(rt_cpu_number, &cpuset);
if ((ret = pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset)) != 0)
return -ret;
}
}
if (do_thread_lock)
pthread_mutex_lock(&thread_lock);
if ((ret = pthread_create(&task->thr, &attr, &wrapper, reinterpret_cast<void *>(task))) != 0)
return -ret;

return 0;
}

static void *wrapper(void *arg) {
auto task = reinterpret_cast<PosixTask *>(arg);

pthread_setspecific(key, arg);
set_namef("rtapi_app:T#%d", task->id);

struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
rtapi_timespec_advance(task->nextstart, now, task->period + task->pll_correction);

/* call the task function with the task argument */
(task->taskcode)(task->arg);

rtapi_print("ERROR: reached end of wrapper for task %d\n", task->id);
return NULL;
}

int task_pause(int task_id) {
(void)task_id;
return -ENOSYS;
}

int task_resume(int task_id) {
(void)task_id;
return -ENOSYS;
}

long long task_pll_get_reference(void) {
RtapiTask *task = reinterpret_cast<RtapiTask *>(pthread_getspecific(key));
if (!task)
return 0;
return task->nextstart.tv_sec * 1000000000LL + task->nextstart.tv_nsec;
}

int task_pll_set_correction(long value) {
RtapiTask *task = reinterpret_cast<RtapiTask *>(pthread_getspecific(key));
if (!task)
return -EINVAL;
if (value > task->pll_correction_limit)
value = task->pll_correction_limit;
if (value < -(task->pll_correction_limit))
value = -(task->pll_correction_limit);
task->pll_correction = value;
return 0;
}

void wait() {
if (do_thread_lock)
pthread_mutex_unlock(&thread_lock);
pthread_testcancel();
RtapiTask *task = reinterpret_cast<RtapiTask *>(pthread_getspecific(key));
rtapi_timespec_advance(task->nextstart, task->nextstart, task->period + task->pll_correction);
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
if (rtapi_timespec_less(task->nextstart, now)) {
if (policy == SCHED_FIFO)
unexpected_realtime_delay(task);
} else {
int res = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &task->nextstart, nullptr);
if (res < 0)
perror("clock_nanosleep");
}
if (do_thread_lock)
pthread_mutex_lock(&thread_lock);
}

unsigned char do_inb(unsigned int port) {
#ifdef HAVE_SYS_IO_H
return inb(port);
#else
(void)port;
return 0;
#endif
}

void do_outb(unsigned char val, unsigned int port) {
#ifdef HAVE_SYS_IO_H
return outb(val, port);
#else
(void)val;
(void)port;
#endif
}

int task_self() {
RtapiTask *task = reinterpret_cast<RtapiTask *>(pthread_getspecific(key));
if (!task)
return -EINVAL;
return task->id;
}

bool do_thread_lock;

static pthread_once_t key_once;
static pthread_key_t key;
static void init_key(void) {
pthread_key_create(&key, NULL);
}

static pthread_once_t lock_once;
static pthread_mutex_t thread_lock;
static void init_lock(void) {
pthread_mutex_init(&thread_lock, NULL);
}

long long do_get_time() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return ts.tv_sec * 1000000000LL + ts.tv_nsec;
}

void do_delay(long ns) {
struct timespec ts = {0, ns};
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, nullptr);
}
};

pthread_once_t PosixApp::key_once = PTHREAD_ONCE_INIT;
pthread_once_t PosixApp::lock_once = PTHREAD_ONCE_INIT;
pthread_key_t PosixApp::key;
pthread_mutex_t PosixApp::thread_lock;

} // namespace

extern "C" RtapiApp *make(int policy);

RtapiApp *make(int policy) {
if (policy == SCHED_OTHER) {
rtapi_print_msg(RTAPI_MSG_ERR, "Note: Using POSIX non-realtime\n");
} else {
rtapi_print_msg(RTAPI_MSG_ERR, "Note: Using POSIX realtime\n");
}
return new PosixApp(policy);
}
Loading
Loading