1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-15 17:43:51 +01:00

cpu/native: docs and descriptive naming

This commit is contained in:
carl 2025-03-07 14:34:02 +01:00
parent aff3b107c1
commit 90a3f3ffcc
15 changed files with 410 additions and 313 deletions

View File

@ -1,4 +1,4 @@
/**
/*
* Multiple asynchronous read on file descriptors
*
* Copyright (C) 2015 Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>,
@ -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 <Yonezawa-T2@mail.dnp.co.jp>
* Author: Takuo Yonezawa <Yonezawa-T2@mail.dnp.co.jp>
*/
#include <err.h>
@ -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);
}
}
/** @} */

View File

@ -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 <ludwig.knuepfer@fu-berlin.de>
*/
#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 <ludwig.knuepfer@fu-berlin.de>
*
* 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 */

View File

@ -1,4 +1,4 @@
/**
/*
* Native CPU configuration
*
* Copyright (C) 2013 Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
@ -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 <ludwig.knuepfer@fu-berlin.de>
* @}
*/
#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

View File

@ -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 <ludwig.knuepfer@fu-berlin.de>
* @see @ref cpu_native
*/
#ifndef NATIVE_INTERNAL_H
#define NATIVE_INTERNAL_H
#include <signal.h>
#include "util/ucontext.h"
#include <stdio.h>
#include <stdint.h>
#include <poll.h>
/* 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 <ucontext.h>
#undef _XOPEN_SOURCE
#else
#include <ucontext.h>
#endif
#elif defined(__linux__)
#ifndef _GNU_SOURCE
#define GNU_SOURCE
#include <ucontext.h>
#undef GNU_SOURCE
#else
#include <ucontext.h>
#endif
#endif /* BSD/Linux */
#include <stdbool.h>
#include <netdb.h>
#include <ifaddrs.h>
#include <time.h>
@ -64,80 +39,270 @@
#include <sys/uio.h>
#include <dirent.h>
#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 */

View File

@ -1,4 +1,4 @@
/**
/*
* Native CPU irq.h implementation
*
* Copyright (C) 2013 Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
@ -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 <ludwig.knuepfer@fu-berlin.de>
*/
/* __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 <err.h>
#include <signal.h>
#include <stdlib.h>
@ -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");

View File

@ -1,43 +1,31 @@
/*
* Native CPU kernel_intern.h and sched.h implementation
*
* Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
* 2013 Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
*
* 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 <ludwig.knuepfer@fu-berlin.de>
* Author: Kaspar Schleiser <kaspar@schleiser.de>
*/
/**
* @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 <ludwig.knuepfer@fu-berlin.de>
* @author Kaspar Schleiser <kaspar@schleiser.de>
*
* 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 <err.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#if USE_LIBUCONTEXT
#include <libucontext/libucontext.h>
#else
#include <ucontext.h>
#endif
#ifdef HAVE_VALGRIND_H
#include <valgrind.h>
#define VALGRIND_DEBUG DEBUG
@ -50,6 +38,8 @@
#endif
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#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;
}

View File

@ -16,6 +16,7 @@
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @}
*/
#include <assert.h>
#include <err.h>
#include <errno.h>
@ -28,19 +29,20 @@
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <unistd.h>
#include <signal.h>
/* needs to be included before native's declarations of ntohl etc. */
#include "byteorder.h"
#ifdef __FreeBSD__
#include <sys/socket.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <net/if_dl.h>
#if defined(__FreeBSD__)
# include <sys/socket.h>
# include <net/if.h>
# include <ifaddrs.h>
# include <net/if_dl.h>
#else
#include <net/if.h>
#include <linux/if_tun.h>
#include <linux/if_ether.h>
# include <net/if.h>
# include <linux/if_tun.h>
# include <linux/if_ether.h>
#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]);

View File

@ -7,15 +7,11 @@
*/
/**
* @ingroup cpu_native
* @{
*
* @file
* @brief Crash handling functions implementation for 'native' port
*
* @author Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
* @author Oliver Hahm <oliver.hahm@inria.fr>
* @brief Crash handling functions implementation for 'native' port
* @author Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
* @author Kévin Roussel <Kevin.Roussel@inria.fr>
* @author Oliver Hahm <oliver.hahm@inria.fr>
*/
#include <errno.h>

View File

@ -17,8 +17,6 @@
* @author Benjamin Valentin <benpicco@googlemail.com>
*/
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <linux/gpio.h>

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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)

View File

@ -1,5 +1,4 @@
/**
* Native CPU entry code
/* Native CPU entry code
*
* Copyright (C) 2013 Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
* 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 <ludwig.knuepfer@fu-berlin.de>
* @author Martine Lenders <m.lenders@fu-berlin.de>
* @}
* Author: Ludwig Knüpfer <ludwig.knuepfer@fu-berlin.de>
* Author: Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <dlfcn.h>
#else
#include <dlfcn.h>
#endif
#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <features.h>
#include <getopt.h>
#include <stdbool.h>
@ -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();

View File

@ -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 <ludwig.knuepfer@fu-berlin.de>
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#include <dlfcn.h>
#else
#include <dlfcn.h>
#endif
#include <err.h>
#include <errno.h>
#include <poll.h>
@ -32,7 +20,7 @@
#include <stdio.h>
#include <stdarg.h>
#ifdef MODULE_LIBC_GETTIMEOFDAY
#include <sys/time.h>
# include <sys/time.h>
#endif
#include <ifaddrs.h>
#include <sys/stat.h>
@ -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");

View File

@ -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 <benjamin.valentin@ml-pa.com>
*/