From cf54187b7c7e9d44137f45c14567aaf3135f2ec1 Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:06:14 +0100 Subject: [PATCH 01/13] cpu/native: move syscalls into separate header --- cpu/native/include/native_internal.h | 72 +--------------- cpu/native/include/syscalls.h | 118 +++++++++++++++++++++++++++ cpu/native/syscalls.c | 64 +-------------- 3 files changed, 121 insertions(+), 133 deletions(-) create mode 100644 cpu/native/include/syscalls.h diff --git a/cpu/native/include/native_internal.h b/cpu/native/include/native_internal.h index 91744bab50..154baf2b33 100644 --- a/cpu/native/include/native_internal.h +++ b/cpu/native/include/native_internal.h @@ -68,6 +68,7 @@ extern "C" { #endif +#include "syscalls.h" /** * Prototype for native's internal callbacks */ @@ -89,77 +90,6 @@ void _native_syscall_enter(void); void _native_init_syscalls(void); /** - * external functions regularly wrapped in native for direct use - */ -extern ssize_t (*real_read)(int fd, void *buf, size_t count); -extern ssize_t (*real_write)(int fd, const void *buf, size_t count); -extern off_t (*real_lseek)(int fd, off_t offset, int whence); -extern off_t (*real_fstat)(int fd, struct stat *statbuf); -extern int (*real_statvfs)(const char *restrict path, struct statvfs *restrict buf); -extern int (*real_fsync)(int fd); -extern size_t (*real_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream); -extern void (*real_clearerr)(FILE *stream); -extern __attribute__((noreturn)) void (*real_exit)(int status); -extern void (*real_free)(void *ptr); -extern void* (*real_calloc)(size_t nmemb, size_t size); -extern void* (*real_malloc)(size_t size); -extern void* (*real_realloc)(void *ptr, size_t size); -extern void (*real_freeaddrinfo)(struct addrinfo *res); -extern void (*real_freeifaddrs)(struct ifaddrs *ifa); -extern void (*real_srandom)(unsigned int seed); -/* The ... is a hack to save includes: */ -extern int (*real_accept)(int socket, ...); -/* The ... is a hack to save includes: */ -extern int (*real_bind)(int socket, ...); -extern int (*real_connect)(int socket, ...); -extern ssize_t (*real_recv)(int sockfd, void *buf, size_t len, int flags); -extern int (*real_chdir)(const char *path); -extern int (*real_close)(int); -extern int (*real_fcntl)(int, int, ...); -/* The ... is a hack to save includes: */ -extern int (*real_creat)(const char *path, ...); -extern int (*real_dup2)(int, int); -extern int (*real_execve)(const char *, char *const[], char *const[]); -extern int (*real_feof)(FILE *stream); -extern int (*real_ferror)(FILE *stream); -extern int (*real_fork)(void); -/* The ... is a hack to save includes: */ -extern int (*real_getaddrinfo)(const char *node, ...); -extern int (*real_getifaddrs)(struct ifaddrs **ifap); -extern int (*real_getpid)(void); -extern int (*real_gettimeofday)(struct timeval *t, ...); -extern int (*real_ioctl)(int fildes, unsigned long request, ...); -extern int (*real_listen)(int socket, int backlog); -extern int (*real_open)(const char *path, int oflag, ...); -extern int (*real_mkdir)(const char *pathname, mode_t mode); -extern int (*real_rmdir)(const char *pathname); -extern DIR *(*real_opendir)(const char *name); -extern struct dirent *(*real_readdir)(DIR *dirp); -extern int (*real_closedir)(DIR *dirp); -extern int (*real_pause)(void); -extern int (*real_pipe)(int[2]); -/* The ... is a hack to save includes: */ -extern int (*real_select)(int nfds, ...); -extern int (*real_poll)(struct pollfd *nfds, ...); -extern int (*real_setitimer)(int which, const struct itimerval - *__restrict value, struct itimerval *__restrict ovalue); -extern int (*real_setsid)(void); -extern int (*real_setsockopt)(int socket, ...); -extern int (*real_socket)(int domain, int type, int protocol); -extern int (*real_printf)(const char *format, ...); -extern int (*real_unlink)(const char *); -extern int (*real_rename)(const char *, const char *); -extern long int (*real_random)(void); -extern const char* (*real_gai_strerror)(int errcode); -extern FILE* (*real_fopen)(const char *path, const char *mode); -extern int (*real_fclose)(FILE *stream); -extern int (*real_fseek)(FILE *stream, long offset, int whence); -extern long (*real_ftell)(FILE *stream); -extern int (*real_fputc)(int c, FILE *stream); -extern int (*real_fgetc)(FILE *stream); -extern mode_t (*real_umask)(mode_t cmask); -extern ssize_t (*real_writev)(int fildes, const struct iovec *iov, int iovcnt); -extern ssize_t (*real_send)(int sockfd, const void *buf, size_t len, int flags); /** * data structures diff --git a/cpu/native/include/syscalls.h b/cpu/native/include/syscalls.h new file mode 100644 index 0000000000..3235af3a9d --- /dev/null +++ b/cpu/native/include/syscalls.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2013 Ludwig Knüpfer + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef SYSCALLS_H +#define SYSCALLS_H + +#include +#include +#include +#include + +/** + * @addtogroup cpu_native + * @{ + */ + +#ifndef DOXYGEN +# if NATIVE_SYSCALLS_DEFINITION +# define __SPECIFIER +# else +# define __SPECIFIER extern +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* MARK: - System call wrappers */ +/** @cond */ +/** + * @name System call wrappers + * + * Internally, these function pointers are assigned their implementation in the standard library. + * We wrap system calls and syscall-invoking library calls to ensure **no context switches occur during a system call**. + * @{ + */ +__SPECIFIER ssize_t (*real_read)(int fd, void *buf, size_t count); +__SPECIFIER ssize_t (*real_write)(int fd, const void *buf, size_t count); +__SPECIFIER size_t (*real_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream); +__SPECIFIER ssize_t (*real_recv)(int sockfd, void *buf, size_t len, int flags); +__SPECIFIER void (*real_clearerr)(FILE *stream); +__SPECIFIER __attribute__((noreturn)) void (*real_exit)(int status); +__SPECIFIER void (*real_free)(void *ptr); +__SPECIFIER void* (*real_malloc)(size_t size); +__SPECIFIER void* (*real_calloc)(size_t nmemb, size_t size); +__SPECIFIER void* (*real_realloc)(void *ptr, size_t size); +__SPECIFIER void (*real_freeaddrinfo)(struct addrinfo *res); +__SPECIFIER void (*real_freeifaddrs)(struct ifaddrs *ifa); +__SPECIFIER void (*real_srandom)(unsigned int seed); +__SPECIFIER int (*real_accept)(int socket, ...); +__SPECIFIER int (*real_bind)(int socket, ...); +__SPECIFIER int (*real_connect)(int socket, ...); +__SPECIFIER int (*real_printf)(const char *format, ...); +__SPECIFIER int (*real_getaddrinfo)(const char *node, ...); +__SPECIFIER int (*real_getifaddrs)(struct ifaddrs **ifap); +__SPECIFIER int (*real_gettimeofday)(struct timeval *t, ...); +__SPECIFIER int (*real_getpid)(void); +__SPECIFIER int (*real_chdir)(const char *path); +__SPECIFIER int (*real_close)(int); +__SPECIFIER int (*real_fcntl)(int, int, ...); +__SPECIFIER int (*real_creat)(const char *path, ...); +__SPECIFIER int (*real_dup2)(int, int); +__SPECIFIER int (*real_execve)(const char *, char *const[], char *const[]); +__SPECIFIER int (*real_fork)(void); +__SPECIFIER int (*real_feof)(FILE *stream); +__SPECIFIER int (*real_ferror)(FILE *stream); +__SPECIFIER int (*real_listen)(int socket, int backlog); +__SPECIFIER int (*real_ioctl)(int fildes, unsigned long request, ...); +__SPECIFIER int (*real_open)(const char *path, int oflag, ...); +__SPECIFIER int (*real_pause)(void); +__SPECIFIER int (*real_pipe)(int[2]); +__SPECIFIER int (*real_select)(int nfds, ...); +__SPECIFIER int (*real_poll)(struct pollfd *fds, ...); +__SPECIFIER int (*real_setsid)(void); +__SPECIFIER int (*real_setsockopt)(int socket, ...); +__SPECIFIER int (*real_socket)(int domain, int type, int protocol); +__SPECIFIER int (*real_unlink)(const char *); +__SPECIFIER long int (*real_random)(void); +__SPECIFIER const char* (*real_gai_strerror)(int errcode); +__SPECIFIER FILE* (*real_fopen)(const char *path, const char *mode); +__SPECIFIER int (*real_fclose)(FILE *stream); +__SPECIFIER int (*real_fseek)(FILE *stream, long offset, int whence); +__SPECIFIER long (*real_ftell)(FILE *stream); +__SPECIFIER int (*real_fputc)(int c, FILE *stream); +__SPECIFIER int (*real_fgetc)(FILE *stream); +__SPECIFIER mode_t (*real_umask)(mode_t cmask); +__SPECIFIER ssize_t (*real_writev)(int fildes, const struct iovec *iov, int iovcnt); +__SPECIFIER ssize_t (*real_send)(int sockfd, const void *buf, size_t len, int flags); +__SPECIFIER off_t (*real_lseek)(int fd, off_t offset, int whence); +__SPECIFIER off_t (*real_fstat)(int fd, struct stat *statbuf); +__SPECIFIER int (*real_fsync)(int fd); +__SPECIFIER int (*real_mkdir)(const char *pathname, mode_t mode); +__SPECIFIER int (*real_rmdir)(const char *pathname); +__SPECIFIER DIR *(*real_opendir)(const char *name); +__SPECIFIER struct dirent *(*real_readdir)(DIR *dirp); +__SPECIFIER int (*real_closedir)(DIR *dirp); +__SPECIFIER int (*real_rename)(const char *, const char *); +__SPECIFIER int (*real_statvfs)(const char *restrict path, struct statvfs *restrict buf); +/** @}*/ +/** @endcond */ + +#ifdef __cplusplus +} +#endif + +#if !defined(DOXYGEN) +# undef __SPECIFIER +#endif + +/** @} */ + +#endif /* SYSCALLS_H */ diff --git a/cpu/native/syscalls.c b/cpu/native/syscalls.c index 76a13e9f81..02ec691e88 100644 --- a/cpu/native/syscalls.c +++ b/cpu/native/syscalls.c @@ -46,73 +46,13 @@ #include "stdio_base.h" #include "kernel_defines.h" +/* This header defines the system call function pointers */ +#define NATIVE_SYSCALLS_DEFINITION 1 #include "native_internal.h" #define ENABLE_DEBUG 0 #include "debug.h" -ssize_t (*real_read)(int fd, void *buf, size_t count); -ssize_t (*real_write)(int fd, const void *buf, size_t count); -size_t (*real_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream); -ssize_t (*real_recv)(int sockfd, void *buf, size_t len, int flags); -void (*real_clearerr)(FILE *stream); -__attribute__((noreturn)) void (*real_exit)(int status); -void (*real_free)(void *ptr); -void* (*real_malloc)(size_t size); -void* (*real_calloc)(size_t nmemb, size_t size); -void* (*real_realloc)(void *ptr, size_t size); -void (*real_freeaddrinfo)(struct addrinfo *res); -void (*real_freeifaddrs)(struct ifaddrs *ifa); -void (*real_srandom)(unsigned int seed); -int (*real_accept)(int socket, ...); -int (*real_bind)(int socket, ...); -int (*real_connect)(int socket, ...); -int (*real_printf)(const char *format, ...); -int (*real_getaddrinfo)(const char *node, ...); -int (*real_getifaddrs)(struct ifaddrs **ifap); -int (*real_gettimeofday)(struct timeval *t, ...); -int (*real_getpid)(void); -int (*real_chdir)(const char *path); -int (*real_close)(int); -int (*real_fcntl)(int, int, ...); -int (*real_creat)(const char *path, ...); -int (*real_dup2)(int, int); -int (*real_execve)(const char *, char *const[], char *const[]); -int (*real_fork)(void); -int (*real_feof)(FILE *stream); -int (*real_ferror)(FILE *stream); -int (*real_listen)(int socket, int backlog); -int (*real_ioctl)(int fildes, unsigned long request, ...); -int (*real_open)(const char *path, int oflag, ...); -int (*real_pause)(void); -int (*real_pipe)(int[2]); -int (*real_select)(int nfds, ...); -int (*real_poll)(struct pollfd *fds, ...); -int (*real_setsid)(void); -int (*real_setsockopt)(int socket, ...); -int (*real_socket)(int domain, int type, int protocol); -int (*real_unlink)(const char *); -long int (*real_random)(void); -const char* (*real_gai_strerror)(int errcode); -FILE* (*real_fopen)(const char *path, const char *mode); -int (*real_fclose)(FILE *stream); -int (*real_fseek)(FILE *stream, long offset, int whence); -long (*real_ftell)(FILE *stream); -int (*real_fputc)(int c, FILE *stream); -int (*real_fgetc)(FILE *stream); -mode_t (*real_umask)(mode_t cmask); -ssize_t (*real_writev)(int fildes, const struct iovec *iov, int iovcnt); -ssize_t (*real_send)(int sockfd, const void *buf, size_t len, int flags); -off_t (*real_lseek)(int fd, off_t offset, int whence); -off_t (*real_fstat)(int fd, struct stat *statbuf); -int (*real_fsync)(int fd); -int (*real_mkdir)(const char *pathname, mode_t mode); -int (*real_rmdir)(const char *pathname); -DIR *(*real_opendir)(const char *name); -struct dirent *(*real_readdir)(DIR *dirp); -int (*real_closedir)(DIR *dirp); -int (*real_rename)(const char *, const char *); -int (*real_statvfs)(const char *restrict path, struct statvfs *restrict buf); void _native_syscall_enter(void) { From aff3b107c10d2a2f4c5fb85dba1fb2f48119db69 Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:22:53 +0100 Subject: [PATCH 02/13] cpu/native: log with prefix --- cpu/native/irq_cpu.c | 42 +++++++++++++++++++++-------------------- cpu/native/native_cpu.c | 11 +++++++---- cpu/native/startup.c | 9 +++++---- cpu/native/syscalls.c | 9 +++++++-- 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index c5e404115a..e1c0d88323 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -44,6 +44,7 @@ #define ENABLE_DEBUG 0 #include "debug.h" +#define DEBUG_IRQ(...) DEBUG("[native] IRQ: " __VA_ARGS__) volatile int native_interrupts_enabled = 0; volatile int _native_in_isr; @@ -155,10 +156,10 @@ unsigned irq_disable(void) unsigned int prev_state; _native_syscall_enter(); - DEBUG("irq_disable()\n"); + DEBUG_IRQ("irq_disable(): _native_in_isr == %i\n", _native_in_isr); if (_native_in_isr == 1) { - DEBUG("irq_disable + _native_in_isr\n"); + DEBUG_IRQ("irq_disable + _native_in_isr\n"); } if (sigprocmask(SIG_SETMASK, &_native_sig_set_dint, NULL) == -1) { @@ -168,7 +169,7 @@ unsigned irq_disable(void) prev_state = native_interrupts_enabled; native_interrupts_enabled = 0; - DEBUG("irq_disable(): return\n"); + DEBUG_IRQ("irq_disable(): return\n"); _native_syscall_leave(); return prev_state; @@ -182,15 +183,15 @@ unsigned irq_enable(void) unsigned int prev_state; if (_native_in_isr == 1) { -#ifdef DEVELHELP +# ifdef DEVELHELP real_write(STDERR_FILENO, "irq_enable + _native_in_isr\n", 27); -#else - DEBUG("irq_enable + _native_in_isr\n"); -#endif +# else + DEBUG_IRQ("irq_enable + _native_in_isr\n"); +# endif } _native_syscall_enter(); - DEBUG("irq_enable()\n"); + DEBUG_IRQ("irq_enable()\n"); /* Mark the IRQ as enabled first since sigprocmask could call the handler * before returning to userspace. @@ -206,18 +207,18 @@ unsigned irq_enable(void) _native_syscall_leave(); if (_native_in_isr == 0 && sched_context_switch_request) { - DEBUG("irq_enable() deferred thread_yield_higher()\n"); + DEBUG_IRQ("irq_enable() deferred thread_yield_higher()\n"); thread_yield_higher(); } - DEBUG("irq_enable(): return\n"); + DEBUG_IRQ("irq_enable(): return\n"); return prev_state; } void irq_restore(unsigned state) { - DEBUG("irq_restore()\n"); + DEBUG_IRQ("irq_restore()\n"); if (state == 1) { irq_enable(); @@ -236,7 +237,7 @@ bool irq_is_enabled(void) bool irq_is_in(void) { - DEBUG("irq_is_in: %i\n", _native_in_isr); + DEBUG_IRQ("irq_is_in: %i\n", _native_in_isr); return _native_in_isr; } @@ -266,15 +267,15 @@ int _native_popsig(void) */ void native_irq_handler(void) { - DEBUG("\n\n\t\tnative_irq_handler\n\n"); + DEBUG_IRQ("\n\n\t\tcall sig handlers + switch\n\n"); while (_native_sigpend > 0) { int sig = _native_popsig(); _native_sigpend--; if (native_irq_handlers[sig] != NULL) { - DEBUG("native_irq_handler: calling interrupt handler for %i\n", sig); native_irq_handlers[sig](); + DEBUG_IRQ("call sig handlers + switch: calling interrupt handler for %i\n", sig); } else if (sig == SIGUSR1) { warnx("native_irq_handler: ignoring SIGUSR1"); @@ -284,7 +285,7 @@ void native_irq_handler(void) } } - DEBUG("native_irq_handler: return\n"); + DEBUG_IRQ("call sig handlers + switch: return\n"); cpu_switch_context_exit(); } @@ -331,7 +332,7 @@ void native_isr_entry(int sig, siginfo_t *info, void *context) } if (_native_in_syscall != 0) { - DEBUG("\n\n\t\tnative_isr_entry: return to syscall\n\n"); + DEBUG_IRQ("\n\n\t\tnative_signal_action: return to syscall\n\n"); return; } @@ -343,7 +344,7 @@ void native_isr_entry(int sig, siginfo_t *info, void *context) * stacks are manually word aligned in thread_stack_init() */ _native_cur_ctx = (ucontext_t *)(uintptr_t)thread_get_active()->sp; - DEBUG("\n\n\t\tnative_isr_entry: return to _native_sig_leave_tramp\n\n"); + DEBUG_IRQ("\n\n\t\tnative_signal_action: return to _native_sig_leave_tramp\n\n"); /* disable interrupts in context */ isr_set_sigmask((ucontext_t *)context); _native_in_isr = 1; @@ -424,7 +425,7 @@ void set_signal_handler(int sig, bool add) */ int register_interrupt(int sig, _native_callback_t handler) { - DEBUG("register_interrupt\n"); + DEBUG_IRQ("native_register_interrupt\n"); unsigned state = irq_disable(); @@ -441,7 +442,8 @@ int register_interrupt(int sig, _native_callback_t handler) */ int unregister_interrupt(int sig) { - DEBUG("unregister_interrupt\n"); + /* empty signal mask */ + DEBUG_IRQ("native_unregister_interrupt\n"); unsigned state = irq_disable(); @@ -471,7 +473,7 @@ static void native_shutdown(int sig, siginfo_t *info, void *context) void native_interrupt_init(void) { struct sigaction sa; - DEBUG("native_interrupt_init\n"); + DEBUG_IRQ("native_interrupt_init\n"); (void) VALGRIND_STACK_REGISTER(__isr_stack, __isr_stack + sizeof(__isr_stack)); VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n", diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index c2c1a39ca4..e544648545 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -66,6 +66,7 @@ extern netdev_tap_t netdev_tap; #define ENABLE_DEBUG 0 #include "debug.h" +#define DEBUG_CPU(...) DEBUG("[native] CPU: " __VA_ARGS__) ucontext_t end_context; @@ -131,6 +132,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_sta ucontext_t *p; stack_start = align_stack((uintptr_t)stack_start, &stacksize); + DEBUG_CPU("... ISR: switching to user thread, calling setcontext(PID %" PRIkernel_pid ")\n\n", thread_getpid()); (void) VALGRIND_STACK_REGISTER(stack_start, (char *)stack_start + stacksize); VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n", @@ -165,7 +167,7 @@ void isr_cpu_switch_context_exit(void) { ucontext_t *ctx; - DEBUG("isr_cpu_switch_context_exit\n"); + DEBUG_CPU("_isr_schedule_and_switch\n"); if (((sched_context_switch_request == 1) || (thread_get_active() == NULL)) && IS_USED(MODULE_CORE_THREAD)) { sched_run(); @@ -190,7 +192,7 @@ void cpu_switch_context_exit(void) #ifdef NATIVE_AUTO_EXIT if (sched_num_threads <= 1) { extern unsigned _native_retval; - DEBUG("cpu_switch_context_exit: last task has ended. exiting.\n"); + DEBUG_CPU("cpu_switch_context_exit: last task has ended. exiting.\n"); real_exit(_native_retval); } #endif @@ -215,11 +217,11 @@ void cpu_switch_context_exit(void) void isr_thread_yield(void) { - DEBUG("isr_thread_yield\n"); + DEBUG_CPU("... ISR: switched to ISR context, scheduling\n"); if (_native_sigpend > 0) { - DEBUG("isr_thread_yield(): handling signals\n\n"); native_irq_handler(); + DEBUG_CPU("... ISR: pending signals, handling signals\n\n"); } if (!IS_USED(MODULE_CORE_THREAD)) { @@ -249,6 +251,7 @@ void thread_yield_higher(void) /* Use intermediate cast to uintptr_t to silence -Wcast-align. * stacks are manually word aligned in thread_static_init() */ ucontext_t *ctx = (ucontext_t *)(uintptr_t)(thread_get_active()->sp); + DEBUG_CPU("yielding higher priority thread, switching to ISR context ...\n"); _native_in_isr = 1; irq_disable(); native_isr_context.uc_stack.ss_sp = __isr_stack; diff --git a/cpu/native/startup.c b/cpu/native/startup.c index 5ee0515ff4..cc1abfaa38 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -47,6 +47,7 @@ #define ENABLE_DEBUG 0 #include "debug.h" +#define DEBUG_STARTUP(...) DEBUG("[native] startup: " __VA_ARGS__) typedef enum { _STDIOTYPE_STDIO = 0, /**< leave intact */ @@ -693,20 +694,20 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e /* Skip everything which has already been run */ if ((*init_array_ptr) == startup) { /* Found ourselves, move on to calling the rest of the constructors */ - DEBUG("%18p - myself\n", (void *)init_array_ptr); + DEBUG_STARTUP("%18p - myself\n", (void *)init_array_ptr); ++init_array_ptr; break; } - DEBUG("%18p - skip\n", (void *)init_array_ptr); + DEBUG_STARTUP("%18p - skip\n", (void *)init_array_ptr); ++init_array_ptr; } while (init_array_ptr != &__init_array_end) { /* call all remaining constructors */ - DEBUG("%18p - call\n", (void *)init_array_ptr); + DEBUG_STARTUP("%18p - call\n", (void *)init_array_ptr); (*init_array_ptr)(argc, argv, envp); ++init_array_ptr; } - DEBUG("done, __init_array_end: %p\n", (void *)init_array_ptr); + DEBUG_STARTUP("done, __init_array_end: %p\n", (void *)init_array_ptr); native_cpu_init(); native_interrupt_init(); diff --git a/cpu/native/syscalls.c b/cpu/native/syscalls.c index 02ec691e88..5d2230ac00 100644 --- a/cpu/native/syscalls.c +++ b/cpu/native/syscalls.c @@ -53,20 +53,25 @@ #define ENABLE_DEBUG 0 #include "debug.h" +#define _DEBUG_PREFIX "[native] syscalls: " +#define DEBUG_SYSCALLS(...) DEBUG(_DEBUG_PREFIX __VA_ARGS__) + +#define _SYSCALL_ENTER_MESSAGE _DEBUG_PREFIX "> _native_pending_syscalls\n" +#define _SYSCALL_LEAVE_MESSAGE _DEBUG_PREFIX "< _native_pending_syscalls\n" void _native_syscall_enter(void) { _native_in_syscall++; if (IS_ACTIVE(ENABLE_DEBUG)) { - real_write(STDERR_FILENO, "> _native_in_syscall\n", 21); + real_write(STDERR_FILENO, _SYSCALL_ENTER_MESSAGE, sizeof(_SYSCALL_ENTER_MESSAGE) - 1); } } void _native_syscall_leave(void) { if (IS_ACTIVE(ENABLE_DEBUG)) { - real_write(STDERR_FILENO, "< _native_in_syscall\n", 21); + real_write(STDERR_FILENO, _SYSCALL_LEAVE_MESSAGE, sizeof(_SYSCALL_LEAVE_MESSAGE) - 1); } _native_in_syscall--; From 90a3f3ffcc3ae25f07ba5ac9fe2d1444cf7c26ea Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:34:02 +0100 Subject: [PATCH 03/13] cpu/native: docs and descriptive naming --- cpu/native/async_read.c | 16 +- cpu/native/include/cpu.h | 32 +-- cpu/native/include/cpu_conf.h | 29 ++- cpu/native/include/native_internal.h | 301 +++++++++++++++++++++------ cpu/native/irq_cpu.c | 173 ++++++--------- cpu/native/native_cpu.c | 34 ++- cpu/native/netdev_tap/netdev_tap.c | 44 ++-- cpu/native/panic.c | 12 +- cpu/native/periph/gpio_linux.c | 2 - cpu/native/periph/pm.c | 8 +- cpu/native/periph/timer.c | 2 +- cpu/native/socket_zep/socket_zep.c | 10 +- cpu/native/startup.c | 19 +- cpu/native/syscalls.c | 33 +-- sys/include/fs/native_fs.h | 8 +- 15 files changed, 410 insertions(+), 313 deletions(-) diff --git a/cpu/native/async_read.c b/cpu/native/async_read.c index 5aed77739e..81c84b513d 100644 --- a/cpu/native/async_read.c +++ b/cpu/native/async_read.c @@ -1,4 +1,4 @@ -/** +/* * Multiple asynchronous read on file descriptors * * Copyright (C) 2015 Ludwig Knüpfer , @@ -11,10 +11,7 @@ * General Public License v2.1. See the file LICENSE in the top level * directory for more details. * - * @ingroup cpu_native - * @{ - * @file - * @author Takuo Yonezawa + * Author: Takuo Yonezawa */ #include @@ -45,11 +42,11 @@ static void _async_io_isr(void) { } void native_async_read_setup(void) { - register_interrupt(SIGIO, _async_io_isr); + native_register_interrupt(SIGIO, _async_io_isr); } void native_async_read_cleanup(void) { - unregister_interrupt(SIGIO); + native_unregister_interrupt(SIGIO); for (int i = 0; i < _next_index; i++) { real_close(_fds[i].fd); @@ -115,12 +112,12 @@ void native_async_read_remove_handler(int fd) return; } - unregister_interrupt(SIGIO); + native_unregister_interrupt(SIGIO); for (; i < (unsigned)_next_index - 1; i++) { _fds[i] = _fds[i + 1]; } _next_index--; - register_interrupt(SIGIO, _async_io_isr); + native_register_interrupt(SIGIO, _async_io_isr); _fds[_next_index] = (struct pollfd){ 0 }; } @@ -179,4 +176,3 @@ static void _sigio_child(int index) sigwait(&sigmask, &sig); } } -/** @} */ diff --git a/cpu/native/include/cpu.h b/cpu/native/include/cpu.h index 20a8f6310b..ca9dd47364 100644 --- a/cpu/native/include/cpu.h +++ b/cpu/native/include/cpu.h @@ -5,18 +5,6 @@ * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ - -/** - * @ingroup cpu - * @defgroup cpu_native Native - * @brief Native CPU specific code - * @details The native CPU uses system calls to simulate hardware access. - * @ingroup cpu - * @brief CPU abstraction for the native port - * @{ - * @author Ludwig Knüpfer - */ - #ifndef CPU_H #define CPU_H @@ -28,6 +16,22 @@ extern "C" { #endif +/** + * @defgroup cpu_native Native CPU + * @ingroup cpu + * @brief CPU implementation for running RIOT on a Linux and BSD + * @author Ludwig Knüpfer + * + * The native CPU uses system calls to simulate hardware access. + * + * @{ + */ + +/* MARK: - Basics */ +/** + * @name + * @{ + */ /** * @brief The CPU supports unaligned memory access. * Even if the underlying architecture does not support it, the kernel will take care of it. @@ -44,10 +48,12 @@ __attribute__((always_inline)) static inline uintptr_t cpu_get_caller_pc(void) * it is the return address of the user of this function */ return (uintptr_t)__builtin_return_address(0); } +/** @} */ + +/** @} */ #ifdef __cplusplus } #endif -/** @} */ #endif /* CPU_H */ diff --git a/cpu/native/include/cpu_conf.h b/cpu/native/include/cpu_conf.h index 88d37cbb94..2dec361e2c 100644 --- a/cpu/native/include/cpu_conf.h +++ b/cpu/native/include/cpu_conf.h @@ -1,4 +1,4 @@ -/** +/* * Native CPU configuration * * Copyright (C) 2013 Ludwig Knüpfer @@ -6,12 +6,6 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer - * @} */ #ifndef CPU_CONF_H #define CPU_CONF_H @@ -21,7 +15,13 @@ extern "C" { #endif /** - * @brief CPU specific default stack sizes + * @addtogroup cpu_native + * @{ + */ + +/* MARK: - CPU-specific default stack sizes */ +/** + * @brief CPU-specific default stack sizes * * TODO: tighten stack sizes * @@ -53,6 +53,11 @@ extern "C" { #endif /** @} */ +/* MARK: - Networking constants */ +/** + * @name Networking constants + * @{ + */ /** * @brief Native internal Ethernet protocol number */ @@ -62,10 +67,12 @@ extern "C" { # undef CONFIG_GNRC_PKTBUF_SIZE # define CONFIG_GNRC_PKTBUF_SIZE (2048) #endif +/** @} */ +/* MARK: - Native flash emulation */ /** - * @brief Native Flash emulation - * Use unusual parameters to trigger edge cases + * @name Native flash emulation + * Use unusual parameters to trigger edge cases * @{ */ #ifndef FLASHPAGE_SIZE @@ -89,6 +96,8 @@ extern char _native_flash[FLASHPAGE_SIZE * FLASHPAGE_NUMOF]; #define CPU_FLASH_BASE ((uintptr_t)_native_flash) /** @} */ +/** @} */ + #ifdef __cplusplus } #endif diff --git a/cpu/native/include/native_internal.h b/cpu/native/include/native_internal.h index 154baf2b33..3e7e08f35d 100644 --- a/cpu/native/include/native_internal.h +++ b/cpu/native/include/native_internal.h @@ -11,50 +11,25 @@ */ /** - * @defgroup cpu_native_stdio STDIO for native - * @ingroup sys_stdio - * @brief Standard input/output backend for native + * @defgroup cpu_native_stdio STDIO for native + * @ingroup sys_stdio + * @brief Standard input/output backend for native * * This will hook up RIOT's stdio to the host's stdio fds. It is the default * stdio implementation of the board `native`. * - * @see cpu_native - */ - -/** - * @ingroup cpu_native - * @{ - * @author Ludwig Knüpfer + * @see @ref cpu_native */ #ifndef NATIVE_INTERNAL_H #define NATIVE_INTERNAL_H -#include +#include "util/ucontext.h" #include #include #include -/* enable signal handler register access on different platforms - * check here for more: - * http://sourceforge.net/p/predef/wiki/OperatingSystems/ - */ -#ifdef __FreeBSD__ -#ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE -#include -#undef _XOPEN_SOURCE -#else -#include -#endif -#elif defined(__linux__) -#ifndef _GNU_SOURCE -#define GNU_SOURCE -#include -#undef GNU_SOURCE -#else -#include -#endif -#endif /* BSD/Linux */ + +#include #include #include #include @@ -64,80 +39,270 @@ #include #include +#include "cpu_conf.h" +#include "thread.h" +#include "sched.h" + #ifdef __cplusplus extern "C" { #endif #include "syscalls.h" + /** - * Prototype for native's internal callbacks + * @addtogroup cpu_native + * @{ + */ + +/* MARK: - Internal native CPU API */ +/** + * @name Internal native CPU API + * @{ + */ + +/** + * @brief Prototype for native's internal callbacks */ typedef void (*_native_callback_t)(void); /** - * @cond INTERNAL - * internal functions + * @brief Initializes native CPU */ void native_cpu_init(void); +/** @} */ + +/* MARK: - Native Signal Handling */ +/** + * @name Native Signal Handling + * @{ + */ + +/** + * @brief A boolean variable indicating whether interrupts are currently permissible + * @private + */ +extern volatile bool _native_interrupts_enabled; + +/** + * @brief Pipe yielding signals + * @private + * + * The internal signal handler writes into the write end of this pipe + */ +extern int _signal_pipe_fd[2]; + +/** + * @brief Number of currently pending signals + * @private + */ +extern volatile int _native_pending_signals; + +/** + * @brief Registers signal handlers for the native CPU + */ void native_interrupt_init(void); -void native_irq_handler(void); +/** + * @brief Register interrupt handler handler for interrupt signal + * + * @param sig Signal number + * @param handler Signal action function + * + * @returns 0 on success, negative number otherwise. + */ +int native_register_interrupt(int sig, _native_callback_t handler); + +/** + * @brief Unregister interrupt handler for interrupt signal + * + * @param sig Signal number + * + * @returns 0 on success, negative number otherwise. + */ +int native_unregister_interrupt(int sig); + +/** + * @brief Calls signal handlers for pending signal, then exits ISR context and performs context switch + * @pre Intended to be called from **ISR context** + * @private + * + * The context switch back to userspace is performed using @ref `cpu_switch_context_exit`. + * + * @note While it would have been possible to separate this method's functionality into two functions, `setcontext` requires us to have a single function. + */ +void _native_call_sig_handlers_and_switch(void); + +/** + * @brief Switches to ISR context, then enables IRQ and returns to userspace + * + * @note This function is implemented in assembly. + */ extern void _native_sig_leave_tramp(void); -extern void _native_sig_leave_handler(void); +/** @} */ + +/* MARK: - System Calls */ +/** + * @name System Calls + * + * We wrap system calls and syscall-invoking library calls to ensure **no context switches occur during a system call**. + * @{ + */ +/** + * @brief Number of currently pending system calls + * @private + */ +extern volatile int _native_pending_syscalls; + +/** + * @brief Increment spending system call counter + */ +static inline void _native_pending_syscalls_up(void) { + _native_pending_syscalls += 1; +} + +/** + * @brief Decrements pending system call counter + */ +static inline void _native_pending_syscalls_down(void) { + _native_pending_syscalls -= 1; +} + +/** + * @brief Executes post-syscall logic + * @private + * + * Decrements internal pending syscall counter. + * + * If there are other pending system calls and when not already in an ISR context, this function switches to the ISR context and + * calls signals handlers. This is done through @ref `_native_call_sig_handlers_and_switch`. Returns to userspace + * thereafter. + */ void _native_syscall_leave(void); + +/** + * @brief Executes pre-syscall logic + * @private + * + * Increments internal pending syscall counter. + */ void _native_syscall_enter(void); + +/** + * @brief Registers system calls. + * + * Wraps syscall functions from the standard library. + */ void _native_init_syscalls(void); +/** @} */ +/* MARK: - Native Context Switching */ /** - -/** - * data structures + * @name Native Context Switching + * @{ + */ + +// TODO: do we still need to expose this? +extern volatile uintptr_t _native_user_fptr; + +/** + * @brief A boolean variable indicating whether program execution currently takes place in an ISR context */ -extern volatile int native_interrupts_enabled; -extern volatile uintptr_t _native_saved_eip; -extern int _sig_pipefd[2]; -extern volatile int _native_sigpend; extern volatile int _native_in_isr; -extern volatile int _native_in_syscall; -extern char __isr_stack[]; -extern const size_t __isr_stack_size; -extern ucontext_t native_isr_context; -extern ucontext_t end_context; -extern ucontext_t *_native_cur_ctx, *_native_isr_ctx; +/** + * @brief Stack used in ISR context + */ +extern char _isr_stack[THREAD_STACKSIZE_DEFAULT]; +/** + * @brief ISR context + */ +extern ucontext_t *_native_isr_context; + +/** + * @brief Resets internal `in_ISR` barrier switch and resumes execution on the currently scheduled thread + * @pre Intended to be executed in userspace + * @private + * + * @note This function is implemented in assembly to preserve registers. See `native.S` + */ +extern void _native_isr_leave(void); + + +/** @} */ + +/* MARK: - Native Process State */ +/** + * @name Native Process State + * @{ + */ +/** + * @brief Program name + * @private + */ extern const char *_progname; + +/** + * @brief Program argument values + * @private + */ extern char **_native_argv; + +/** + * @brief Process Identifier + * @private + */ extern pid_t _native_pid; + +/** + * @brief Process Identifier / CPUID ??? + * @private + */ extern pid_t _native_id; -extern unsigned _native_rng_seed; -extern int _native_rng_mode; /**< 0 = /dev/random, 1 = random(3) */ -extern const char *_native_unix_socket_path; +/** + * @brief Random number generator seed value + * @private + */ +extern unsigned int _native_rng_seed; + +/** + * @brief Random number generator mode + * @private + * + * - `0`: Use `/dev/random` + * - `1`: Use `random(3)` + */ +extern int _native_rng_mode; +/** @} */ + +/* MARK: - Native Read/Write Methods */ +/** + * @name Native Read/Write Methods + * @{ + */ +/** + * @brief Reads file, populates given buffer + */ ssize_t _native_read(int fd, void *buf, size_t count); + +/** + * @brief Writes given data into file + */ ssize_t _native_write(int fd, const void *buf, size_t count); + +/** + * @brief Performs a vectored write operation + */ ssize_t _native_writev(int fildes, const struct iovec *iov, int iovcnt); +/** @} */ -/** - * @endcond - */ -/** - * register interrupt handler handler for interrupt sig - */ -int register_interrupt(int sig, _native_callback_t handler); - -/** - * unregister interrupt handler for interrupt sig - */ -int unregister_interrupt(int sig); +/** @} */ #ifdef __cplusplus } #endif -#include "sched.h" - -/** @} */ #endif /* NATIVE_INTERNAL_H */ diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index e1c0d88323..cf7007f16a 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -1,4 +1,4 @@ -/** +/* * Native CPU irq.h implementation * * Copyright (C) 2013 Ludwig Knüpfer @@ -6,18 +6,8 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer */ -/* __USE_GNU for gregs[REG_EIP] access under glibc - * _GNU_SOURCE for REG_EIP and strsignal() under musl */ -#define __USE_GNU -#define _GNU_SOURCE - #include #include #include @@ -46,31 +36,38 @@ #include "debug.h" #define DEBUG_IRQ(...) DEBUG("[native] IRQ: " __VA_ARGS__) -volatile int native_interrupts_enabled = 0; +volatile bool _native_interrupts_enabled = false; volatile int _native_in_isr; -volatile int _native_in_syscall; +volatile int _native_pending_syscalls; -static sigset_t _native_sig_set, _native_sig_set_dint; +char _isr_stack[THREAD_STACKSIZE_DEFAULT]; +static ucontext_t _native_isr_context_storage; +ucontext_t *_native_isr_context = &_native_isr_context_storage; +ucontext_t *_native_current_context = NULL; -char __isr_stack[THREAD_STACKSIZE_DEFAULT]; -const size_t __isr_stack_size = sizeof(__isr_stack); -ucontext_t native_isr_context; -ucontext_t *_native_cur_ctx, *_native_isr_ctx; +volatile uintptr_t _native_user_fptr; -volatile uintptr_t _native_saved_eip; -volatile int _native_sigpend; -int _sig_pipefd[2]; +static sigset_t _native_sig_set; +static sigset_t _native_sig_set_dint; +volatile int _native_pending_signals; +int _signal_pipe_fd[2]; -static _native_callback_t native_irq_handlers[255]; +static _native_callback_t _native_irq_handlers[255]; + +static inline void _set_sigmask(ucontext_t *ctx) +{ + ctx->uc_sigmask = _native_sig_set_dint; + _native_interrupts_enabled = false; +} void *thread_isr_stack_pointer(void) { - return native_isr_context.uc_stack.ss_sp; + return _native_isr_context->uc_stack.ss_sp; } void *thread_isr_stack_start(void) { - return __isr_stack; + return _isr_stack; } void print_thread_sigmask(ucontext_t *cp) @@ -82,7 +79,7 @@ void print_thread_sigmask(ucontext_t *cp) } for (int i = 1; i < (NSIG); i++) { - if (native_irq_handlers[i] != NULL) { + if (_native_irq_handlers[i] != NULL) { printf("%s: %s\n", strsignal(i), (sigismember(&_native_sig_set, i) ? "blocked" : "unblocked") @@ -131,7 +128,7 @@ void native_print_signals(void) } for (int i = 1; i < (NSIG); i++) { - if (native_irq_handlers[i] != NULL || i == SIGUSR1) { + if (_native_irq_handlers[i] != NULL || i == SIGUSR1) { printf("%s: %s in active thread\n", strsignal(i), (sigismember(&_native_sig_set, i) ? "blocked" : "unblocked") @@ -166,8 +163,8 @@ unsigned irq_disable(void) err(EXIT_FAILURE, "irq_disable: sigprocmask"); } - prev_state = native_interrupts_enabled; - native_interrupts_enabled = 0; + prev_state = _native_interrupts_enabled; + _native_interrupts_enabled = false; DEBUG_IRQ("irq_disable(): return\n"); _native_syscall_leave(); @@ -197,8 +194,8 @@ unsigned irq_enable(void) * before returning to userspace. */ - prev_state = native_interrupts_enabled; - native_interrupts_enabled = 1; + prev_state = _native_interrupts_enabled; + _native_interrupts_enabled = true; if (sigprocmask(SIG_SETMASK, &_native_sig_set, NULL) == -1) { err(EXIT_FAILURE, "irq_enable: sigprocmask"); @@ -232,7 +229,7 @@ void irq_restore(unsigned state) bool irq_is_enabled(void) { - return native_interrupts_enabled; + return _native_interrupts_enabled; } bool irq_is_in(void) @@ -241,7 +238,7 @@ bool irq_is_in(void) return _native_in_isr; } -int _native_popsig(void) +static int _native_pop_sig(void) { int nread, nleft, i; int sig = 0; @@ -249,36 +246,32 @@ int _native_popsig(void) nleft = sizeof(int); i = 0; - while ((nleft > 0) && ((nread = real_read(_sig_pipefd[0], ((uint8_t*)&sig) + i, nleft)) != -1)) { + while ((nleft > 0) && ((nread = real_read(_signal_pipe_fd[0], ((uint8_t*)&sig) + i, nleft)) != -1)) { i += nread; nleft -= nread; } if (nread == -1) { - err(EXIT_FAILURE, "_native_popsig: real_read"); + err(EXIT_FAILURE, "_native_pop_sig: real_read"); } return sig; } -/** - * call signal handlers, - * restore user context - */ -void native_irq_handler(void) +void _native_call_sig_handlers_and_switch(void) { DEBUG_IRQ("\n\n\t\tcall sig handlers + switch\n\n"); - while (_native_sigpend > 0) { - int sig = _native_popsig(); - _native_sigpend--; + while (_native_pending_signals > 0) { + int sig = _native_pop_sig(); + _native_pending_signals--; - if (native_irq_handlers[sig] != NULL) { - native_irq_handlers[sig](); + if (_native_irq_handlers[sig]) { DEBUG_IRQ("call sig handlers + switch: calling interrupt handler for %i\n", sig); + _native_irq_handlers[sig](); } else if (sig == SIGUSR1) { - warnx("native_irq_handler: ignoring SIGUSR1"); + warnx("call sig handlers + switch: ignoring SIGUSR1"); } else { errx(EXIT_FAILURE, "XXX: no handler for signal %i\nXXX: this should not have happened!\n", sig); @@ -286,52 +279,41 @@ void native_irq_handler(void) } DEBUG_IRQ("call sig handlers + switch: return\n"); + + /* Leave ISR context */ cpu_switch_context_exit(); } -void isr_set_sigmask(ucontext_t *ctx) -{ - ctx->uc_sigmask = _native_sig_set_dint; - native_interrupts_enabled = 0; -} - -/** - * save signal, return to _native_sig_leave_tramp if possible - */ -void native_isr_entry(int sig, siginfo_t *info, void *context) +void native_signal_action(int sig, siginfo_t *info, void *context) { (void) info; /* unused at the moment */ - //printf("\n\033[33m\n\t\tnative_isr_entry(%i)\n\n\033[0m", sig); /* save the signal */ - if (real_write(_sig_pipefd[1], &sig, sizeof(int)) == -1) { - err(EXIT_FAILURE, "native_isr_entry: real_write()"); + if (real_write(_signal_pipe_fd[1], &sig, sizeof(int)) == -1) { + err(EXIT_FAILURE, "native_signal_action: real_write()"); } - _native_sigpend++; - //real_write(STDOUT_FILENO, "sigpend\n", 8); + _native_pending_signals++; if (context == NULL) { - errx(EXIT_FAILURE, "native_isr_entry: context is null - unhandled"); + errx(EXIT_FAILURE, "native_signal_action: context is null - unhandled"); } if (thread_get_active() == NULL) { _native_in_isr++; - warnx("native_isr_entry: thread_get_active() is null - unhandled"); + warnx("native_signal_action: thread_get_active() is null - unhandled"); _native_in_isr--; return; } /* XXX: Workaround safety check - whenever this happens it really * indicates a bug in irq_disable */ - if (native_interrupts_enabled == 0) { - //printf("interrupts are off, but I caught a signal.\n"); + if (!_native_interrupts_enabled) { return; } if (_native_in_isr != 0) { - //real_write(STDOUT_FILENO, "interrupts in ISR!!\n", 20); return; } - if (_native_in_syscall != 0) { + if (_native_pending_syscalls != 0) { DEBUG_IRQ("\n\n\t\tnative_signal_action: return to syscall\n\n"); return; } @@ -368,13 +350,7 @@ void native_isr_entry(int sig, siginfo_t *info, void *context) #endif } -/** - * Add or remove handler for signal - * - * To be called with interrupts disabled - * - */ -void set_signal_handler(int sig, bool add) +static void _set_signal_handler(int sig, bool add) { struct sigaction sa; int ret; @@ -404,7 +380,7 @@ void set_signal_handler(int sig, bool add) if (add) { sa.sa_flags |= SA_SIGINFO; /* sa.sa_sigaction is used */ - sa.sa_sigaction = native_isr_entry; + sa.sa_sigaction = native_signal_action; } else { sa.sa_handler = SIG_IGN; @@ -417,38 +393,30 @@ void set_signal_handler(int sig, bool add) _native_syscall_leave(); } -/** - * register signal/interrupt handler for signal sig - * - * TODO: use appropriate data structure for signal - * handlers. - */ -int register_interrupt(int sig, _native_callback_t handler) +/* TODO: use appropriate data structure for signal handlers. */ +int native_register_interrupt(int sig, _native_callback_t handler) { DEBUG_IRQ("native_register_interrupt\n"); unsigned state = irq_disable(); - native_irq_handlers[sig] = handler; - set_signal_handler(sig, true); + _native_irq_handlers[sig] = handler; + _set_signal_handler(sig, true); irq_restore(state); return 0; } -/** - * empty signal mask - */ -int unregister_interrupt(int sig) +int native_unregister_interrupt(int sig) { /* empty signal mask */ DEBUG_IRQ("native_unregister_interrupt\n"); unsigned state = irq_disable(); - set_signal_handler(sig, false); - native_irq_handlers[sig] = NULL; + _set_signal_handler(sig, false); + _native_irq_handlers[sig] = NULL; irq_restore(state); @@ -464,14 +432,10 @@ static void native_shutdown(int sig, siginfo_t *info, void *context) pm_off(); } -/** - * register internal signal handler, - * initialize local variables - * - * TODO: see register_interrupt - */ void native_interrupt_init(void) { + /* register internal signal handler, initialize local variables + * TODO: see native_register_interrupt */ struct sigaction sa; DEBUG_IRQ("native_interrupt_init\n"); @@ -479,13 +443,10 @@ void native_interrupt_init(void) VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n", (void *)__isr_stack, (void*)(__isr_stack + sizeof(__isr_stack))); - _native_sigpend = 0; + _native_pending_signals = 0; + memset(_native_irq_handlers, 0, sizeof(_native_irq_handlers)); - for (int i = 0; i < 255; i++) { - native_irq_handlers[i] = NULL; - } - - sa.sa_sigaction = native_isr_entry; + sa.sa_sigaction = native_signal_action; if (sigfillset(&sa.sa_mask) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigfillset"); @@ -517,7 +478,7 @@ void native_interrupt_init(void) err(EXIT_FAILURE, "native_interrupt_init: sigaction"); } - if (getcontext(&native_isr_context) == -1) { + if (getcontext(_native_isr_context) == -1) { err(EXIT_FAILURE, "native_interrupt_init: getcontext"); } @@ -536,16 +497,14 @@ void native_interrupt_init(void) err(EXIT_FAILURE, "native_interrupt_init: sigaltstack"); } - makecontext(&native_isr_context, native_irq_handler, 0); + _native_pending_syscalls = 0; - _native_in_syscall = 0; - - if (real_pipe(_sig_pipefd) == -1) { + if (real_pipe(_signal_pipe_fd) == -1) { err(EXIT_FAILURE, "native_interrupt_init: pipe"); } /* allow for ctrl+c to shut down gracefully always */ - //register_interrupt(SIGINT, native_shutdown); + //native_register_interrupt(SIGINT, native_shutdown); sa.sa_sigaction = native_shutdown; if (sigdelset(&_native_sig_set, SIGINT) == -1) { err(EXIT_FAILURE, "native_interrupt_init: sigdelset"); diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index e544648545..dc043e6faa 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -1,43 +1,31 @@ /* + * Native CPU kernel_intern.h and sched.h implementation + * * Copyright (C) 2016 Kaspar Schleiser * 2013 Ludwig Knüpfer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. + * + * Author: Ludwig Knüpfer + * Author: Kaspar Schleiser */ /** - * @ingroup cpu_native - * @{ - * * @file * @brief Native CPU kernel_intern.h and sched.h implementation - * - * in-process preemptive context switching utilizes POSIX ucontexts. - * (ucontext provides for architecture independent stack handling) - * * @author Ludwig Knüpfer * @author Kaspar Schleiser + * + * In-process preemptive context switching utilizes POSIX ucontexts. + * (ucontext provides for architecture independent stack handling) */ -/* __USE_GNU for gregs[REG_EIP] access under glibc - * _GNU_SOURCE for REG_EIP and strsignal() under musl */ -#define __USE_GNU -#define _GNU_SOURCE - #include -#include #include -#include #include -#if USE_LIBUCONTEXT -#include -#else -#include -#endif - #ifdef HAVE_VALGRIND_H #include #define VALGRIND_DEBUG DEBUG @@ -50,6 +38,8 @@ #endif #include +#include +#include #include "cpu.h" #include "cpu_conf.h" @@ -68,7 +58,7 @@ extern netdev_tap_t netdev_tap; #include "debug.h" #define DEBUG_CPU(...) DEBUG("[native] CPU: " __VA_ARGS__) -ucontext_t end_context; +static ucontext_t _end_context; /** * make the new context assign `_native_in_isr = 0` before resuming @@ -99,7 +89,7 @@ static void _native_mod_ctx_leave_sigh(ucontext_t *ctx) */ void thread_print_stack(void) { - DEBUG("thread_print_stack\n"); + CPU_DEBUG("thread_print_stack\n"); return; } diff --git a/cpu/native/netdev_tap/netdev_tap.c b/cpu/native/netdev_tap/netdev_tap.c index 444ac0f2c0..99cf572f07 100644 --- a/cpu/native/netdev_tap/netdev_tap.c +++ b/cpu/native/netdev_tap/netdev_tap.c @@ -16,6 +16,7 @@ * @author Kaspar Schleiser * @} */ + #include #include #include @@ -28,19 +29,20 @@ #include #include #include +#include /* needs to be included before native's declarations of ntohl etc. */ #include "byteorder.h" -#ifdef __FreeBSD__ -#include -#include -#include -#include +#if defined(__FreeBSD__) +# include +# include +# include +# include #else -#include -#include -#include +# include +# include +# include #endif #include "native_internal.h" @@ -209,14 +211,14 @@ static void _continue_reading(netdev_tap_t *dev) FD_ZERO(&rfds); FD_SET(dev->tap_fd, &rfds); - _native_in_syscall++; /* no switching here */ + _native_pending_syscalls_up(); /* no switching here */ if (real_select(dev->tap_fd + 1, &rfds, NULL, NULL, &t) == 1) { int sig = SIGIO; - extern int _sig_pipefd[2]; + extern int _signal_pipe_fd[2]; extern ssize_t (*real_write)(int fd, const void * buf, size_t count); - real_write(_sig_pipefd[1], &sig, sizeof(int)); - _native_sigpend++; + real_write(_signal_pipe_fd[1], &sig, sizeof(int)); + _native_pending_signals++; DEBUG("netdev_tap: sigpend++\n"); } else { @@ -224,7 +226,7 @@ static void _continue_reading(netdev_tap_t *dev) native_async_read_continue(dev->tap_fd); } - _native_in_syscall--; + _native_pending_syscalls_down(); } static int _recv(netdev_t *netdev, void *buf, size_t len, void *info) @@ -342,20 +344,20 @@ static int _init(netdev_t *netdev) } char *name = dev->tap_name; -#ifdef __FreeBSD__ +# ifdef __FreeBSD__ char clonedev[255] = "/dev/"; /* XXX bad size */ strncpy(clonedev + 5, name, 250); -#else /* Linux */ +# else /* Linux */ struct ifreq ifr; const char *clonedev = "/dev/net/tun"; -#endif +# endif /* initialize device descriptor */ dev->promiscuous = 0; /* implicitly create the tap interface */ if ((dev->tap_fd = real_open(clonedev, O_RDWR | O_NONBLOCK)) == -1) { err(EXIT_FAILURE, "open(%s)", clonedev); } -#if __FreeBSD__ /* FreeBSD */ +# if __FreeBSD__ /* FreeBSD */ struct ifaddrs *iflist; if (real_getifaddrs(&iflist) == 0) { for (struct ifaddrs *cur = iflist; cur; cur = cur->ifa_next) { @@ -367,12 +369,12 @@ static int _init(netdev_t *netdev) } real_freeifaddrs(iflist); } -#else /* Linux */ +# else /* Linux */ memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; strncpy(ifr.ifr_name, name, IFNAMSIZ); if (real_ioctl(dev->tap_fd, TUNSETIFF, (void *)&ifr) == -1) { - _native_in_syscall++; + _native_pending_syscalls_up(); warn("ioctl TUNSETIFF"); warnx("probably the tap interface (%s) does not exist or is already in use", name); real_exit(EXIT_FAILURE); @@ -382,7 +384,7 @@ static int _init(netdev_t *netdev) memset(&ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", name); if (real_ioctl(dev->tap_fd, SIOCGIFHWADDR, &ifr) == -1) { - _native_in_syscall++; + _native_pending_syscalls_up(); warn("ioctl SIOCGIFHWADDR"); if (real_close(dev->tap_fd) == -1) { warn("close"); @@ -393,7 +395,7 @@ static int _init(netdev_t *netdev) /* change mac addr so it differs from what the host is using */ dev->addr[5]++; -#endif +# endif DEBUG("gnrc_tapnet_init(): dev->addr = %02x:%02x:%02x:%02x:%02x:%02x\n", dev->addr[0], dev->addr[1], dev->addr[2], dev->addr[3], dev->addr[4], dev->addr[5]); diff --git a/cpu/native/panic.c b/cpu/native/panic.c index 127df9f005..67a79ce1bd 100644 --- a/cpu/native/panic.c +++ b/cpu/native/panic.c @@ -7,15 +7,11 @@ */ /** - * @ingroup cpu_native - * @{ - * * @file - * @brief Crash handling functions implementation for 'native' port - * - * @author Ludwig Knüpfer - * @author Kévin Roussel - * @author Oliver Hahm + * @brief Crash handling functions implementation for 'native' port + * @author Ludwig Knüpfer + * @author Kévin Roussel + * @author Oliver Hahm */ #include diff --git a/cpu/native/periph/gpio_linux.c b/cpu/native/periph/gpio_linux.c index 2b32790e99..f04e749b86 100644 --- a/cpu/native/periph/gpio_linux.c +++ b/cpu/native/periph/gpio_linux.c @@ -17,8 +17,6 @@ * @author Benjamin Valentin */ -#define _GNU_SOURCE - #include #include #include diff --git a/cpu/native/periph/pm.c b/cpu/native/periph/pm.c index a1215163ef..19de1c92c7 100644 --- a/cpu/native/periph/pm.c +++ b/cpu/native/periph/pm.c @@ -40,12 +40,12 @@ unsigned _native_retval = EXIT_SUCCESS; static void _native_sleep(void) { - _native_in_syscall++; /* no switching here */ + _native_pending_syscalls_up(); /* no switching here */ real_pause(); - _native_in_syscall--; + _native_pending_syscalls_down(); - if (_native_sigpend > 0) { - _native_in_syscall++; + if (_native_pending_signals > 0) { + _native_pending_syscalls_up(); _native_syscall_leave(); } } diff --git a/cpu/native/periph/timer.c b/cpu/native/periph/timer.c index 7a80baa2e3..479aeb4e64 100644 --- a/cpu/native/periph/timer.c +++ b/cpu/native/periph/timer.c @@ -121,7 +121,7 @@ int timer_init(tim_t dev, uint32_t freq, timer_cb_t cb, void *arg) return -1; } - if (register_interrupt(SIGALRM, native_isr_timer) != 0) { + if (native_register_interrupt(SIGALRM, native_isr_timer) != 0) { DEBUG_PUTS("Failed to register SIGALRM handler"); timer_delete(itimer_monotonic); return -1; diff --git a/cpu/native/socket_zep/socket_zep.c b/cpu/native/socket_zep/socket_zep.c index ea5617de5a..aaa432e5d4 100644 --- a/cpu/native/socket_zep/socket_zep.c +++ b/cpu/native/socket_zep/socket_zep.c @@ -88,19 +88,19 @@ static void _continue_reading(socket_zep_t *dev) FD_ZERO(&rfds); FD_SET(dev->sock_fd, &rfds); - _native_in_syscall++; /* no switching here */ + _native_pending_syscalls_up(); /* no switching here */ if (real_select(dev->sock_fd + 1, &rfds, NULL, NULL, &t) == 1) { int sig = SIGIO; - extern int _sig_pipefd[2]; - real_write(_sig_pipefd[1], &sig, sizeof(sig)); - _native_sigpend++; + extern int _signal_pipe_fd[2]; + real_write(_signal_pipe_fd[1], &sig, sizeof(sig)); + _native_pending_signals++; } else { native_async_read_continue(dev->sock_fd); } - _native_in_syscall--; + _native_pending_syscalls_down(); } static inline bool _dst_not_me(socket_zep_t *dev, const void *buf) diff --git a/cpu/native/startup.c b/cpu/native/startup.c index cc1abfaa38..b0959267e4 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -1,5 +1,4 @@ -/** - * Native CPU entry code +/* Native CPU entry code * * Copyright (C) 2013 Ludwig Knüpfer * 2017 Freie Universität Berlin @@ -8,24 +7,16 @@ * General Public License v2.1. See the file LICENSE in the top level * directory for more details. * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer - * @author Martine Lenders - * @} + * Author: Ludwig Knüpfer + * Author: Martine Lenders */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE #include -#else -#include -#endif #include #include #include #include +#include #include #include #include @@ -728,7 +719,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e periph_init(); board_init(); - register_interrupt(SIGUSR1, _reset_handler); + native_register_interrupt(SIGUSR1, _reset_handler); puts("RIOT native hardware initialization complete.\n"); irq_enable(); diff --git a/cpu/native/syscalls.c b/cpu/native/syscalls.c index 5d2230ac00..1ee05c3703 100644 --- a/cpu/native/syscalls.c +++ b/cpu/native/syscalls.c @@ -1,5 +1,4 @@ -/** - * Native CPU syscall managing +/* Native CPU syscall managing * * Wrap system calls and system call invoking library calls to make * sure no context switches happen during a system call. @@ -9,20 +8,9 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE #include -#else -#include -#endif - #include #include #include @@ -32,7 +20,7 @@ #include #include #ifdef MODULE_LIBC_GETTIMEOFDAY -#include +# include #endif #include #include @@ -40,8 +28,8 @@ #include "cpu.h" #include "irq.h" #ifdef MODULE_LIBC_GETTIMEOFDAY -#include "time_units.h" -#include "ztimer64.h" +# include "time_units.h" +# include "ztimer64.h" #endif #include "stdio_base.h" @@ -61,7 +49,7 @@ void _native_syscall_enter(void) { - _native_in_syscall++; + _native_pending_syscalls_up(); if (IS_ACTIVE(ENABLE_DEBUG)) { real_write(STDERR_FILENO, _SYSCALL_ENTER_MESSAGE, sizeof(_SYSCALL_ENTER_MESSAGE) - 1); @@ -74,12 +62,12 @@ void _native_syscall_leave(void) real_write(STDERR_FILENO, _SYSCALL_LEAVE_MESSAGE, sizeof(_SYSCALL_LEAVE_MESSAGE) - 1); } - _native_in_syscall--; + _native_pending_syscalls_down(); if ( - (_native_sigpend > 0) + (_native_pending_signals > 0) && (_native_in_isr == 0) - && (_native_in_syscall == 0) - && (native_interrupts_enabled == 1) + && (_native_pending_syscalls == 0) + && (_native_interrupts_enabled) && (thread_get_active() != NULL) ) { @@ -454,9 +442,6 @@ int _gettimeofday(struct timeval *tp, void *restrict tzp) } #endif -/** - * set up native internal syscall symbols - */ void _native_init_syscalls(void) { *(void **)(&real_read) = dlsym(RTLD_NEXT, "read"); diff --git a/sys/include/fs/native_fs.h b/sys/include/fs/native_fs.h index 1a521990fc..5abfd90922 100644 --- a/sys/include/fs/native_fs.h +++ b/sys/include/fs/native_fs.h @@ -7,14 +7,14 @@ */ /** - * @defgroup sys_fs_native native fs integration - * @ingroup cpu_native - * @brief Access to the host fs from RIOT native + * @defgroup sys_fs_native Native FS Integration + * @ingroup cpu_native + * @brief Access to the host filesystem from RIOT native * * @{ * * @file - * @brief native integration with vfs + * @brief Native integration with virtual filesystem (VFS) * * @author Benjamin Valentin */ From 64283b52aa71d69ed5404e8164692f0ff927266a Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Sat, 8 Mar 2025 15:20:01 +0100 Subject: [PATCH 04/13] cpu/native: doxygen gardening --- cpu/native/async_read.c | 11 +- cpu/native/backtrace/backtrace.c | 6 +- cpu/native/cli_eui_provider/eui_provider.c | 13 +-- cpu/native/fs/native_fs.c | 11 +- cpu/native/include/architecture_arch.h | 27 +++-- cpu/native/include/async_read.h | 11 +- cpu/native/include/atomic_utils_arch.h | 17 +-- cpu/native/include/backtrace.h | 18 +-- cpu/native/include/can_params.h | 12 +- cpu/native/include/candev_linux.h | 72 ++++++------ cpu/native/include/cpu.h | 31 ++--- cpu/native/include/cpu_conf.h | 102 +++++++++++++---- cpu/native/include/eeprom_native.h | 15 ++- cpu/native/include/gpiodev_linux.h | 19 ++-- cpu/native/include/mtd_native.h | 13 +-- cpu/native/include/native_cli_eui_provider.h | 20 ++-- cpu/native/include/native_internal.h | 32 +++--- cpu/native/include/netdev_tap.h | 23 ++-- cpu/native/include/netdev_tap_params.h | 12 +- cpu/native/include/periph_conf.h | 43 +++---- cpu/native/include/periph_cpu.h | 114 ++++++++++--------- cpu/native/include/socket_zep.h | 17 +-- cpu/native/include/socket_zep_params.h | 11 +- cpu/native/include/spidev_linux.h | 19 ++-- cpu/native/include/thread_arch.h | 12 +- cpu/native/include/tty_uart.h | 12 +- cpu/native/irq_cpu.c | 10 +- cpu/native/mtd/mtd_native.c | 10 +- cpu/native/native_cpu.c | 12 +- cpu/native/netdev_tap/netdev_tap.c | 5 +- cpu/native/panic.c | 9 +- cpu/native/periph/can.c | 14 +-- cpu/native/periph/cpuid.c | 13 +-- cpu/native/periph/eeprom.c | 12 +- cpu/native/periph/flashpage.c | 12 +- cpu/native/periph/gpio_linux.c | 13 +-- cpu/native/periph/gpio_mock.c | 13 +-- cpu/native/periph/hwrng.c | 27 ++--- cpu/native/periph/pm.c | 11 +- cpu/native/periph/pwm.c | 12 +- cpu/native/periph/qdec.c | 13 +-- cpu/native/periph/rtc.c | 12 +- cpu/native/periph/spidev_linux.c | 12 +- cpu/native/periph/timer.c | 16 ++- cpu/native/periph/uart.c | 13 +-- cpu/native/socket_zep/socket_zep.c | 8 +- cpu/native/startup.c | 13 ++- cpu/native/stdio_native/stdio_native.c | 6 +- cpu/native/syscalls.c | 18 ++- cpu/native/vfs/native_vfs.c | 11 +- 50 files changed, 495 insertions(+), 493 deletions(-) diff --git a/cpu/native/async_read.c b/cpu/native/async_read.c index 81c84b513d..58a0e0881d 100644 --- a/cpu/native/async_read.c +++ b/cpu/native/async_read.c @@ -1,6 +1,4 @@ /* - * Multiple asynchronous read on file descriptors - * * Copyright (C) 2015 Ludwig Knüpfer , * Martine Lenders * Kaspar Schleiser @@ -10,8 +8,13 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * Author: Takuo Yonezawa + */ + +/** + * @file + * @brief Multiple asynchronous read on file descriptors + * @ingroup cpu_native + * @author Takuo Yonezawa */ #include diff --git a/cpu/native/backtrace/backtrace.c b/cpu/native/backtrace/backtrace.c index f17157f1cf..cb38361293 100644 --- a/cpu/native/backtrace/backtrace.c +++ b/cpu/native/backtrace/backtrace.c @@ -7,9 +7,9 @@ */ /** - * @{ - * * @file + * @ingroup cpu_native + * @brief Backtrace implementation for native CPU * @author Martine Lenders */ @@ -55,5 +55,3 @@ int backtrace_len(void) return backtrace(array, BACKTRACE_SIZE + 1) - 1; } - -/** @} */ diff --git a/cpu/native/cli_eui_provider/eui_provider.c b/cpu/native/cli_eui_provider/eui_provider.c index b187b19743..1ed2723117 100644 --- a/cpu/native/cli_eui_provider/eui_provider.c +++ b/cpu/native/cli_eui_provider/eui_provider.c @@ -1,17 +1,16 @@ -/** - * Native CPU EUI provider - * +/* * Copyright (C) 2020 Benjamin Valentin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * @ingroup cpu_native - * @{ + */ + +/** * @file + * @ingroup cpu_native + * @brief Native CPU EUI provider * @author Benjamin Valentin - * @} */ #include diff --git a/cpu/native/fs/native_fs.c b/cpu/native/fs/native_fs.c index 8d8bcba700..3d1fd24867 100644 --- a/cpu/native/fs/native_fs.c +++ b/cpu/native/fs/native_fs.c @@ -7,15 +7,10 @@ */ /** - * @ingroup sys_fs_native - * @{ - * * @file - * @brief native integration with vfs - * - * @author Benjamin Valentin - * - * @} + * @ingroup sys_fs_native + * @brief Native integration with virtual filesystem (VFS) + * @author Benjamin Valentin */ #include diff --git a/cpu/native/include/architecture_arch.h b/cpu/native/include/architecture_arch.h index 604dd08b39..6df3954a14 100644 --- a/cpu/native/include/architecture_arch.h +++ b/cpu/native/include/architecture_arch.h @@ -7,16 +7,15 @@ */ /** - * @ingroup cpu_native + * @addtogroup cpu_native * @{ - * - * @file - * @brief Architecture details - * - * @author Marian Buschsieweke - * */ +/** + * @file + * @brief Architecture details + * @author Marian Buschsieweke + */ #ifndef ARCHITECTURE_ARCH_H #define ARCHITECTURE_ARCH_H @@ -33,17 +32,17 @@ void native_breakpoint(void); /* Doc is provided centrally in architecture.h, hide this from Doxygen */ #ifndef DOXYGEN -#if (__SIZEOF_POINTER__ == 8) -#define ARCHITECTURE_WORD_BITS (64U) -#else -#define ARCHITECTURE_WORD_BITS (32U) -#endif -#define ARCHITECTURE_BREAKPOINT(v) native_breakpoint() +# if (__SIZEOF_POINTER__ == 8) +# define ARCHITECTURE_WORD_BITS (64U) +# else +# define ARCHITECTURE_WORD_BITS (32U) +# endif +# define ARCHITECTURE_BREAKPOINT(v) native_breakpoint() #endif /* DOXYGEN */ #ifdef __cplusplus } #endif -/** @} */ #endif /* ARCHITECTURE_ARCH_H */ +/** @} */ diff --git a/cpu/native/include/async_read.h b/cpu/native/include/async_read.h index 3f36ab1af5..e483c27433 100644 --- a/cpu/native/include/async_read.h +++ b/cpu/native/include/async_read.h @@ -7,13 +7,14 @@ */ /** - * @ingroup cpu_native + * @addtogroup cpu_native * @{ - * + */ + +/** * @file - * @brief Multiple asynchronous read on file descriptors - * - * @author Takuo Yonezawa + * @brief Multiple asynchronous read on file descriptors + * @author Takuo Yonezawa */ #ifndef ASYNC_READ_H #define ASYNC_READ_H diff --git a/cpu/native/include/atomic_utils_arch.h b/cpu/native/include/atomic_utils_arch.h index eda75e6449..32c52c9620 100644 --- a/cpu/native/include/atomic_utils_arch.h +++ b/cpu/native/include/atomic_utils_arch.h @@ -7,18 +7,17 @@ */ /** - * @ingroup cpu_native - * + * @addtogroup cpu_native * @{ - * - * @file - * @brief Implementation of fast atomic utility functions - * @author Marian Buschsieweke */ +/** + * @file + * @brief Implementation of fast atomic utility functions + * @author Marian Buschsieweke + */ #ifndef ATOMIC_UTILS_ARCH_H #define ATOMIC_UTILS_ARCH_H -#ifndef DOXYGEN #include "periph_cpu.h" @@ -26,6 +25,8 @@ extern "C" { #endif +#ifndef DOXYGEN + /* clang provides no built-in atomic access to regular variables */ #ifndef __clang__ @@ -66,11 +67,11 @@ static inline void atomic_store_u32(volatile uint32_t *dest, uint32_t val) } #endif /* __clang__ */ +#endif /* DOXYGEN */ #ifdef __cplusplus } #endif -#endif /* DOXYGEN */ #endif /* ATOMIC_UTILS_ARCH_H */ /** @} */ diff --git a/cpu/native/include/backtrace.h b/cpu/native/include/backtrace.h index 2174607080..84a83d41af 100644 --- a/cpu/native/include/backtrace.h +++ b/cpu/native/include/backtrace.h @@ -7,19 +7,19 @@ */ /** - * @defgroup backtrace Stack backtrace (only under native) - * @ingroup core_util - * @brief Backtrace functionalitry + * @defgroup backtrace Stack backtrace (only under native) + * @ingroup core_util + * @brief Backtrace functionalitry + * @{ * * If you call the @ref backtrace_print() function a stack backtrace of all return * addresses up to @ref BACKTRACE_SIZE will be printed from the point of execution. - * - * @{ - * + */ + +/** * @file - * @brief - * - * @author Martine Lenders + * @brief Backtrace functionalitry + * @author Martine Lenders */ #ifndef BACKTRACE_H #define BACKTRACE_H diff --git a/cpu/native/include/can_params.h b/cpu/native/include/can_params.h index 36e69962ea..16d83249af 100644 --- a/cpu/native/include/can_params.h +++ b/cpu/native/include/can_params.h @@ -7,15 +7,15 @@ */ /** - * @ingroup drivers_candev_linux + * @addtogroup drivers_candev_linux * @{ - * - * @file - * @brief Default linux can config - * - * @author Vincent Dupont */ +/** + * @file + * @brief Default linux can config + * @author Vincent Dupont + */ #ifndef CAN_PARAMS_H #define CAN_PARAMS_H diff --git a/cpu/native/include/candev_linux.h b/cpu/native/include/candev_linux.h index c911c9bee8..d5c082273f 100644 --- a/cpu/native/include/candev_linux.h +++ b/cpu/native/include/candev_linux.h @@ -7,19 +7,19 @@ */ /** - * @defgroup drivers_candev_linux SocketCAN driver - * @ingroup drivers_can - * @brief Implementation of simulated CAN controller driver using SocketCAN on Linux + * @defgroup drivers_candev_linux SocketCAN driver + * @ingroup drivers_can + * @brief Implementation of simulated CAN controller driver using SocketCAN on Linux * @{ - * - * @file - * @brief Implementation of simulated CAN controller driver using SocketCAN on Linux - * - * @author Hermann Lelong - * @author Aurelien Gonce - * @author Vincent Dupont */ +/** + * @file + * @brief Implementation of simulated CAN controller driver using SocketCAN on Linux + * @author Hermann Lelong + * @author Aurelien Gonce + * @author Vincent Dupont + */ #ifndef CANDEV_LINUX_H #define CANDEV_LINUX_H @@ -29,48 +29,42 @@ extern "C" { #if defined(__linux__) /* SocketCAN is supported only on Linux */ || defined(DOXYGEN) -#include +# include -#include "can/device.h" -#include "can/candev.h" -#include "mutex.h" +# include "can/device.h" +# include "can/candev.h" +# include "mutex.h" /** - * Maximum size of an interface name + * @brief Maximum size of an interface name */ -#define CAN_MAX_SIZE_INTERFACE_NAME (5) +# define CAN_MAX_SIZE_INTERFACE_NAME (5) /** - * Linux candev configuration + * @brief Linux candev configuration */ typedef struct candev_conf { /** local interface name */ char interface_name[CAN_MAX_SIZE_INTERFACE_NAME + 1]; } can_conf_t; -/** CAN device configuration type can_conf_t is redefined by native CAN */ -#define HAVE_CAN_CONF_T +/** @brief CAN device configuration type can_conf_t is redefined by native CAN */ +# define HAVE_CAN_CONF_T -#ifndef CANDEV_LINUX_MAX_FILTERS_RX -/** - * Max number of rx filters which can be set - */ -#define CANDEV_LINUX_MAX_FILTERS_RX (16) -#endif +# if !defined(CANDEV_LINUX_MAX_FILTERS_RX) || defined(DOXYGEN) +/** @brief Max number of rx filters which can be set */ +# define CANDEV_LINUX_MAX_FILTERS_RX (16) +# endif -#ifndef CANDEV_LINUX_DEFAULT_BITRATE -/** - * Default bitrate setup - */ -#define CANDEV_LINUX_DEFAULT_BITRATE (500000) -#endif +# if !defined(CANDEV_LINUX_DEFAULT_BITRATE) || defined(DOXYGEN) +/** @brief Default bitrate setup */ +# define CANDEV_LINUX_DEFAULT_BITRATE (500000) +# endif -#ifndef CANDEV_LINUX_DEFAULT_SPT -/** - * Default sampling point setup - */ -#define CANDEV_LINUX_DEFAULT_SPT (875) -#endif +# if !defined(CANDEV_LINUX_DEFAULT_SPT) || defined(DOXYGEN) +/** @brief Default sampling point setup*/ +# define CANDEV_LINUX_DEFAULT_SPT (875) +# endif /** * @brief The candev_linux struct @@ -83,8 +77,8 @@ typedef struct candev_linux { struct can_filter filters[CANDEV_LINUX_MAX_FILTERS_RX]; } can_t; -/** CAN device type can_t is redefined by native CAN */ -#define HAVE_CAN_T +/** @brief CAN device type can_t is redefined by native CAN */ +# define HAVE_CAN_T /** * @brief Array containing socketCAN device names diff --git a/cpu/native/include/cpu.h b/cpu/native/include/cpu.h index ca9dd47364..5eb3830d07 100644 --- a/cpu/native/include/cpu.h +++ b/cpu/native/include/cpu.h @@ -5,6 +5,23 @@ * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ + +/** + * @defgroup cpu_native Native CPU + * @ingroup cpu + * @brief CPU implementation for running RIOT on a Linux and BSD + * @author Ludwig Knüpfer + * + * The native CPU uses system calls to simulate hardware access. + * + * @{ + */ + +/** + * @file + * @brief Native CPU header + * @author Ludwig Knüpfer + */ #ifndef CPU_H #define CPU_H @@ -16,17 +33,6 @@ extern "C" { #endif -/** - * @defgroup cpu_native Native CPU - * @ingroup cpu - * @brief CPU implementation for running RIOT on a Linux and BSD - * @author Ludwig Knüpfer - * - * The native CPU uses system calls to simulate hardware access. - * - * @{ - */ - /* MARK: - Basics */ /** * @name @@ -50,10 +56,9 @@ __attribute__((always_inline)) static inline uintptr_t cpu_get_caller_pc(void) } /** @} */ -/** @} */ - #ifdef __cplusplus } #endif #endif /* CPU_H */ +/** @} */ diff --git a/cpu/native/include/cpu_conf.h b/cpu/native/include/cpu_conf.h index 2dec361e2c..28797134c6 100644 --- a/cpu/native/include/cpu_conf.h +++ b/cpu/native/include/cpu_conf.h @@ -1,12 +1,21 @@ /* - * Native CPU configuration - * * Copyright (C) 2013 Ludwig Knüpfer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ + +/** + * @addtogroup cpu_native + * @{ + */ + +/** + * @file + * @brief Native CPU configuration + * @author Ludwig Knüpfer + */ #ifndef CPU_CONF_H #define CPU_CONF_H @@ -14,40 +23,56 @@ extern "C" { #endif -/** - * @addtogroup cpu_native - * @{ - */ - /* MARK: - CPU-specific default stack sizes */ /** * @brief CPU-specific default stack sizes * - * TODO: tighten stack sizes + * @todo TODO: tighten stack sizes * * @{ */ #ifndef THREAD_STACKSIZE_DEFAULT #if (__SIZEOF_POINTER__ == 8) +/** + * @brief Default size of a thread stack on 64-bit platforms + */ #define THREAD_STACKSIZE_DEFAULT (16384) #else +/** + * @brief Default size of a thread stack + */ #define THREAD_STACKSIZE_DEFAULT (8192) #endif #endif +/** + * @brief Default size of idle thread stack + */ #ifndef THREAD_STACKSIZE_IDLE #define THREAD_STACKSIZE_IDLE (THREAD_STACKSIZE_DEFAULT) #endif +/** + * @brief Extra stack buffer capacity needed for `printf` + */ #ifndef THREAD_EXTRA_STACKSIZE_PRINTF #define THREAD_EXTRA_STACKSIZE_PRINTF (4096) #endif +/** + * @brief Extra stack buffer capacity needed for `printf` in floating-point operations + */ #ifndef THREAD_EXTRA_STACKSIZE_PRINTF_FLOAT #define THREAD_EXTRA_STACKSIZE_PRINTF_FLOAT (4096) #endif /* for core/include/thread.h */ +/** + * @brief Minimum thread size + */ #ifndef THREAD_STACKSIZE_MINIMUM #define THREAD_STACKSIZE_MINIMUM (THREAD_STACKSIZE_DEFAULT) #endif /* native internal */ +/** + * @brief Size of stack used in ISR context + */ #ifndef ISR_STACKSIZE #define ISR_STACKSIZE (THREAD_STACKSIZE_DEFAULT) #endif @@ -75,31 +100,62 @@ extern "C" { * Use unusual parameters to trigger edge cases * @{ */ +/** + * @brief Size of a single emulated flash page + */ #ifndef FLASHPAGE_SIZE -#define FLASHPAGE_SIZE (512) -#endif -#ifndef FLASHPAGE_NUMOF -#define FLASHPAGE_NUMOF (32) -#endif -#ifndef FLASHPAGE_WRITE_BLOCK_ALIGNMENT -#define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (8) -#endif -#ifndef FLASHPAGE_WRITE_BLOCK_SIZE -#define FLASHPAGE_WRITE_BLOCK_SIZE (16) -#endif -#ifndef FLASHPAGE_ERASE_STATE -#define FLASHPAGE_ERASE_STATE (0x0) +# define FLASHPAGE_SIZE (512) #endif +/** + * @brief Total number of emulated flash pages + */ +#ifndef FLASHPAGE_NUMOF +# define FLASHPAGE_NUMOF (32) +#endif + +/** + * @brief Flashpage alignment + * + * The address passed to @ref flashpage_write must be a multiple of this constant. + */ +#ifndef FLASHPAGE_WRITE_BLOCK_ALIGNMENT +# define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (8) +#endif +/** + * @brief Flashpage block size + * + * When writing to flash, the data size must be a multiple of this constant. + * + * @see @ref flashpage_write + */ +#ifndef FLASHPAGE_WRITE_BLOCK_SIZE +# define FLASHPAGE_WRITE_BLOCK_SIZE (16) +#endif + +/** + * @brief Value of bytes in erased flash + * + * The flash is set to this constant when you call @ref flashpage_erase. + */ +#ifndef FLASHPAGE_ERASE_STATE +# define FLASHPAGE_ERASE_STATE (0x0) +#endif + +/** + * @brief Emulated flash buffer + */ extern char _native_flash[FLASHPAGE_SIZE * FLASHPAGE_NUMOF]; +/** + * @brief Base buffer pointer to emulated flash + */ #define CPU_FLASH_BASE ((uintptr_t)_native_flash) /** @} */ -/** @} */ - #ifdef __cplusplus } #endif #endif /* CPU_CONF_H */ +/** @} */ diff --git a/cpu/native/include/eeprom_native.h b/cpu/native/include/eeprom_native.h index eb1238029a..518b29fb17 100644 --- a/cpu/native/include/eeprom_native.h +++ b/cpu/native/include/eeprom_native.h @@ -7,17 +7,16 @@ */ /** - * @defgroup drivers_eeprom_native Native extra API for EEPROM - * @ingroup cpu_native - * @brief Implementation of EEPROM buffer persistence in file. - * + * @defgroup drivers_eeprom_native Native extra API for EEPROM + * @ingroup cpu_native + * @brief Implementation of EEPROM buffer persistence in file. * @{ - * - * @file - * - * @author Alexandre Abadie */ +/** + * @file + * @author Alexandre Abadie + */ #ifndef EEPROM_NATIVE_H #define EEPROM_NATIVE_H diff --git a/cpu/native/include/gpiodev_linux.h b/cpu/native/include/gpiodev_linux.h index 456bdf659c..f65c119908 100644 --- a/cpu/native/include/gpiodev_linux.h +++ b/cpu/native/include/gpiodev_linux.h @@ -7,9 +7,10 @@ */ /** - * @defgroup drivers_gpio_linux Linux User Mode GPIO Driver - * @ingroup cpu_native - * @brief Implementation of GPIO access from Linux User Space + * @defgroup drivers_gpio_linux Linux User Mode GPIO Driver + * @ingroup cpu_native + * @brief Implementation of GPIO access from Linux User Space + * @{ * * This module allows to connect a RIOT application that runs on a Linux host to * the physical GPIO pins of that host. To do so, the application has to be @@ -34,15 +35,13 @@ * port would be PIN(0,1) and so on. * * Please refer to your board's documentation for the mapping of the pins. - * - * @{ - * - * @file - * @brief Implementation of GPIO access from Linux User Space - * - * @author Benjamin Valentin */ +/** + * @file + * @brief Implementation of GPIO access from Linux User Space + * @author Benjamin Valentin + */ #ifndef GPIODEV_LINUX_H #define GPIODEV_LINUX_H diff --git a/cpu/native/include/mtd_native.h b/cpu/native/include/mtd_native.h index 7ba16cbeb4..0eee280176 100644 --- a/cpu/native/include/mtd_native.h +++ b/cpu/native/include/mtd_native.h @@ -7,16 +7,16 @@ */ /** - * @ingroup drivers_mtd + * @addtogroup drivers_mtd * @defgroup drivers_mtd_native Native MTD + * @brief MTD flash emulation for native * @{ - * @brief mtd flash emulation for native - * - * @file - * - * @author Vincent Dupont */ +/** + * @file + * @author Vincent Dupont + */ #ifndef MTD_NATIVE_H #define MTD_NATIVE_H @@ -42,5 +42,4 @@ extern const mtd_desc_t native_flash_driver; #endif #endif /* MTD_NATIVE_H */ - /** @} */ diff --git a/cpu/native/include/native_cli_eui_provider.h b/cpu/native/include/native_cli_eui_provider.h index 0ed57a7a22..a019c73986 100644 --- a/cpu/native/include/native_cli_eui_provider.h +++ b/cpu/native/include/native_cli_eui_provider.h @@ -7,15 +7,15 @@ */ /** - * @ingroup cpu_native + * @addtogroup cpu_native * @{ - * - * @file - * @brief Command-line EUI provider for native - * - * @author Benjamin Valentin */ +/** + * @file + * @brief Command-line EUI provider for native + * @author Benjamin Valentin + */ #ifndef NATIVE_CLI_EUI_PROVIDER_H #define NATIVE_CLI_EUI_PROVIDER_H @@ -26,17 +26,17 @@ extern "C" { #endif /** - * @name parse a string as an EUI-64 and add it to the list of EUI-64s + * @brief parse a string as an EUI-64 and add it to the list of EUI-64s * - * @param s[in] EUI-64 as hexadecimal string representation + * @param[in] s EUI-64 as hexadecimal string representation */ void native_cli_add_eui64(const char *s); /** - * @name Get a command-line provided EUI-64 + * @brief Get a command-line provided EUI-64 * * @param index index of ZEP device - * @param addr[out] user supplied EUI-64 + * @param[out] addr user supplied EUI-64 * * @return 0 on success, negatvie if no more EUIs are available. */ diff --git a/cpu/native/include/native_internal.h b/cpu/native/include/native_internal.h index 3e7e08f35d..1829fe65c0 100644 --- a/cpu/native/include/native_internal.h +++ b/cpu/native/include/native_internal.h @@ -1,26 +1,37 @@ /* * Copyright (C) 2013, 2014 Ludwig Knüpfer + * Copyright (C) 2025 carl-tud * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. */ -/** - * Native CPU internal declarations - */ - /** * @defgroup cpu_native_stdio STDIO for native * @ingroup sys_stdio * @brief Standard input/output backend for native + * @{ * * This will hook up RIOT's stdio to the host's stdio fds. It is the default * stdio implementation of the board `native`. * * @see @ref cpu_native + + * @} */ +/** + * @addtogroup cpu_native + * @{ + */ + +/** + * @file + * @brief Native CPU internal symbols + * @author Ludwig Knüpfer + * @author carl-tud + */ #ifndef NATIVE_INTERNAL_H #define NATIVE_INTERNAL_H @@ -49,11 +60,6 @@ extern "C" { #include "syscalls.h" -/** - * @addtogroup cpu_native - * @{ - */ - /* MARK: - Internal native CPU API */ /** * @name Internal native CPU API @@ -202,7 +208,9 @@ void _native_init_syscalls(void); * @{ */ -// TODO: do we still need to expose this? +/** + * @brief Points to instruction in userspace where RIOT left off and switched to ISR context + */ extern volatile uintptr_t _native_user_fptr; /** @@ -298,11 +306,9 @@ ssize_t _native_write(int fd, const void *buf, size_t count); ssize_t _native_writev(int fildes, const struct iovec *iov, int iovcnt); /** @} */ - -/** @} */ - #ifdef __cplusplus } #endif #endif /* NATIVE_INTERNAL_H */ +/** @} */ diff --git a/cpu/native/include/netdev_tap.h b/cpu/native/include/netdev_tap.h index 197cb89d9e..ef24280887 100644 --- a/cpu/native/include/netdev_tap.h +++ b/cpu/native/include/netdev_tap.h @@ -7,15 +7,15 @@ */ /** - * @ingroup drivers_netdev - * @brief Low-level ethernet driver for native tap interfaces + * @addtogroup drivers_netdev * @{ - * + */ + +/** * @file - * @brief Definitions for @ref netdev ethernet driver for host system's - * TAP interfaces - * - * @author Kaspar Schleiser + * @brief Definitions for @ref netdev ethernet driver for host system's + * TAP interfaces + * @author Kaspar Schleiser */ #ifndef NETDEV_TAP_H #define NETDEV_TAP_H @@ -32,6 +32,11 @@ extern "C" { #include "net/if.h" +/* MARK: - Low-level ethernet driver for native tap interfaces */ +/** + * @name Low-level ethernet driver for native tap interfaces + * @{ + */ /** * @brief tap interface state */ @@ -63,9 +68,11 @@ typedef struct { * If initialized manually, pass a unique identifier instead. */ void netdev_tap_setup(netdev_tap_t *dev, const netdev_tap_params_t *params, int index); +/** @} */ #ifdef __cplusplus } #endif -/** @} */ + #endif /* NETDEV_TAP_H */ +/** @} */ diff --git a/cpu/native/include/netdev_tap_params.h b/cpu/native/include/netdev_tap_params.h index a588ab921b..2cec1d3864 100644 --- a/cpu/native/include/netdev_tap_params.h +++ b/cpu/native/include/netdev_tap_params.h @@ -7,14 +7,14 @@ */ /** - * @ingroup drivers_netdev - * @brief + * @addtogroup drivers_netdev * @{ - * + */ + +/** * @file - * @brief Default configuration for the netdev_tap driver - * - * @author Martine Lenders + * @brief Default configuration for the netdev_tap driver + * @author Martine Lenders */ #ifndef NETDEV_TAP_PARAMS_H #define NETDEV_TAP_PARAMS_H diff --git a/cpu/native/include/periph_conf.h b/cpu/native/include/periph_conf.h index 0df89b2c53..4dbb0f133d 100644 --- a/cpu/native/include/periph_conf.h +++ b/cpu/native/include/periph_conf.h @@ -1,18 +1,21 @@ -/** - * Native CPU peripheral configuration - * +/* * Copyright (C) 2014 Ludwig Knüpfer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * @ingroup cpu_native - * @{ - * @file - * @author Ludwig Knüpfer */ +/** + * @addtogroup cpu_native + * @{ + */ + +/** + * @file + * @brief Native CPU peripheral configuration + * @author Ludwig Knüpfer + */ #ifndef PERIPH_CONF_H #define PERIPH_CONF_H @@ -23,7 +26,7 @@ extern "C" { #endif /** - * @brief System core clock in Hz + * @brief System core clock in Hz * * 1GHz is an arbitrary value used for compatibility with other platforms. */ @@ -32,46 +35,43 @@ extern "C" { #endif /** - * @name hardware timer clock skew avoidance - * @{ + * @brief Hardware timer clock skew avoidance */ #define NATIVE_TIMER_MIN_RES 200 -/** @} */ /** - * @name Random Number Generator configuration - * @{ + * @brief Random Number Generator configuration */ #define RANDOM_NUMOF (1U) -/** @} */ +/* MARK: - Timer peripheral configuration */ /** * @name Timer peripheral configuration * @{ */ #define TIMER_NUMOF (1U) #define TIMER_CHANNEL_NUMOF (1U) /**< Number of timer channels */ +/** @} */ +/* MARK: - xtimer configuration */ /** - * @brief xtimer configuration - */ -/* timer_set_absolute() has a high margin for possible underflow if set with + * @name `xtimer` configuration + * @{ + * + * @ref timer_set_absolute has a high margin for possible underflow if set with * value not far in the future. To prevent this, we set high backoff values * here. */ #define XTIMER_BACKOFF 200 #define XTIMER_ISR_BACKOFF 200 - /** @} */ /** * @brief UART configuration - * @{ */ #ifndef UART_NUMOF #define UART_NUMOF (1U) #endif -/** @} */ /** * @brief PWM configuration @@ -87,6 +87,7 @@ extern "C" { #define QDEC_NUMOF (8U) #endif +/* MARK: - SPI configuration (Linux host only) */ /** * @name SPI configuration (Linux host only) * @{ diff --git a/cpu/native/include/periph_cpu.h b/cpu/native/include/periph_cpu.h index 94d70693eb..f77e627233 100644 --- a/cpu/native/include/periph_cpu.h +++ b/cpu/native/include/periph_cpu.h @@ -7,15 +7,15 @@ */ /** - * @ingroup cpu_native + * @addtogroup cpu_native * @{ - * - * @file - * @brief CPU specific definitions for internal peripheral handling - * - * @author Hauke Petersen */ +/** + * @file + * @brief CPU specific definitions for internal peripheral handling + * @author Hauke Petersen + */ #ifndef PERIPH_CPU_H #define PERIPH_CPU_H @@ -28,15 +28,15 @@ extern "C" { /** * @brief Length of the CPU_ID in octets */ -#ifndef CPUID_LEN -#define CPUID_LEN (4U) +#if !defined(CPUID_LEN) || defined(DOXYGEN) +# define CPUID_LEN (4U) #endif /** - * @name Power mode configuration + * @brief Power mode configuration */ -#ifndef PM_NUM_MODES -#define PM_NUM_MODES (1U) +#if !defined(PM_NUM_MODES) || defined(DOXYGEN) +# define PM_NUM_MODES (1U) #endif /** @@ -46,30 +46,39 @@ extern "C" { /* GPIO configuration only if the module is available (=Linux) */ #if defined(MODULE_PERIPH_GPIO_LINUX) || defined(DOXYGEN) -#include +# include +/* MARK: - GPIO Configuration */ /** * @name GPIO Configuration * @{ */ - /** * @brief The offset between Port and Pin */ -#define GPIO_PORT_SHIFT (24) +# define GPIO_PORT_SHIFT (24) /** * @brief Define a custom GPIO_PIN macro for native */ -#define GPIO_PIN(port, pin) (gpio_t)((port << GPIO_PORT_SHIFT) | pin) +# define GPIO_PIN(port, pin) (gpio_t)((port << GPIO_PORT_SHIFT) | pin) -#define HAVE_GPIO_MODE_T -#ifndef GPIOHANDLE_REQUEST_PULL_DOWN -#define GPIOHANDLE_REQUEST_PULL_DOWN (0xFF) -#endif -#ifndef GPIOHANDLE_REQUEST_PULL_UP -#define GPIOHANDLE_REQUEST_PULL_UP (0xFF) -#endif +/** + * @brief Macro indicating whether GPIO modes are available on the native CPU + */ +# define HAVE_GPIO_MODE_T +/** + * @brief Pull-down + */ +# if !defined(GPIOHANDLE_REQUEST_PULL_DOWN) || defined(DOXYGEN) +# define GPIOHANDLE_REQUEST_PULL_DOWN (0xFF) +# endif +/** + * @brief Pull-up + */ +# if !defined(GPIOHANDLE_REQUEST_PULL_UP) || defined(DOXYGEN) +# define GPIOHANDLE_REQUEST_PULL_UP (0xFF) +# endif /** * @brief Available pin modes @@ -88,21 +97,27 @@ typedef enum { GPIO_OD_PU = GPIOHANDLE_REQUEST_OPEN_DRAIN | GPIOHANDLE_REQUEST_PULL_UP } gpio_mode_t; -#define HAVE_GPIO_FLANK_T +/** + * @brief A macro indicating whether the native CPU supports GPIO edge behavior + */ +# define HAVE_GPIO_FLANK_T + +/** + * @brief An enum for the type of flank that emit interrupts + */ typedef enum { GPIO_FALLING = GPIOEVENT_EVENT_FALLING_EDGE, /**< emit interrupt on falling flank */ GPIO_RISING = GPIOEVENT_EVENT_RISING_EDGE, /**< emit interrupt on rising flank */ GPIO_BOTH = GPIO_FALLING | GPIO_RISING /**< emit interrupt on both flanks */ } gpio_flank_t; - /** @} */ + #elif defined(MODULE_PERIPH_GPIO_MOCK) /** * @brief Mocked GPIO * * Mocked GPIO representation for simulation. - * @{ */ typedef struct { int value; /**< current value */ @@ -111,24 +126,23 @@ typedef struct { void (*cb)(void *arg); /**< ISR */ void *arg; /**< ISR arg */ } gpio_mock_t; -/** @} */ -#define GPIO_UNDEF 0 +# define GPIO_UNDEF 0 -#ifndef GPIO_PORT_MAX -#define GPIO_PORT_MAX (16) -#endif +# if !defined(GPIO_PORT_MAX) || defined(DOXYGEN) +# define GPIO_PORT_MAX (16) +# endif -#ifndef GPIO_PIN_MAX -#define GPIO_PIN_MAX (32) -#endif +# if !defined(GPIO_PIN_MAX) || defined(DOXYGEN) +# define GPIO_PIN_MAX (32) +# endif /** * @brief Mocked GPIO array */ extern gpio_mock_t gpio_mock[GPIO_PORT_MAX][GPIO_PIN_MAX]; -#define HAVE_GPIO_T +# define HAVE_GPIO_T /** * @brief Pointer on a mocked GPIO */ @@ -138,7 +152,7 @@ typedef gpio_mock_t* gpio_t; * @brief Define a custom GPIO_PIN macro for native mocked GPIO framework. * Get the mocked GPIO object from mocked GPIO array. */ -#define GPIO_PIN(port, pin) \ +# define GPIO_PIN(port, pin) \ (((port >= 0) && (pin >= 0) && (port < GPIO_PORT_MAX) && (pin < GPIO_PIN_MAX)) \ ? &gpio_mock[port][pin] \ : GPIO_UNDEF) @@ -150,8 +164,9 @@ typedef gpio_mock_t* gpio_t; */ #define PERIPH_TIMER_PROVIDES_SET +/* MARK: - Power management configuration*/ /** - * @name Power management configuration + * @name Power management configuration * @{ */ #define PROVIDES_PM_OFF @@ -164,35 +179,34 @@ typedef gpio_mock_t* gpio_t; * spi.h. */ #if defined(MODULE_PERIPH_SPIDEV_LINUX) || defined(DOXYGEN) - +/* MARK: - SPI Configuration */ /** * @name SPI Configuration + * @{ */ - /** * @brief Use the common `transfer_byte` SPI function */ -#define PERIPH_SPI_NEEDS_TRANSFER_BYTE +# define PERIPH_SPI_NEEDS_TRANSFER_BYTE /** * @brief Use the common `transfer_reg` SPI function */ -#define PERIPH_SPI_NEEDS_TRANSFER_REG +# define PERIPH_SPI_NEEDS_TRANSFER_REG /** * @brief Use the common `transfer_regs` SPI function */ -#define PERIPH_SPI_NEEDS_TRANSFER_REGS +# define PERIPH_SPI_NEEDS_TRANSFER_REGS -#ifndef DOXYGEN +# ifndef DOXYGEN /** * @brief Use a custom clock speed type */ -#define HAVE_SPI_CLK_T +# define HAVE_SPI_CLK_T /** * @brief SPI clock speed values * * The Linux userspace driver takes values in Hertz, which values are available * can only be determined at runtime. - * @{ */ typedef enum { SPI_CLK_100KHZ = (100000U), @@ -201,21 +215,19 @@ typedef enum { SPI_CLK_5MHZ = (5000000U), SPI_CLK_10MHZ = (10000000U) } spi_clk_t; +# endif /* ndef DOXYGEN */ /** @} */ -#endif /* ndef DOXYGEN */ #endif /* MODULE_PERIPH_SPI | DOXYGEN */ /** - * @name EEPROM configuration - * @{ + * @brief EEPROM configuration */ -#ifndef EEPROM_SIZE -#define EEPROM_SIZE (1024U) /* 1kB */ +#if !defined(EEPROM_SIZE) || defined(DOXYGEN) +# define EEPROM_SIZE (1024U) /* 1kB */ #endif -/** @} */ #ifdef MODULE_PERIPH_CAN -#include "candev_linux.h" +# include "candev_linux.h" #endif #ifdef __cplusplus diff --git a/cpu/native/include/socket_zep.h b/cpu/native/include/socket_zep.h index ac2a7edd2a..eda624b7ca 100644 --- a/cpu/native/include/socket_zep.h +++ b/cpu/native/include/socket_zep.h @@ -7,9 +7,10 @@ */ /** - * @defgroup drivers_socket_zep Socket-based ZEP - * @ingroup drivers_netdev - * @brief UDP socket-based IEEE 802.15.4 device over ZEP + * @defgroup drivers_socket_zep Socket-based ZEP + * @ingroup drivers_netdev + * @brief UDP socket-based IEEE 802.15.4 device over ZEP + * @{ * * @see @ref net_zep for protocol definitions * @@ -46,12 +47,12 @@ * | 0 | 0 | 0 | 0 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * - * @{ - * + */ + +/** * @file - * @brief Socket ZEP definitions - * - * @author Martine Lenders + * @brief Socket ZEP definitions + * @author Martine Lenders */ #ifndef SOCKET_ZEP_H #define SOCKET_ZEP_H diff --git a/cpu/native/include/socket_zep_params.h b/cpu/native/include/socket_zep_params.h index 7e9a1fe2bd..7330e8886b 100644 --- a/cpu/native/include/socket_zep_params.h +++ b/cpu/native/include/socket_zep_params.h @@ -7,13 +7,14 @@ */ /** - * @ingroup drivers_socket_zep + * @addtogroup drivers_socket_zep * @{ - * + */ + +/** * @file - * @brief Configuration parameters for the @ref drivers_socket_zep driver - * - * @author Martine Lenders + * @brief Configuration parameters for the @ref drivers_socket_zep driver + * @author Martine Lenders */ #ifndef SOCKET_ZEP_PARAMS_H #define SOCKET_ZEP_PARAMS_H diff --git a/cpu/native/include/spidev_linux.h b/cpu/native/include/spidev_linux.h index 2914a311d6..0849302103 100644 --- a/cpu/native/include/spidev_linux.h +++ b/cpu/native/include/spidev_linux.h @@ -7,9 +7,10 @@ */ /** - * @defgroup drivers_spidev_linux Linux User Mode SPI Driver - * @ingroup cpu_native - * @brief Implementation of SPI access from Linux User Space + * @defgroup drivers_spidev_linux Linux User Mode SPI Driver + * @ingroup cpu_native + * @brief Implementation of SPI access from Linux User Space + * @{ * * This module allows to connect a RIOT application that runs on a Linux host to * the physical SPI bus(ses) of that host. To do so, the application has to be @@ -50,15 +51,13 @@ * select the file descriptor with the lowest HWCS id for that bus, but the * actual CS line will not be pulled low (if the hardware supports this). This * would (in principle) allow to control CS manually. - * - * @{ - * - * @file - * @brief Implementation of SPI access from Linux User Space - * - * @author Frank Hessel */ +/** + * @file + * @brief Implementation of SPI access from Linux User Space + * @author Frank Hessel + */ #ifndef SPIDEV_LINUX_H #define SPIDEV_LINUX_H diff --git a/cpu/native/include/thread_arch.h b/cpu/native/include/thread_arch.h index d1ae2867b3..83ab0385e6 100644 --- a/cpu/native/include/thread_arch.h +++ b/cpu/native/include/thread_arch.h @@ -8,15 +8,15 @@ */ /** - * @ingroup cpu_native + * @addtogroup cpu_native * @{ - * - * @file - * @brief Implementation of the kernels thread interface - * - * @author Koen Zandberg */ +/** + * @file + * @brief Implementation of the kernels thread interface + * @author Koen Zandberg + */ #ifndef THREAD_ARCH_H #define THREAD_ARCH_H diff --git a/cpu/native/include/tty_uart.h b/cpu/native/include/tty_uart.h index aaac459a72..62871721cf 100644 --- a/cpu/native/include/tty_uart.h +++ b/cpu/native/include/tty_uart.h @@ -7,15 +7,15 @@ */ /** - * @ingroup cpu_native + * @addtogroup cpu_native * @{ - * - * @file - * @brief UART implementation based on /dev/tty devices on host - * - * @author Takuo Yonezawa */ +/** + * @file + * @brief UART implementation based on /dev/tty devices on host + * @author Takuo Yonezawa + */ #ifndef TTY_UART_H #define TTY_UART_H diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index cf7007f16a..27e05a24ba 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -1,6 +1,4 @@ /* - * Native CPU irq.h implementation - * * Copyright (C) 2013 Ludwig Knüpfer * * This file is subject to the terms and conditions of the GNU Lesser @@ -8,6 +6,13 @@ * directory for more details. */ +/** + * @file + * @brief Native CPU irq.h implementation + * @ingroup cpu_native + * @author Ludwig Knüpfer + */ + #include #include #include @@ -518,4 +523,3 @@ void native_interrupt_init(void) puts("RIOT native interrupts/signals initialized."); } -/** @} */ diff --git a/cpu/native/mtd/mtd_native.c b/cpu/native/mtd/mtd_native.c index 672cdad3a5..11db5d0a4a 100644 --- a/cpu/native/mtd/mtd_native.c +++ b/cpu/native/mtd/mtd_native.c @@ -7,12 +7,10 @@ */ /** - * @{ - * @brief mtd flash emulation for native - * * @file - * - * @author Vincent Dupont + * @ingroup drivers_mtd_native + * @brief MTD flash emulation for native + * @author Vincent Dupont */ #include @@ -156,5 +154,3 @@ const mtd_desc_t native_flash_driver = { .erase = _erase, .init = _init, }; - -/** @} */ diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index dc043e6faa..ab070b595b 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -1,22 +1,17 @@ /* - * Native CPU kernel_intern.h and sched.h implementation - * * Copyright (C) 2016 Kaspar Schleiser * 2013 Ludwig Knüpfer * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * Author: Ludwig Knüpfer - * Author: Kaspar Schleiser */ /** * @file - * @brief Native CPU kernel_intern.h and sched.h implementation - * @author Ludwig Knüpfer - * @author Kaspar Schleiser + * @brief Native CPU kernel_intern.h and sched.h implementation + * @author Ludwig Knüpfer + * @author Kaspar Schleiser * * In-process preemptive context switching utilizes POSIX ucontexts. * (ucontext provides for architecture independent stack handling) @@ -274,4 +269,3 @@ void native_cpu_init(void) DEBUG("RIOT native cpu initialized.\n"); } -/** @} */ diff --git a/cpu/native/netdev_tap/netdev_tap.c b/cpu/native/netdev_tap/netdev_tap.c index 99cf572f07..1a0c8bd472 100644 --- a/cpu/native/netdev_tap/netdev_tap.c +++ b/cpu/native/netdev_tap/netdev_tap.c @@ -9,12 +9,11 @@ * more details. */ -/* +/** + * @file * @ingroup drivers_netdev - * @{ * @brief Low-level ethernet driver for tap interfaces * @author Kaspar Schleiser - * @} */ #include diff --git a/cpu/native/panic.c b/cpu/native/panic.c index 67a79ce1bd..6d1be76732 100644 --- a/cpu/native/panic.c +++ b/cpu/native/panic.c @@ -8,10 +8,11 @@ /** * @file - * @brief Crash handling functions implementation for 'native' port - * @author Ludwig Knüpfer - * @author Kévin Roussel - * @author Oliver Hahm + * @ingroup cpu_native + * @brief Crash handling functions implementation for 'native' port + * @author Ludwig Knüpfer + * @author Kévin Roussel + * @author Oliver Hahm */ #include diff --git a/cpu/native/periph/can.c b/cpu/native/periph/can.c index aa1565dc3c..a5fd61b2c9 100644 --- a/cpu/native/periph/can.c +++ b/cpu/native/periph/can.c @@ -7,16 +7,12 @@ */ /** - * @ingroup drivers_candev_linux - * @{ - * * @file - * @brief Implementation of simulated CAN controller driver using SocketCAN on Linux - * - * @author Hermann Lelong - * @author Aurelien Gonce - * @author Vincent Dupont - * @} + * @ingroup drivers_candev_linux + * @brief Implementation of simulated CAN controller driver using SocketCAN on Linux + * @author Hermann Lelong + * @author Aurelien Gonce + * @author Vincent Dupont */ #if !defined(__linux__) diff --git a/cpu/native/periph/cpuid.c b/cpu/native/periph/cpuid.c index 8f315f544d..1eebe4494c 100644 --- a/cpu/native/periph/cpuid.c +++ b/cpu/native/periph/cpuid.c @@ -7,16 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_cpuid - * @{ - * * @file - * @brief Implementation - * - * @author Martine Lenders - * - * @} + * @ingroup cpu_native + * @ingroup drivers_periph_cpuid + * @brief CPUID implementation + * @author Martine Lenders */ #include diff --git a/cpu/native/periph/eeprom.c b/cpu/native/periph/eeprom.c index 797db72f86..ea9f7cb6df 100644 --- a/cpu/native/periph/eeprom.c +++ b/cpu/native/periph/eeprom.c @@ -7,15 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_eeprom - * @{ - * * @file - * @brief Low-level EEPROM driver implementation for native - * - * @author Alexandre Abadie - * @} + * @ingroup cpu_native + * @ingroup drivers_periph_eeprom + * @brief Low-level EEPROM driver implementation for native + * @author Alexandre Abadie */ #include diff --git a/cpu/native/periph/flashpage.c b/cpu/native/periph/flashpage.c index 8da0c26a8e..3fb8200091 100644 --- a/cpu/native/periph/flashpage.c +++ b/cpu/native/periph/flashpage.c @@ -7,15 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_flashpage - * @{ - * * @file - * @brief Low-level flashpage driver emulation - * - * @author Benjamin Valentin - * @} + * @ingroup cpu_native + * @ingroup drivers_periph_flashpage + * @brief Low-level flashpage driver emulation + * @author Benjamin Valentin */ #include diff --git a/cpu/native/periph/gpio_linux.c b/cpu/native/periph/gpio_linux.c index f04e749b86..024a8ac4c9 100644 --- a/cpu/native/periph/gpio_linux.c +++ b/cpu/native/periph/gpio_linux.c @@ -7,14 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_gpio - * @{ - * * @file - * @brief native GPIO implementation - * - * @author Benjamin Valentin + * @ingroup cpu_native + * @ingroup drivers_periph_gpio + * @brief native GPIO implementation + * @author Benjamin Valentin */ #include @@ -312,5 +309,3 @@ void gpio_irq_disable(gpio_t pin) } #endif /* MODULE_PERIPH_GPIO_IRQ */ - -/** @} */ diff --git a/cpu/native/periph/gpio_mock.c b/cpu/native/periph/gpio_mock.c index 3094be3144..ecaf7555dd 100644 --- a/cpu/native/periph/gpio_mock.c +++ b/cpu/native/periph/gpio_mock.c @@ -7,14 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_gpio - * @{ - * * @file - * @brief empty GPIO implementation - * - * @author Takuo Yonezawa + * @ingroup cpu_native + * @ingroup drivers_periph_gpio + * @brief empty GPIO implementation + * @author Takuo Yonezawa */ #include "periph/gpio.h" @@ -97,5 +94,3 @@ __attribute__((weak)) void gpio_write(gpio_t pin, bool value) { pin->value = value; } } - -/** @} */ diff --git a/cpu/native/periph/hwrng.c b/cpu/native/periph/hwrng.c index f9971cebbf..f4301b3c2e 100644 --- a/cpu/native/periph/hwrng.c +++ b/cpu/native/periph/hwrng.c @@ -8,14 +8,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_hwrng - * @{ - * * @file - * @brief HWRNG interface implementation - * - * @author Ludwig Knüpfer + * @ingroup cpu_native + * @ingroup drivers_periph_hwrng + * @brief HWRNG interface implementation + * @author Ludwig Knüpfer */ #include @@ -35,9 +32,7 @@ static int initialized = 0; static int dev_random = -1; -/********************************************************************** - * internal API declaration - **********************************************************************/ +/* MARK: - Internal API declaration */ /** * seed host random module with @ref _native_rng_seed @@ -47,9 +42,7 @@ void _native_rng_init_hq(void); unsigned _native_rng_read_det(uint8_t *buf, unsigned num); unsigned _native_rng_read_hq(uint8_t *buf, unsigned num); -/********************************************************************** - * public API implementation - **********************************************************************/ +/* MARK: - Public API implementation */ void hwrng_init(void) { @@ -94,9 +87,7 @@ void hwrng_read(void *buf, unsigned int num) } } -/********************************************************************** - * internal API implementation - **********************************************************************/ +/* MARK: - Internal API implementation */ void _native_rng_init_det(void) { @@ -152,7 +143,3 @@ unsigned _native_rng_read_hq(uint8_t *buf, unsigned num) return offset; } - -/** - * @} - */ diff --git a/cpu/native/periph/pm.c b/cpu/native/periph/pm.c index 19de1c92c7..7fda4515b0 100644 --- a/cpu/native/periph/pm.c +++ b/cpu/native/periph/pm.c @@ -7,14 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_pm - * @{ - * * @file - * @brief native Power Management implementation - * - * @author Kaspar Schleiser + * @ingroup cpu_native + * @ingroup drivers_periph_pm + * @brief Native Power Management implementation + * @author Kaspar Schleiser */ #include diff --git a/cpu/native/periph/pwm.c b/cpu/native/periph/pwm.c index f4b0af0c12..cb92aecf9d 100644 --- a/cpu/native/periph/pwm.c +++ b/cpu/native/periph/pwm.c @@ -7,15 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_pwm - * @{ - * * @file - * @brief Low-level PWM driver implementation - * - * @author Gilles DOFFE - * @} + * @ingroup cpu_native + * @ingroup drivers_periph_pwm + * @brief Low-level PWM driver implementation + * @author Gilles DOFFE */ #include diff --git a/cpu/native/periph/qdec.c b/cpu/native/periph/qdec.c index c3a3b8aa91..47c6d29c10 100644 --- a/cpu/native/periph/qdec.c +++ b/cpu/native/periph/qdec.c @@ -7,16 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_qdec - * @{ - * * @file - * @brief Low-level QDEC driver implementation - * - * @author Gilles DOFFE - * - * @} + * @ingroup cpu_native + * @ingroup drivers_periph_qdec + * @brief Low-level QDEC driver implementation + * @author Gilles DOFFE */ #include diff --git a/cpu/native/periph/rtc.c b/cpu/native/periph/rtc.c index 088e465332..6e1200e5fa 100644 --- a/cpu/native/periph/rtc.c +++ b/cpu/native/periph/rtc.c @@ -7,18 +7,16 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_rtc - * @{ - * * @file - * @brief Native CPU periph/rtc.h implementation + * @ingroup cpu_native + * @ingroup drivers_periph_rtc + * @brief Native CPU periph/rtc.h implementation + * @author Ludwig Knüpfer + * @{ * * The implementation uses POSIX system calls to emulate a real-time * clock based on the system clock. * - * @author Ludwig Knüpfer - * * @} */ diff --git a/cpu/native/periph/spidev_linux.c b/cpu/native/periph/spidev_linux.c index f5f0d29082..e204e46c21 100644 --- a/cpu/native/periph/spidev_linux.c +++ b/cpu/native/periph/spidev_linux.c @@ -7,15 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_spidev_linux - * @{ - * * @file - * @brief Implementation of SPI access from Linux User Space - * - * @author Frank Hessel - * @} + * @ingroup cpu_native + * @ingroup drivers_spidev_linux + * @brief Implementation of SPI access from Linux User Space + * @author Frank Hessel */ #ifdef MODULE_PERIPH_SPIDEV_LINUX diff --git a/cpu/native/periph/timer.c b/cpu/native/periph/timer.c index 479aeb4e64..507aa63830 100644 --- a/cpu/native/periph/timer.c +++ b/cpu/native/periph/timer.c @@ -1,4 +1,4 @@ -/** +/* * Copyright (C) 2013 Ludwig Knüpfer * 2015 Kaspar Schleiser * @@ -8,12 +8,13 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_timer - * @{ - * * @file - * @brief Native CPU periph/timer.h implementation + * @ingroup cpu_native + * @ingroup drivers_periph_timer + * @brief Native CPU periph/timer.h implementation + * @author Ludwig Knüpfer + * @author Kaspar Schleiser + * @{ * * Uses POSIX realtime clock and POSIX itimer to mimic hardware. * This is done with the timer_settime(3), timer_create(3) interfaces, which are @@ -22,9 +23,6 @@ * This is based on native's hwtimer implementation by Ludwig Knüpfer. * I removed the multiplexing, as ztimer does the same. (kaspar) * - * @author Ludwig Knüpfer - * @author Kaspar Schleiser - * * @} */ diff --git a/cpu/native/periph/uart.c b/cpu/native/periph/uart.c index c3bd7ea0bc..a1b2994409 100644 --- a/cpu/native/periph/uart.c +++ b/cpu/native/periph/uart.c @@ -7,16 +7,11 @@ */ /** - * @ingroup cpu_native - * @ingroup drivers_periph_uart - * @{ - * * @file - * @brief UART implementation based on /dev/tty devices on host - * - * @author Takuo Yonezawa - * - * @} + * @ingroup cpu_native + * @ingroup drivers_periph_uart + * @brief UART implementation based on /dev/tty devices on host + * @author Takuo Yonezawa */ #include diff --git a/cpu/native/socket_zep/socket_zep.c b/cpu/native/socket_zep/socket_zep.c index aaa432e5d4..75ebf84c64 100644 --- a/cpu/native/socket_zep/socket_zep.c +++ b/cpu/native/socket_zep/socket_zep.c @@ -7,11 +7,9 @@ */ /** - * @{ - * * @file - * @author Martine Lenders - * @author Benjamin Valentin + * @author Martine Lenders + * @author Benjamin Valentin */ #include @@ -640,5 +638,3 @@ void socket_zep_hal_setup(socket_zep_t *dev, ieee802154_dev_t *hal) hal->driver = &socket_zep_rf_ops; hal->priv = dev; } - -/** @} */ diff --git a/cpu/native/startup.c b/cpu/native/startup.c index b0959267e4..e24568f045 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -1,14 +1,17 @@ -/* Native CPU entry code - * +/* * Copyright (C) 2013 Ludwig Knüpfer * 2017 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level * directory for more details. - * - * Author: Ludwig Knüpfer - * Author: Martine Lenders + */ + +/** + * @file Ludwig Knüpfer + * @brief Native CPU entry code + * @ingroup cpu_native + * @author Martine Lenders */ #include diff --git a/cpu/native/stdio_native/stdio_native.c b/cpu/native/stdio_native/stdio_native.c index e79bec4eba..8902b02feb 100644 --- a/cpu/native/stdio_native/stdio_native.c +++ b/cpu/native/stdio_native/stdio_native.c @@ -7,10 +7,8 @@ */ /** - * @{ - * * @file - * @author Martine S. Lenders + * @author Martine S. Lenders */ #include "kernel_defines.h" @@ -31,5 +29,3 @@ ssize_t stdio_write(const void* buffer, size_t len) { return real_write(STDOUT_FILENO, buffer, len); } - -/** @} */ diff --git a/cpu/native/syscalls.c b/cpu/native/syscalls.c index 1ee05c3703..34f9ff2d2a 100644 --- a/cpu/native/syscalls.c +++ b/cpu/native/syscalls.c @@ -1,8 +1,4 @@ -/* Native CPU syscall managing - * - * Wrap system calls and system call invoking library calls to make - * sure no context switches happen during a system call. - * +/* * Copyright (C) 2013 Ludwig Knüpfer * * This file is subject to the terms and conditions of the GNU Lesser @@ -10,6 +6,18 @@ * directory for more details. */ +/** + * @file + * @ingroup cpu_native + * @brief Native CPU syscall managing + * @{ + * + * Wrap system calls and system call invoking library calls to make + * sure no context switches happen during a system call. + * + * @} + */ + #include #include #include diff --git a/cpu/native/vfs/native_vfs.c b/cpu/native/vfs/native_vfs.c index 2d701c8a9e..8d4adf6a72 100644 --- a/cpu/native/vfs/native_vfs.c +++ b/cpu/native/vfs/native_vfs.c @@ -7,13 +7,10 @@ */ /** - * @ingroup cpu_native - * @{ - * * @file - * @brief VFS wrappers for POSIX file I/O functions - * - * @author Kaspar Schleiser + * @ingroup cpu_native + * @brief VFS wrappers for POSIX file I/O functions + * @author Kaspar Schleiser */ #include @@ -145,5 +142,3 @@ int unlink(const char *path) } return 0; } - -/** @} */ From b5eff6a10736d7bb31ae72f5fd8878c837138adb Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:36:28 +0100 Subject: [PATCH 05/13] cpu/native: unify ucontext manipulation --- cpu/native/include/native_internal.h | 22 +++++++ cpu/native/include/util/ucontext.h | 91 ++++++++++++++++++++++++++++ cpu/native/irq_cpu.c | 43 ++++--------- cpu/native/native_cpu.c | 24 -------- cpu/native/syscalls.c | 14 ++--- 5 files changed, 131 insertions(+), 63 deletions(-) create mode 100644 cpu/native/include/util/ucontext.h diff --git a/cpu/native/include/native_internal.h b/cpu/native/include/native_internal.h index 1829fe65c0..16e64e276a 100644 --- a/cpu/native/include/native_internal.h +++ b/cpu/native/include/native_internal.h @@ -237,7 +237,29 @@ extern ucontext_t *_native_isr_context; */ extern void _native_isr_leave(void); +/** + * @brief Makes ISR context so that execution continues at `func` when the context is applied + * + * @param func Function executed when `_native_isr_context` is applied + */ +static inline void _native_isr_context_make(void (*func)(void)) { + _native_isr_context->uc_stack.ss_sp = _isr_stack; + _native_isr_context->uc_stack.ss_size = sizeof(_isr_stack); + _native_isr_context->uc_stack.ss_flags = 0; + /* Create the ISR context, will execute _isr_schedule_and_switch */ + makecontext(_native_isr_context, func, 0); +} + +/** + * @brief Retrieves user context + * @returns `ucontext_t` + */ +static inline ucontext_t* _native_user_context(void) { + /* Use intermediate cast to uintptr_t to silence -Wcast-align. + * stacks are manually word aligned in thread_static_init() */ + return (ucontext_t *)(uintptr_t)thread_get_active()->sp; +} /** @} */ /* MARK: - Native Process State */ diff --git a/cpu/native/include/util/ucontext.h b/cpu/native/include/util/ucontext.h new file mode 100644 index 0000000000..5880dce198 --- /dev/null +++ b/cpu/native/include/util/ucontext.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2013 - 2016 Ludwig Knüpfer + * Copyright (C) 2025 carl-tud + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef UTIL_UCONTEXT_H +#define UTIL_UCONTEXT_H + +#if USE_LIBUCONTEXT +# include +#else +# include +#endif /* USE_LIBUCONTEXT */ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup cpu_native + * @{ + */ + +/* MARK: - Context accessors */ +/** + * @name Context accessors + * @{ + */ + +/** + * @brief Retrieves function pointer generated during calls to `makecontext`/`setcontext`/`swapcontext` + * @param context `ucontext_t` + * @returns Function pointer (does not need to be start of a function, points to instruction) + */ +static inline uintptr_t _context_get_fptr(ucontext_t *context) { +# if defined(__FreeBSD__) /* FreeBSD */ + return (uintptr_t)((struct sigcontext *)context)->sc_eip; +# elif defined(__linux__) /* Linux */ +# if defined(__arm__) + return (uintptr_t)((ucontext_t *)context)->uc_mcontext.arm_pc; +# elif defined(__x86_64__) + return (uintptr_t)((ucontext_t *)context)->uc_mcontext.gregs[REG_RIP]; +# elif defined(__i386__) + return (uintptr_t)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]; +# else +# error "Unsupported Linux architecture" +# endif +# else +# error "Operating system unsupported" +# endif +} + +/** + * @brief Retrieves function pointer generated during calls to `makecontext`/`setcontext`/`swapcontext` + * @param context `ucontext_t` + * @param func Function pointer + */ +static inline void _context_set_fptr(ucontext_t *context, uintptr_t func) { +# if defined(__FreeBSD__) /* FreeBSD */ + ((struct sigcontext *)context)->sc_eip = (unsigned int)func; +# elif defined(__linux__) /* Linux */ +# if defined(__arm__) + ((ucontext_t *)context)->uc_mcontext.arm_lr = func; + ((ucontext_t *)context)->uc_mcontext.arm_pc = func; +# elif defined(__x86_64__) + ((ucontext_t *)context)->uc_mcontext.gregs[REG_RIP] = (greg_t)func; +# elif defined(__i386__) + ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP] = func; +# else +# error "Unsupported Linux architecture" +# endif +# else +# error "Operating system unsupported" +# endif +} +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* UTIL_UCONTEXT_H */ diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index 27e05a24ba..b42d7d593f 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -323,36 +323,22 @@ void native_signal_action(int sig, siginfo_t *info, void *context) return; } - native_isr_context.uc_stack.ss_sp = __isr_stack; - native_isr_context.uc_stack.ss_size = sizeof(__isr_stack); - native_isr_context.uc_stack.ss_flags = 0; - makecontext(&native_isr_context, native_irq_handler, 0); - /* Use intermediate cast to uintptr_t to silence -Wcast-align. - * stacks are manually word aligned in thread_stack_init() */ - _native_cur_ctx = (ucontext_t *)(uintptr_t)thread_get_active()->sp; + /* We will switch to the ISR context with ISR stack */ + _native_isr_context_make(_native_call_sig_handlers_and_switch); + + /* Current user thread context */ + _native_current_context = _native_user_context(); DEBUG_IRQ("\n\n\t\tnative_signal_action: return to _native_sig_leave_tramp\n\n"); /* disable interrupts in context */ - isr_set_sigmask((ucontext_t *)context); + _set_sigmask((ucontext_t *)context); _native_in_isr = 1; -#if defined(__FreeBSD__) - _native_saved_eip = ((struct sigcontext *)context)->sc_eip; - ((struct sigcontext *)context)->sc_eip = (unsigned int)&_native_sig_leave_tramp; -#else /* Linux */ -#if defined(__arm__) - _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.arm_pc; - ((ucontext_t *)context)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_tramp; -#else /* Linux/x86 */ - #ifdef __x86_64__ - _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_RIP]; - ((ucontext_t *)context)->uc_mcontext.gregs[REG_RIP] = (uintptr_t)&_native_sig_leave_tramp; - #else - //printf("\n\033[31mEIP:\t%p\ngo switching\n\n\033[0m", (void*)((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]); - _native_saved_eip = ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP]; - ((ucontext_t *)context)->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_tramp; - #endif -#endif -#endif + + /* Get PC/LR. This is where we will resume execution on the userspace thread. */ + _native_user_fptr = (uintptr_t)_context_get_fptr((ucontext_t *)context); + + /* Now we want to go to _native_sig_leave_tramp before resuming execution at _native_user_fptr. */ + _context_set_fptr(context, (uintptr_t)_native_sig_leave_tramp); } static void _set_signal_handler(int sig, bool add) @@ -487,10 +473,7 @@ void native_interrupt_init(void) err(EXIT_FAILURE, "native_interrupt_init: getcontext"); } - native_isr_context.uc_stack.ss_sp = __isr_stack; - native_isr_context.uc_stack.ss_size = sizeof(__isr_stack); - native_isr_context.uc_stack.ss_flags = 0; - _native_isr_ctx = &native_isr_context; + _native_isr_context_make(_native_call_sig_handlers_and_switch); static stack_t sigstk; sigstk.ss_sp = malloc(SIGSTKSZ); diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index ab070b595b..af243efd45 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -55,30 +55,6 @@ extern netdev_tap_t netdev_tap; static ucontext_t _end_context; -/** - * make the new context assign `_native_in_isr = 0` before resuming - */ -static void _native_mod_ctx_leave_sigh(ucontext_t *ctx) -{ -#if defined(__FreeBSD__) - _native_saved_eip = ((struct sigcontext *)ctx)->sc_eip; - ((struct sigcontext *)ctx)->sc_eip = (unsigned int)&_native_sig_leave_handler; -#else /* Linux */ -#if defined(__arm__) - _native_saved_eip = ((ucontext_t *)ctx)->uc_mcontext.arm_pc; - ((ucontext_t *)ctx)->uc_mcontext.arm_pc = (unsigned int)&_native_sig_leave_handler; -#else /* Linux/x86 */ - #ifdef __x86_64__ - _native_saved_eip = ctx->uc_mcontext.gregs[REG_RIP]; - ctx->uc_mcontext.gregs[REG_RIP] = (unsigned long)&_native_sig_leave_handler; - #else - _native_saved_eip = ctx->uc_mcontext.gregs[REG_EIP]; - ctx->uc_mcontext.gregs[REG_EIP] = (unsigned int)&_native_sig_leave_handler; - #endif -#endif -#endif -} - /** * TODO: implement */ diff --git a/cpu/native/syscalls.c b/cpu/native/syscalls.c index 34f9ff2d2a..222162b4a7 100644 --- a/cpu/native/syscalls.c +++ b/cpu/native/syscalls.c @@ -39,6 +39,7 @@ # include "time_units.h" # include "ztimer64.h" #endif + #include "stdio_base.h" #include "kernel_defines.h" @@ -80,15 +81,10 @@ void _native_syscall_leave(void) ) { _native_in_isr = 1; - /* Use intermediate cast to uintptr_t to silence -Wcast-align. - * stacks are manually word aligned in thread_static_init() */ - _native_cur_ctx = (ucontext_t *)(uintptr_t)thread_get_active()->sp; - native_isr_context.uc_stack.ss_sp = __isr_stack; - native_isr_context.uc_stack.ss_size = __isr_stack_size; - native_isr_context.uc_stack.ss_flags = 0; - native_interrupts_enabled = 0; - makecontext(&native_isr_context, native_irq_handler, 0); - if (swapcontext(_native_cur_ctx, &native_isr_context) == -1) { + _native_interrupts_enabled = false; + + _native_isr_context_make(_native_call_sig_handlers_and_switch); + if (swapcontext(_native_user_context(), _native_isr_context) == -1) { err(EXIT_FAILURE, "_native_syscall_leave: swapcontext"); } } From 9c96c1856686dd3a214ba51b4dae996b5043c51e Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:37:25 +0100 Subject: [PATCH 06/13] cpu/native: move valgrind imports into separate header --- cpu/native/include/util/valgrind.h | 27 +++++++++++++++++++++++++++ cpu/native/irq_cpu.c | 11 +---------- cpu/native/native_cpu.c | 14 ++------------ 3 files changed, 30 insertions(+), 22 deletions(-) create mode 100644 cpu/native/include/util/valgrind.h diff --git a/cpu/native/include/util/valgrind.h b/cpu/native/include/util/valgrind.h new file mode 100644 index 0000000000..3457527884 --- /dev/null +++ b/cpu/native/include/util/valgrind.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2025 carl-tud + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef UTIL_VALGRIND_H +#define UTIL_VALGRIND_H + +#ifdef HAVE_VALGRIND_H +# include +#define VALGRIND_DEBUG DEBUG +# elif defined(HAVE_VALGRIND_VALGRIND_H) +# include +#define VALGRIND_DEBUG DEBUG +#else +# define VALGRIND_STACK_REGISTER(...) (0) +# define VALGRIND_DEBUG(...) +#endif + +#ifdef __cplusplus +extern "C" {} +#endif + +#endif /* UTIL_VALGRIND_H */ diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq_cpu.c index b42d7d593f..ab5e250ccc 100644 --- a/cpu/native/irq_cpu.c +++ b/cpu/native/irq_cpu.c @@ -19,16 +19,7 @@ #include #include -#ifdef HAVE_VALGRIND_H -#include -#define VALGRIND_DEBUG DEBUG -#elif defined(HAVE_VALGRIND_VALGRIND_H) -#include -#define VALGRIND_DEBUG DEBUG -#else -#define VALGRIND_STACK_REGISTER(...) (0) -#define VALGRIND_DEBUG(...) -#endif +#include "util/valgrind.h" #include "irq.h" #include "cpu.h" diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index af243efd45..69bce9752a 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -20,22 +20,12 @@ #include #include #include - -#ifdef HAVE_VALGRIND_H -#include -#define VALGRIND_DEBUG DEBUG -#elif defined(HAVE_VALGRIND_VALGRIND_H) -#include -#define VALGRIND_DEBUG DEBUG -#else -#define VALGRIND_STACK_REGISTER(...) (0) -#define VALGRIND_DEBUG(...) -#endif - #include #include #include +#include "util/valgrind.h" + #include "cpu.h" #include "cpu_conf.h" #include "irq.h" From ccc97b00184a6cb96a56e4a8364b7b4855cac7a5 Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:37:57 +0100 Subject: [PATCH 07/13] cpu/native: restructure CPU --- cpu/native/native_cpu.c | 288 ++++++++++++++++++++++------------------ 1 file changed, 161 insertions(+), 127 deletions(-) diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index 69bce9752a..767738cc61 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -50,7 +50,7 @@ static ucontext_t _end_context; */ void thread_print_stack(void) { - CPU_DEBUG("thread_print_stack\n"); + DEBUG_CPU("thread_print_stack\n"); return; } @@ -66,6 +66,161 @@ void native_breakpoint(void) raise(SIGTRAP); } +/* ========================================= */ +/* ISR -> user switch function */ + +void _isr_switch_to_user(void) { + DEBUG_CPU("... ISR: switching to user thread, calling setcontext(PID %" PRIkernel_pid ")\n\n", thread_getpid()); + + ucontext_t *context = _native_user_context(); + _native_interrupts_enabled = true; + + /* Get PC/LR. This is where we will resume execution on the userspace thread. */ + _native_user_fptr = (uintptr_t)_context_get_fptr(context); + + /* Now we want to go to _native_isr_leave before resuming execution at _native_user_fptr. */ + _context_set_fptr(context, (uintptr_t)_native_isr_leave); + + if (setcontext(context) == -1) { + err(EXIT_FAILURE, "_isr_schedule_and_switch: setcontext"); + } + errx(EXIT_FAILURE, "2 this should have never been reached!!"); +} + +/* ========================================= */ + +void _isr_context_switch_exit(void) +{ + DEBUG_CPU("_isr_schedule_and_switch\n"); + /* Schedule thread job if no active thread */ + if (((sched_context_switch_request == 1) || (thread_get_active() == NULL)) + && IS_USED(MODULE_CORE_THREAD)) { + /* Schedule active thread */ + sched_run(); + } + + /* Switch to active userspace thread */ + _isr_switch_to_user(); +} + +/* ^ + * | + * | + * cpu_switch_context_exit continues + * in ISR context in _isr_context_switch_exit + */ + +void cpu_switch_context_exit(void) +{ +# ifdef NATIVE_AUTO_EXIT + if (sched_num_threads <= 1) { + extern unsigned _native_retval; + DEBUG_CPU("cpu_switch_context_exit: last task has ended. exiting.\n"); + real_exit(_native_retval); + } +# endif + + if (_native_in_isr == 0) { + /* Disable interrupts while switching */ + irq_disable(); + _native_in_isr = 1; + + _native_isr_context_make(_isr_context_switch_exit); + if (setcontext(_native_isr_context) == -1) { + err(EXIT_FAILURE, "cpu_switch_context_exit: setcontext"); + } + errx(EXIT_FAILURE, "1 this should have never been reached!!"); + } + else { + _isr_context_switch_exit(); + } + errx(EXIT_FAILURE, "3 this should have never been reached!!"); +} + +/* ========================================= */ + + +void _isr_thread_yield(void) +{ + DEBUG_CPU("... ISR: switched to ISR context, scheduling\n"); + + if (_native_pending_signals > 0) { + DEBUG_CPU("... ISR: pending signals, handling signals\n\n"); + _native_call_sig_handlers_and_switch(); + } + + if (!IS_USED(MODULE_CORE_THREAD)) { + return; + } + + /* Set active thread */ + sched_run(); + + /* Switch to active userspace thread */ + _isr_switch_to_user(); +} + +/* ^ + * | + * | + * thread_yield_higher continues + * in ISR context in _isr_thread_yield + */ + +void thread_yield_higher(void) +{ + sched_context_switch_request = 1; + + if (_native_in_isr == 0 && _native_interrupts_enabled) { + DEBUG_CPU("yielding higher priority thread, switching to ISR context ...\n"); + + _native_in_isr = 1; + irq_disable(); + + /* Create the ISR context, will execute isr_thread_yield */ + _native_isr_context_make(_isr_thread_yield); + if (swapcontext(_native_user_context(), _native_isr_context) == -1) { + err(EXIT_FAILURE, "thread_yield_higher: swapcontext"); + } + irq_enable(); + } +} + +/* ========================================= */ + +void native_cpu_init(void) +{ + if (getcontext(&_end_context) == -1) { + err(EXIT_FAILURE, "native_cpu_init: getcontext"); + } + + /* The _end_context allows RIOT to execute code after a thread task func returns. + * This works as follows (explanation based on libplatform) + * - In thread_stack_init, we call makecontext with the thread task func + * and uc_link = _end_context. + * - makecontext modifies the ucontext so that _ctx_start (in the libc/libplatform impl) + * is called when setcontext is executed. The thread task func resides in a register. + * - When the thread is started using setcontext, _ctx_start branches and links to the + * the task func. After the task func returns, _ctx_start would normally call exit. + * However, if _end_context is set, it calls setcontext on th bespoke _end_context. + */ + _end_context.uc_stack.ss_sp = malloc(SIGSTKSZ); + expect(_end_context.uc_stack.ss_sp != NULL); + _end_context.uc_stack.ss_size = SIGSTKSZ; + _end_context.uc_stack.ss_flags = 0; + makecontext(&_end_context, sched_task_exit, 0); + + (void)VALGRIND_STACK_REGISTER(_end_context.uc_stack.ss_sp, + (char *)_end_context.uc_stack.ss_sp + _end_context.uc_stack.ss_size); + VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n", + (void*)_end_context.uc_stack.ss_sp, + (void*)((char *)_end_context.uc_stack.ss_sp + _end_context.uc_stack.ss_size)); + + DEBUG_CPU("RIOT native cpu initialized.\n"); +} + +/* ========================================= */ + static inline void *align_stack(uintptr_t start, int *stacksize) { const size_t alignment = sizeof(uintptr_t); @@ -83,17 +238,18 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_sta ucontext_t *p; stack_start = align_stack((uintptr_t)stack_start, &stacksize); - DEBUG_CPU("... ISR: switching to user thread, calling setcontext(PID %" PRIkernel_pid ")\n\n", thread_getpid()); (void) VALGRIND_STACK_REGISTER(stack_start, (char *)stack_start + stacksize); VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n", stack_start, (void*)((char *)stack_start + stacksize)); - DEBUG("thread_stack_init\n"); + DEBUG_CPU("thread_stack_init\n"); /* Use intermediate cast to uintptr_t to silence -Wcast-align. The stack * is aligned to word size above. */ p = (ucontext_t *)(uintptr_t)((uint8_t *)stack_start + (stacksize - sizeof(ucontext_t))); + /* Stack guards might be in the way. */ + memset(p, 0, sizeof(ucontext_t)); stacksize -= sizeof(ucontext_t); if (getcontext(p) == -1) { @@ -103,135 +259,13 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_sta p->uc_stack.ss_sp = stack_start; p->uc_stack.ss_size = stacksize; p->uc_stack.ss_flags = 0; - p->uc_link = &end_context; + p->uc_link = &_end_context; if (sigemptyset(&(p->uc_sigmask)) == -1) { err(EXIT_FAILURE, "thread_stack_init: sigemptyset"); } - makecontext(p, (void (*)(void)) task_func, 1, arg); + makecontext(p, (void (*)(void))task_func, 1, arg); return (char *) p; } - -void isr_cpu_switch_context_exit(void) -{ - ucontext_t *ctx; - - DEBUG_CPU("_isr_schedule_and_switch\n"); - if (((sched_context_switch_request == 1) || (thread_get_active() == NULL)) - && IS_USED(MODULE_CORE_THREAD)) { - sched_run(); - } - - DEBUG("isr_cpu_switch_context_exit: calling setcontext(%" PRIkernel_pid ")\n\n", thread_getpid()); - /* Use intermediate cast to uintptr_t to silence -Wcast-align. - * stacks are manually word aligned in thread_static_init() */ - ctx = (ucontext_t *)(uintptr_t)(thread_get_active()->sp); - - native_interrupts_enabled = 1; - _native_mod_ctx_leave_sigh(ctx); - - if (setcontext(ctx) == -1) { - err(EXIT_FAILURE, "isr_cpu_switch_context_exit: setcontext"); - } - errx(EXIT_FAILURE, "2 this should have never been reached!!"); -} - -void cpu_switch_context_exit(void) -{ -#ifdef NATIVE_AUTO_EXIT - if (sched_num_threads <= 1) { - extern unsigned _native_retval; - DEBUG_CPU("cpu_switch_context_exit: last task has ended. exiting.\n"); - real_exit(_native_retval); - } -#endif - - if (_native_in_isr == 0) { - irq_disable(); - _native_in_isr = 1; - native_isr_context.uc_stack.ss_sp = __isr_stack; - native_isr_context.uc_stack.ss_size = __isr_stack_size; - native_isr_context.uc_stack.ss_flags = 0; - makecontext(&native_isr_context, isr_cpu_switch_context_exit, 0); - if (setcontext(&native_isr_context) == -1) { - err(EXIT_FAILURE, "cpu_switch_context_exit: setcontext"); - } - errx(EXIT_FAILURE, "1 this should have never been reached!!"); - } - else { - isr_cpu_switch_context_exit(); - } - errx(EXIT_FAILURE, "3 this should have never been reached!!"); -} - -void isr_thread_yield(void) -{ - DEBUG_CPU("... ISR: switched to ISR context, scheduling\n"); - - if (_native_sigpend > 0) { - native_irq_handler(); - DEBUG_CPU("... ISR: pending signals, handling signals\n\n"); - } - - if (!IS_USED(MODULE_CORE_THREAD)) { - return; - } - sched_run(); - - /* Use intermediate cast to uintptr_t to silence -Wcast-align. - * stacks are manually word aligned in thread_static_init() */ - ucontext_t *ctx = (ucontext_t *)(uintptr_t)(thread_get_active()->sp); - DEBUG("isr_thread_yield: switching to(%" PRIkernel_pid ")\n\n", - thread_getpid()); - - native_interrupts_enabled = 1; - _native_mod_ctx_leave_sigh(ctx); - - if (setcontext(ctx) == -1) { - err(EXIT_FAILURE, "isr_thread_yield: setcontext"); - } -} - -void thread_yield_higher(void) -{ - sched_context_switch_request = 1; - - if (_native_in_isr == 0 && native_interrupts_enabled) { - /* Use intermediate cast to uintptr_t to silence -Wcast-align. - * stacks are manually word aligned in thread_static_init() */ - ucontext_t *ctx = (ucontext_t *)(uintptr_t)(thread_get_active()->sp); - DEBUG_CPU("yielding higher priority thread, switching to ISR context ...\n"); - _native_in_isr = 1; - irq_disable(); - native_isr_context.uc_stack.ss_sp = __isr_stack; - native_isr_context.uc_stack.ss_size = __isr_stack_size; - native_isr_context.uc_stack.ss_flags = 0; - makecontext(&native_isr_context, isr_thread_yield, 0); - if (swapcontext(ctx, &native_isr_context) == -1) { - err(EXIT_FAILURE, "thread_yield_higher: swapcontext"); - } - irq_enable(); - } -} - -void native_cpu_init(void) -{ - if (getcontext(&end_context) == -1) { - err(EXIT_FAILURE, "native_cpu_init: getcontext"); - } - - end_context.uc_stack.ss_sp = malloc(SIGSTKSZ); - expect(end_context.uc_stack.ss_sp != NULL); - end_context.uc_stack.ss_size = SIGSTKSZ; - end_context.uc_stack.ss_flags = 0; - makecontext(&end_context, sched_task_exit, 0); - (void)VALGRIND_STACK_REGISTER(end_context.uc_stack.ss_sp, - (char *)end_context.uc_stack.ss_sp + end_context.uc_stack.ss_size); - VALGRIND_DEBUG("VALGRIND_STACK_REGISTER(%p, %p)\n", - (void*)end_context.uc_stack.ss_sp, - (void*)((char *)end_context.uc_stack.ss_sp + end_context.uc_stack.ss_size)); - - DEBUG("RIOT native cpu initialized.\n"); -} From 7d83850395878f178bbb62dcc962338b1f5f501b Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:41:10 +0100 Subject: [PATCH 08/13] cpu/native: assembly: gardening --- cpu/native/fs/native_fs.c | 8 +- cpu/native/include/architecture_arch.h | 12 +- cpu/native/include/async_read.h | 2 +- cpu/native/include/backtrace.h | 2 +- cpu/native/include/cpu_conf.h | 55 +++-- cpu/native/include/eeprom_native.h | 7 +- cpu/native/include/netdev_tap_params.h | 4 +- cpu/native/include/periph_conf.h | 20 +- cpu/native/include/socket_zep_params.h | 4 +- cpu/native/include/syscalls.h | 4 +- cpu/native/include/util/ucontext.h | 4 +- cpu/native/include/util/valgrind.h | 10 +- cpu/native/netdev_tap/netdev_tap.c | 14 +- cpu/native/periph/rtc.c | 2 +- cpu/native/startup.c | 18 +- cpu/native/tramp.S | 274 +++++++++++++++---------- 16 files changed, 253 insertions(+), 187 deletions(-) diff --git a/cpu/native/fs/native_fs.c b/cpu/native/fs/native_fs.c index 3d1fd24867..015a65ec30 100644 --- a/cpu/native/fs/native_fs.c +++ b/cpu/native/fs/native_fs.c @@ -30,7 +30,7 @@ * @brief Assign each native instance a sub-sirectory based on `_native_id` */ #ifndef CONFIG_NATIVE_ISOLATE_FS -#define CONFIG_NATIVE_ISOLATE_FS 0 +# define CONFIG_NATIVE_ISOLATE_FS 0 #endif /* Not using static inline functions here because they are also assigned to. */ @@ -53,14 +53,14 @@ static void _do_prefix(vfs_mount_t *mountp, const char *name, char *buffer, size res = snprintf(buffer, len, "%s%s", fs_desc->hostpath, name); } -#ifdef NDEBUG +# ifdef NDEBUG if (res > len) { puts("fs_native: path larger than PATH_MAX"); exit(ENOBUFS); } -#else +# else assert(res <= len); -#endif +# endif } static char *_prefix_path(vfs_mount_t *mountp, const char *name) diff --git a/cpu/native/include/architecture_arch.h b/cpu/native/include/architecture_arch.h index 6df3954a14..18f9a08700 100644 --- a/cpu/native/include/architecture_arch.h +++ b/cpu/native/include/architecture_arch.h @@ -32,12 +32,12 @@ void native_breakpoint(void); /* Doc is provided centrally in architecture.h, hide this from Doxygen */ #ifndef DOXYGEN -# if (__SIZEOF_POINTER__ == 8) -# define ARCHITECTURE_WORD_BITS (64U) -# else -# define ARCHITECTURE_WORD_BITS (32U) -# endif -# define ARCHITECTURE_BREAKPOINT(v) native_breakpoint() +# if (__SIZEOF_POINTER__ == 8) +# define ARCHITECTURE_WORD_BITS (64U) +# else +# define ARCHITECTURE_WORD_BITS (32U) +# endif +# define ARCHITECTURE_BREAKPOINT(v) native_breakpoint() #endif /* DOXYGEN */ #ifdef __cplusplus diff --git a/cpu/native/include/async_read.h b/cpu/native/include/async_read.h index e483c27433..4793b5bd32 100644 --- a/cpu/native/include/async_read.h +++ b/cpu/native/include/async_read.h @@ -30,7 +30,7 @@ extern "C" { * @brief Maximum number of file descriptors */ #ifndef ASYNC_READ_NUMOF -#define ASYNC_READ_NUMOF 2 +# define ASYNC_READ_NUMOF 2 #endif /** diff --git a/cpu/native/include/backtrace.h b/cpu/native/include/backtrace.h index 84a83d41af..89e3f7bbb3 100644 --- a/cpu/native/include/backtrace.h +++ b/cpu/native/include/backtrace.h @@ -32,7 +32,7 @@ extern "C" { * @brief Maximum number of return addresses to print */ #ifndef BACKTRACE_SIZE -#define BACKTRACE_SIZE (4U) +# define BACKTRACE_SIZE (4U) #endif /** diff --git a/cpu/native/include/cpu_conf.h b/cpu/native/include/cpu_conf.h index 28797134c6..84906bbe1d 100644 --- a/cpu/native/include/cpu_conf.h +++ b/cpu/native/include/cpu_conf.h @@ -31,50 +31,47 @@ extern "C" { * * @{ */ -#ifndef THREAD_STACKSIZE_DEFAULT -#if (__SIZEOF_POINTER__ == 8) -/** - * @brief Default size of a thread stack on 64-bit platforms - */ -#define THREAD_STACKSIZE_DEFAULT (16384) -#else +#if !defined(THREAD_STACKSIZE_DEFAULT) || defined(DOXYGEN) /** * @brief Default size of a thread stack */ -#define THREAD_STACKSIZE_DEFAULT (8192) -#endif +# if (__SIZEOF_POINTER__ == 8) +# define THREAD_STACKSIZE_DEFAULT (16384) +# else +# define THREAD_STACKSIZE_DEFAULT (8192) +# endif #endif /** * @brief Default size of idle thread stack */ -#ifndef THREAD_STACKSIZE_IDLE -#define THREAD_STACKSIZE_IDLE (THREAD_STACKSIZE_DEFAULT) +#if !defined(THREAD_STACKSIZE_IDLE) || defined(DOXYGEN) +# define THREAD_STACKSIZE_IDLE (THREAD_STACKSIZE_DEFAULT) #endif /** * @brief Extra stack buffer capacity needed for `printf` */ -#ifndef THREAD_EXTRA_STACKSIZE_PRINTF -#define THREAD_EXTRA_STACKSIZE_PRINTF (4096) +#if !defined(THREAD_EXTRA_STACKSIZE_PRINTF) || defined(DOXYGEN) +# define THREAD_EXTRA_STACKSIZE_PRINTF (4096) #endif /** * @brief Extra stack buffer capacity needed for `printf` in floating-point operations */ -#ifndef THREAD_EXTRA_STACKSIZE_PRINTF_FLOAT -#define THREAD_EXTRA_STACKSIZE_PRINTF_FLOAT (4096) +#if !defined(THREAD_EXTRA_STACKSIZE_PRINTF_FLOAT) || defined(DOXYGEN) +# define THREAD_EXTRA_STACKSIZE_PRINTF_FLOAT (4096) #endif /* for core/include/thread.h */ /** * @brief Minimum thread size */ -#ifndef THREAD_STACKSIZE_MINIMUM -#define THREAD_STACKSIZE_MINIMUM (THREAD_STACKSIZE_DEFAULT) +#if !defined(THREAD_STACKSIZE_MINIMUM) || defined(DOXYGEN) +# define THREAD_STACKSIZE_MINIMUM (THREAD_STACKSIZE_DEFAULT) #endif /* native internal */ /** * @brief Size of stack used in ISR context */ -#ifndef ISR_STACKSIZE -#define ISR_STACKSIZE (THREAD_STACKSIZE_DEFAULT) +#if !defined(ISR_STACKSIZE) || defined(DOXYGEN) +# define ISR_STACKSIZE (THREAD_STACKSIZE_DEFAULT) #endif /** @} */ @@ -103,15 +100,15 @@ extern "C" { /** * @brief Size of a single emulated flash page */ -#ifndef FLASHPAGE_SIZE -# define FLASHPAGE_SIZE (512) +#if !defined(FLASHPAGE_SIZE) || defined(DOXYGEN) +# define FLASHPAGE_SIZE (512) #endif /** * @brief Total number of emulated flash pages */ -#ifndef FLASHPAGE_NUMOF -# define FLASHPAGE_NUMOF (32) +#if !defined(FLASHPAGE_NUMOF) || defined(DOXYGEN) +# define FLASHPAGE_NUMOF (32) #endif /** @@ -119,8 +116,8 @@ extern "C" { * * The address passed to @ref flashpage_write must be a multiple of this constant. */ -#ifndef FLASHPAGE_WRITE_BLOCK_ALIGNMENT -# define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (8) +#if !defined(FLASHPAGE_WRITE_BLOCK_ALIGNMENT) || defined(DOXYGEN) +# define FLASHPAGE_WRITE_BLOCK_ALIGNMENT (8) #endif /** * @brief Flashpage block size @@ -129,8 +126,8 @@ extern "C" { * * @see @ref flashpage_write */ -#ifndef FLASHPAGE_WRITE_BLOCK_SIZE -# define FLASHPAGE_WRITE_BLOCK_SIZE (16) +#if !defined(FLASHPAGE_WRITE_BLOCK_SIZE) || defined(DOXYGEN) +# define FLASHPAGE_WRITE_BLOCK_SIZE (16) #endif /** @@ -138,8 +135,8 @@ extern "C" { * * The flash is set to this constant when you call @ref flashpage_erase. */ -#ifndef FLASHPAGE_ERASE_STATE -# define FLASHPAGE_ERASE_STATE (0x0) +#if !defined(FLASHPAGE_ERASE_STATE) || defined(DOXYGEN) +# define FLASHPAGE_ERASE_STATE (0x0) #endif /** diff --git a/cpu/native/include/eeprom_native.h b/cpu/native/include/eeprom_native.h index 518b29fb17..ee4acce576 100644 --- a/cpu/native/include/eeprom_native.h +++ b/cpu/native/include/eeprom_native.h @@ -26,8 +26,11 @@ extern "C" { #endif -#ifndef EEPROM_FILEPATH_MAX_LEN -#define EEPROM_FILEPATH_MAX_LEN (128U) /**< Maximum path len to store the EEPROM filepath */ +#if !defined(EEPROM_FILEPATH_MAX_LEN) || defined(DOXYGEN) +/** + * @brief Maximum path len to store the EEPROM filepath + */ +# define EEPROM_FILEPATH_MAX_LEN (128U) #endif /** diff --git a/cpu/native/include/netdev_tap_params.h b/cpu/native/include/netdev_tap_params.h index 2cec1d3864..766a714647 100644 --- a/cpu/native/include/netdev_tap_params.h +++ b/cpu/native/include/netdev_tap_params.h @@ -31,8 +31,8 @@ extern "C" { * @note This was decided to only be configurable on compile-time to be * more similar to actual boards */ -#ifndef NETDEV_TAP_MAX -#define NETDEV_TAP_MAX (1) +#if !defined(NETDEV_TAP_MAX) || defined(DOXYGEN) +# define NETDEV_TAP_MAX (1) #endif /** diff --git a/cpu/native/include/periph_conf.h b/cpu/native/include/periph_conf.h index 4dbb0f133d..cf8aa132ce 100644 --- a/cpu/native/include/periph_conf.h +++ b/cpu/native/include/periph_conf.h @@ -30,8 +30,8 @@ extern "C" { * * 1GHz is an arbitrary value used for compatibility with other platforms. */ -#ifndef CLOCK_CORECLOCK -#define CLOCK_CORECLOCK GHZ(1) +#if !defined(CLOCK_CORECLOCK) || defined(DOXYGEN) +# define CLOCK_CORECLOCK GHZ(1) #endif /** @@ -69,22 +69,22 @@ extern "C" { /** * @brief UART configuration */ -#ifndef UART_NUMOF -#define UART_NUMOF (1U) +#if !defined(UART_NUMOF) || defined(DOXYGEN) +# define UART_NUMOF (1U) #endif /** * @brief PWM configuration */ -#ifndef PWM_NUMOF -#define PWM_NUMOF (8U) +#if !defined(PWM_NUMOF) || defined(DOXYGEN) +# define PWM_NUMOF (8U) #endif /** * @brief QDEC configuration */ -#ifndef QDEC_NUMOF -#define QDEC_NUMOF (8U) +#if !defined(QDEC_NUMOF) || defined(DOXYGEN) +# define QDEC_NUMOF (8U) #endif /* MARK: - SPI configuration (Linux host only) */ @@ -102,7 +102,7 @@ extern "C" { * * Can be overridden during compile time with a `-DSPI_NUMOF=n` flag. */ -#define SPI_NUMOF (1U) +# define SPI_NUMOF (1U) #endif #if !defined(SPI_MAXCS) || defined(DOXYGEN) @@ -112,7 +112,7 @@ extern "C" { * Allows up to SPI_MAXCS hardware cable select lines per SPI device. The n-th * hardware select line can be used with the SPI_HWCS macro. */ -#define SPI_MAXCS (4U) +# define SPI_MAXCS (4U) #endif /** diff --git a/cpu/native/include/socket_zep_params.h b/cpu/native/include/socket_zep_params.h index 7330e8886b..8736ce548f 100644 --- a/cpu/native/include/socket_zep_params.h +++ b/cpu/native/include/socket_zep_params.h @@ -31,8 +31,8 @@ extern "C" { * @note This was decided to only be confiruable on compile-time to be * more similar to actual boards */ -#ifndef SOCKET_ZEP_MAX -#define SOCKET_ZEP_MAX (1) +#if !defined(SOCKET_ZEP_MAX) || defined(DOXYGEN) +# define SOCKET_ZEP_MAX (1) #endif /** diff --git a/cpu/native/include/syscalls.h b/cpu/native/include/syscalls.h index 3235af3a9d..3a9f3c720f 100644 --- a/cpu/native/include/syscalls.h +++ b/cpu/native/include/syscalls.h @@ -21,9 +21,9 @@ #ifndef DOXYGEN # if NATIVE_SYSCALLS_DEFINITION -# define __SPECIFIER +# define __SPECIFIER # else -# define __SPECIFIER extern +# define __SPECIFIER extern # endif #endif diff --git a/cpu/native/include/util/ucontext.h b/cpu/native/include/util/ucontext.h index 5880dce198..3667446e5d 100644 --- a/cpu/native/include/util/ucontext.h +++ b/cpu/native/include/util/ucontext.h @@ -11,9 +11,9 @@ #define UTIL_UCONTEXT_H #if USE_LIBUCONTEXT -# include +# include #else -# include +# include #endif /* USE_LIBUCONTEXT */ #include diff --git a/cpu/native/include/util/valgrind.h b/cpu/native/include/util/valgrind.h index 3457527884..f5323aec48 100644 --- a/cpu/native/include/util/valgrind.h +++ b/cpu/native/include/util/valgrind.h @@ -10,14 +10,14 @@ #define UTIL_VALGRIND_H #ifdef HAVE_VALGRIND_H -# include +# include #define VALGRIND_DEBUG DEBUG -# elif defined(HAVE_VALGRIND_VALGRIND_H) -# include +# elif defined(HAVE_VALGRIND_VALGRIND_H) +# include #define VALGRIND_DEBUG DEBUG #else -# define VALGRIND_STACK_REGISTER(...) (0) -# define VALGRIND_DEBUG(...) +# define VALGRIND_STACK_REGISTER(...) (0) +# define VALGRIND_DEBUG(...) #endif #ifdef __cplusplus diff --git a/cpu/native/netdev_tap/netdev_tap.c b/cpu/native/netdev_tap/netdev_tap.c index 1a0c8bd472..8ddf7fc77a 100644 --- a/cpu/native/netdev_tap/netdev_tap.c +++ b/cpu/native/netdev_tap/netdev_tap.c @@ -34,14 +34,14 @@ #include "byteorder.h" #if defined(__FreeBSD__) -# include -# include -# include -# include +# include +# include +# include +# include #else -# include -# include -# include +# include +# include +# include #endif #include "native_internal.h" diff --git a/cpu/native/periph/rtc.c b/cpu/native/periph/rtc.c index 6e1200e5fa..aa4bcd1b74 100644 --- a/cpu/native/periph/rtc.c +++ b/cpu/native/periph/rtc.c @@ -40,7 +40,7 @@ * @brief Time source of the native RTC */ #ifndef NATIVE_RTC_SOURCE -#define NATIVE_RTC_SOURCE CLOCK_REALTIME +# define NATIVE_RTC_SOURCE CLOCK_REALTIME #endif static int _native_rtc_initialized = 0; diff --git a/cpu/native/startup.c b/cpu/native/startup.c index e24568f045..fc1c2bb700 100644 --- a/cpu/native/startup.c +++ b/cpu/native/startup.c @@ -57,7 +57,6 @@ pid_t _native_pid; pid_t _native_id; unsigned _native_rng_seed = 0; int _native_rng_mode = 0; -const char *_native_unix_socket_path = NULL; #ifdef MODULE_NETDEV_TAP #include "netdev_tap_params.h" @@ -115,9 +114,11 @@ static const char short_opts[] = ":hi:s:deEoc:" ""; #if __GLIBC__ -static const bool _is_glibc = true; +/* glibc and Apple's libSystem pass argc, argv, and envp to init_fini handlers */ +# define _HAVE_INIT_FINIT_PROGRAM_ARGUMENTS 1 #else -static const bool _is_glibc = false; +/* otherwise, not guaranteed */ +# define _HAVE_INIT_FINIT_PROGRAM_ARGUMENTS 0 #endif static const struct option long_opts[] = { @@ -470,7 +471,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e /* Passing argc, argv, and envp to init_fini handlers is a glibc * extension. If we are not running glibc, we parse /proc/self/cmdline * to populate argc and argv by hand */ - if (!_is_glibc) { + if (!_HAVE_INIT_FINIT_PROGRAM_ARGUMENTS) { const size_t bufsize = 4096; const size_t argc_max = 32; size_t cmdlen = 0; @@ -508,6 +509,11 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e } expect((size_t)argc < argc_max); argv = realloc(argv, sizeof(char *) * (argc + 1)); + } else { + /* must be */ + assert(argc > 0); + assert(argv); + assert(argv[0]); } _native_argv = argv; @@ -684,7 +690,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e */ init_func_t *init_array_ptr = &__init_array_start; DEBUG("__init_array_start: %p\n", (void *)init_array_ptr); - while (init_array_ptr != &__init_array_end) { + while (init_array_ptr < &__init_array_end) { /* Skip everything which has already been run */ if ((*init_array_ptr) == startup) { /* Found ourselves, move on to calling the rest of the constructors */ @@ -695,7 +701,7 @@ __attribute__((constructor)) static void startup(int argc, char **argv, char **e DEBUG_STARTUP("%18p - skip\n", (void *)init_array_ptr); ++init_array_ptr; } - while (init_array_ptr != &__init_array_end) { + while (init_array_ptr < &__init_array_end) { /* call all remaining constructors */ DEBUG_STARTUP("%18p - call\n", (void *)init_array_ptr); (*init_array_ptr)(argc, argv, envp); diff --git a/cpu/native/tramp.S b/cpu/native/tramp.S index 85c7c60dc0..fd54976e95 100644 --- a/cpu/native/tramp.S +++ b/cpu/native/tramp.S @@ -7,145 +7,205 @@ * directory for more details. */ +/** + * @brief Generates platform-dependent symbol name + */ +#define SYMBOL(name) name + +/** + * @brief Defines new global symbol + */ +.macro GLOBAL_SYMBOL name + .globl SYMBOL(\name) + SYMBOL(\name): +.endm + +/** + * @brief Loads address immediate and then memory contents into register + * @param register Register to load memory contents in + * @param symbol Symbol whose memory contents to load + */ +.macro LOADMEM register, symbol + ldr \register, =\symbol + ldr \register, [\register] +.endm + +/** + * @brief Write register contents into memory + * @param value Register containing value to write + * @param register Helper register to use for loading address + * @param symbol Symbol pointing to memory location to write to + */ +.macro STOREMEM value, register, symbol + ldr \register, =\symbol + str \value, [\register] +.endm + .text -#ifdef __arm__ +#if defined(__arm__) -.globl _native_sig_leave_tramp -_native_sig_leave_tramp: - /* save _native_saved_eip and registers */ - stmdb sp!, {r0} - ldr r0, =_native_saved_eip - ldr r0, [r0] - stmdb sp!, {r0-r12} - stmdb sp!, {lr} +GLOBAL_SYMBOL _native_sig_leave_tramp + /* save _native_user_fptr and registers */ + stmdb sp!, {r0} + LOADMEM r0, SYMBOL(_native_user_fptr) + stmdb sp!, {r0-r12} + stmdb sp!, {lr} - /* exchange r0 and _native_saved_eip */ - ldr r0, [sp,#56] - ldr r1, [sp,#4 ] - str r0, [sp,#4 ] - str r1, [sp,#56] + /* exchange r0 and _native_user_fptr */ + ldr r0, [sp,#56] + ldr r1, [sp,#4 ] + str r0, [sp,#4 ] + str r1, [sp,#56] - /* call swapcontext ( _native_cur_ctx, _native_isr_ctx ) */ - ldr r2, =_native_cur_ctx - ldr r0, [r2] - ldr r2, =_native_isr_ctx - ldr r1, [r2] - bl swapcontext + /* call swapcontext(_native_current_context, _native_isr_context) */ + LOADMEM r0, SYMBOL(_native_current_context) + LOADMEM r1, SYMBOL(_native_isr_context) + bl SYMBOL(swapcontext) /* reeanble interrupts */ - bl irq_enable + bl SYMBOL(irq_enable) /* _native_in_isr = 0 */ - eor r0, r0, r0 - ldr r2, =_native_in_isr - str r0, [r2] + eor r0, r0, r0 + STOREMEM r0, r1, SYMBOL(_native_in_isr) - /* restore registers, jump to (saved) _native_saved_eip */ - ldmia sp!, {lr} - ldmia sp!, {r0-r12} - ldmia sp!, {pc} + /* restore registers, jump to (saved) _native_user_fptr */ + ldmia sp!, {lr} + ldmia sp!, {r0-r12} + ldmia sp!, {pc} + +GLOBAL_SYMBOL _native_isr_leave + stmdb sp!, {r0} + LOADMEM r0, SYMBOL(_native_user_fptr) + stmdb sp!, {r0-r12} + stmdb sp!, {lr} + + /* exchange r0 and _native_user_fptr */ + ldr r0, [sp,#56] + ldr r1, [sp,#4 ] + str r0, [sp,#4 ] + str r1, [sp,#56] -.globl _native_sig_leave_handler -_native_sig_leave_handler: - stmdb sp!, {r0} - ldr r0, =_native_saved_eip - ldr r0, [r0] - stmdb sp!, {r0-r12} - stmdb sp!, {lr} - /* exchange r0 and _native_saved_eip */ - ldr r0, [sp,#56] - ldr r1, [sp,#4 ] - str r0, [sp,#4 ] - str r1, [sp,#56] /* _native_in_isr = 0 */ - eor r0, r0, r0 - ldr r1, =_native_in_isr - str r0, [r1] - ldmia sp!, {lr} - ldmia sp!, {r0-r12} - ldmia sp!, {pc} + eor r0, r0, r0 + STOREMEM r0, r1, SYMBOL(_native_in_isr) + ldmia sp!, {lr} + ldmia sp!, {r0-r12} + ldmia sp!, {pc} -#else -.globl _native_sig_leave_tramp +#elif defined(__x86_64__) -#ifdef __x86_64__ -_native_sig_leave_tramp: - pushq _native_saved_eip(%rip) +GLOBAL_SYMBOL _native_sig_leave_tramp + /* Push (relative) return address onto stack */ + pushq SYMBOL(_native_user_fptr)(%rip) + /* Push RFLAGS register onto stack */ pushfq + /* Preserve general-purpose registers */ + pushq %rax + pushq %rcx + pushq %rdx + pushq %rbx + pushq %rbp + pushq %rsi + pushq %rdi + pushq %r8 + pushq %r9 + pushq %r10 + pushq %r11 + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 - pushq %rax - pushq %rcx - pushq %rdx - pushq %rbx - pushq %rbp - pushq %rsi - pushq %rdi - pushq %r8 - pushq %r9 - pushq %r10 - pushq %r11 - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 + /* Push swapcontext arguments onto stack (relative) */ + mov SYMBOL(_native_isr_context)(%rip), %rsi + mov SYMBOL(_native_current_context)(%rip), %rdi + /* call swapcontext(_native_current_context (RDI), _native_isr_context (RSI)) */ + call SYMBOL(swapcontext) - mov _native_isr_ctx(%rip), %rsi - mov _native_cur_ctx(%rip), %rdi + /* reeanble interrupts */ + call SYMBOL(irq_enable) - call swapcontext - - call irq_enable - - movl $0x0, _native_in_isr(%rip) - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %r11 - popq %r10 - popq %r9 - popq %r8 - popq %rdi - popq %rsi - popq %rbp - popq %rbx - popq %rdx - popq %rcx - popq %rax + /* _native_in_isr = 0 */ + movl $0x0, SYMBOL(_native_in_isr)(%rip) + /* Restore general-purpose registers */ + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rdi + popq %rsi + popq %rbp + popq %rbx + popq %rdx + popq %rcx + popq %rax + /* Restore RFLAGS register*/ popfq + + /* Pop and jump to _native_user_fptr */ ret -#else -_native_sig_leave_tramp: - pushl _native_saved_eip + +GLOBAL_SYMBOL _native_isr_leave + /* Push (relative) return address onto stack */ + pushq SYMBOL(_native_user_fptr)(%rip) + + /* _native_in_isr = 0 */ + movl $0x0, SYMBOL(_native_in_isr)(%rip) + + /* Pop and jump to _native_user_fptr */ + ret + +#elif defined(__i386__) + +GLOBAL_SYMBOL _native_sig_leave_tramp + /* Push return address onto stack */ + pushl SYMBOL(_native_user_fptr) + /* Push eflags register onto stack */ pushfl + /* Push all general-purpose registers */ pushal - pushl _native_isr_ctx - pushl _native_cur_ctx - call swapcontext - addl $8, %esp + /* Push swapcontext arguments onto stack */ + pushl SYMBOL(_native_isr_context) + pushl SYMBOL(_native_current_context) + /* call swapcontext(_native_current_context, _native_isr_context) */ + call SYMBOL(swapcontext) + /* Remove swapcontext arguments from stack */ + addl $8, %esp - call irq_enable + /* reeanble interrupts */ + call SYMBOL(irq_enable) - movl $0x0, _native_in_isr + /* _native_in_isr = 0 */ + movl $0x0, SYMBOL(_native_in_isr) + + /* Pop all general-purpose registers */ popal + /* Pop eflags register */ popfl + /* Pop and jump to _native_user_fptr */ ret -#endif -.globl _native_sig_leave_handler -_native_sig_leave_handler: -#ifdef __x86_64__ - pushq _native_saved_eip(%rip) - movl $0x0, _native_in_isr(%rip) -#else - pushl _native_saved_eip - movl $0x0, _native_in_isr -#endif +GLOBAL_SYMBOL _native_isr_leave + /* Push return address onto stack */ + pushl SYMBOL(_native_user_fptr) + + /* _native_in_isr = 0 */ + movl $0x0, SYMBOL(_native_in_isr) + + /* Pop and jump to _native_user_fptr*/ ret + +#else +# error "Unsupported architecture" #endif #if defined(__linux__) && defined(__ELF__) From 254e0ada9e517dd21ea6a975fefabd2e61cf5ea4 Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Fri, 7 Mar 2025 14:42:28 +0100 Subject: [PATCH 09/13] cpu/native: enable _GNU_SOURCE/_XOPEN_SOURCE --- makefiles/arch/native.inc.mk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/makefiles/arch/native.inc.mk b/makefiles/arch/native.inc.mk index bb1ef3a88d..1e1804199c 100644 --- a/makefiles/arch/native.inc.mk +++ b/makefiles/arch/native.inc.mk @@ -57,6 +57,12 @@ ifeq ($(OS),Darwin) CFLAGS += -Wno-deprecated-declarations endif +ifneq ($(filter $(OS),Darwin FreeBSD),) + CFLAGS += -D_XOPEN_SOURCE +else + CFLAGS += -D_GNU_SOURCE +endif + # unwanted (CXXUWFLAGS) and extra (CXXEXFLAGS) flags for c++ CXXUWFLAGS += CXXEXFLAGS += From 6e5260c2d59d3510e10c1198165cf28eea574182 Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Sat, 8 Mar 2025 15:47:36 +0100 Subject: [PATCH 10/13] cpu/native: enable 64-bit thread arguments --- cpu/native/include/util/ucontext.h | 45 ++++++++++++++++++++++++++++++ cpu/native/native_cpu.c | 2 +- cpu/native/tramp.S | 11 ++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/cpu/native/include/util/ucontext.h b/cpu/native/include/util/ucontext.h index 3667446e5d..1e11e8b846 100644 --- a/cpu/native/include/util/ucontext.h +++ b/cpu/native/include/util/ucontext.h @@ -82,6 +82,51 @@ static inline void _context_set_fptr(ucontext_t *context, uintptr_t func) { } /** @} */ +/* MARK: - 64-bit support for makecontext */ +/** + * @name 64-bit support for makecontext + * @{ + */ +#if defined(__LP64__) || defined(DOXYGEN) +/** + * @brief Invokes thread task function + * + * This function fixes the otherwise necessary cast from `void*` to `int` of the thread + * task function pointer. We pass the task func and its argument in registers. + * See @ref makecontext64. + */ +extern void _start_task_func64(void); +#endif + +/** + * @brief Like `makecontext`, allows 64-bit wide function argument on 64-bit platforms + * @param context `ucontext_t` + * @param func Function to be executed when context is applied + * @param arg Function argument, previously limited to `int` width, can now be up to 64 bits wide on 64-bit platforms + * + * Internally, we circumvent the 32-bit `int` limitation by passing the parameter in a register. This is done using + * a custom function defined in `native.S` + */ +static inline void makecontext64(ucontext_t *context, void (*func)(void), void* arg) { +# if defined(__LP64__) + /* makecontext accepts int arguments. In RIOT, we use void* for the optional argument. + * To not truncate the argument pointer, we pass it in a register to _start_task_func64. */ + makecontext(context, (void (*)(void))_start_task_func64, 0); + +# if defined(__x86_64__) +# if defined(__linux__) + context->uc_mcontext.gregs[REG_R14] = (greg_t)func; + context->uc_mcontext.gregs[REG_R15] = (greg_t)arg; +# endif +# endif + +# else + /* On 32-bit platforms, the width of an int is enough to fit a pointer. */ + makecontext(context, (void (*)(void))func, 1, arg); +# endif +} +/** @} */ + /** @} */ #ifdef __cplusplus diff --git a/cpu/native/native_cpu.c b/cpu/native/native_cpu.c index 767738cc61..032b67cc3f 100644 --- a/cpu/native/native_cpu.c +++ b/cpu/native/native_cpu.c @@ -265,7 +265,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_sta err(EXIT_FAILURE, "thread_stack_init: sigemptyset"); } - makecontext(p, (void (*)(void))task_func, 1, arg); + makecontext64(p, (void (*)(void))task_func, arg); return (char *) p; } diff --git a/cpu/native/tramp.S b/cpu/native/tramp.S index fd54976e95..ec17bf9d45 100644 --- a/cpu/native/tramp.S +++ b/cpu/native/tramp.S @@ -162,6 +162,17 @@ GLOBAL_SYMBOL _native_isr_leave /* Pop and jump to _native_user_fptr */ ret +GLOBAL_SYMBOL _start_task_func64 + /* Use r14 and r15 as scratch registers. */ + /* r8, r9 / r12 are used by glibc / libplatform on arm64 */ + /* This is the 64-bit function argument. RIOT threads can only receive one argument. */ + /* System V ABI says: first argument in RDI. + * See: https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf + * > %rdi - used to pass 1st argument to functions */ + mov %r15, %rdi + /* Call user thread func. */ + jmp *%r14 + #elif defined(__i386__) GLOBAL_SYMBOL _native_sig_leave_tramp From e95be58fb95b6e6266839948c6b897536a36a5a4 Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Sat, 8 Mar 2025 17:05:25 +0100 Subject: [PATCH 11/13] cpu/native: rename native_cpu.c, irq_cpu.c, tramp.S --- cpu/native/{native_cpu.c => cpu.c} | 0 cpu/native/{irq_cpu.c => irq.c} | 0 cpu/native/{tramp.S => native.S} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename cpu/native/{native_cpu.c => cpu.c} (100%) rename cpu/native/{irq_cpu.c => irq.c} (100%) rename cpu/native/{tramp.S => native.S} (100%) diff --git a/cpu/native/native_cpu.c b/cpu/native/cpu.c similarity index 100% rename from cpu/native/native_cpu.c rename to cpu/native/cpu.c diff --git a/cpu/native/irq_cpu.c b/cpu/native/irq.c similarity index 100% rename from cpu/native/irq_cpu.c rename to cpu/native/irq.c diff --git a/cpu/native/tramp.S b/cpu/native/native.S similarity index 100% rename from cpu/native/tramp.S rename to cpu/native/native.S From 9cad51126e9daf9a9f1a25696b3f126e0f9cb843 Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Mon, 10 Mar 2025 17:59:54 +0100 Subject: [PATCH 12/13] cpu/native: add missing signal.h import --- cpu/native/socket_zep/socket_zep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cpu/native/socket_zep/socket_zep.c b/cpu/native/socket_zep/socket_zep.c index 75ebf84c64..512dfe5d5d 100644 --- a/cpu/native/socket_zep/socket_zep.c +++ b/cpu/native/socket_zep/socket_zep.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include From 827520824933a1d1766256cdbe0d2d5a0de7e74d Mon Sep 17 00:00:00 2001 From: carl <115627588+carl-tud@users.noreply.github.com> Date: Mon, 10 Mar 2025 18:14:51 +0100 Subject: [PATCH 13/13] drivers/pcd8544: rename CHAR_WIDTH --- drivers/pcd8544/pcd8544.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pcd8544/pcd8544.c b/drivers/pcd8544/pcd8544.c index b477a288cd..981eb6afc2 100644 --- a/drivers/pcd8544/pcd8544.c +++ b/drivers/pcd8544/pcd8544.c @@ -30,7 +30,7 @@ #define ASCII_MIN 0x20 /**< start of ASCII table */ #define ASCII_MAX 0x7e /**< end of ASCII table */ -#define CHAR_WIDTH (6U) /**< pixel width of a single character */ +#define CHAR_PIXEL_WIDTH (6U) /**< pixel width of a single character */ #define SPI_CLK (SPI_CLK_1MHZ) #define SPI_MODE (SPI_MODE_0) @@ -328,10 +328,10 @@ void pcd8544_write_c(const pcd8544_t *dev, uint8_t x, uint8_t y, char c) } /* set position */ lock(dev); - _set_x(dev, x * CHAR_WIDTH); + _set_x(dev, x * CHAR_PIXEL_WIDTH); _set_y(dev, y); /* write char */ - for (unsigned i = 0; i < CHAR_WIDTH - 1; i++) { + for (unsigned i = 0; i < CHAR_PIXEL_WIDTH - 1; i++) { _write(dev, MODE_DTA, _ascii[c - ASCII_MIN][i]); } _write(dev, MODE_DTA, 0x00);