fix stack and interrupt bugs
This commit is contained in:
parent
5ca14e630b
commit
2d29a26b64
@ -17,16 +17,10 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
/* TODO: choose more sensibly? */
|
/* TODO: choose more sensibly? */
|
||||||
#ifndef KERNEL_CONF_STACKSIZE_DEFAULT
|
#define KERNEL_CONF_STACKSIZE_DEFAULT (16384)
|
||||||
#define KERNEL_CONF_STACKSIZE_DEFAULT 8192
|
#define KERNEL_CONF_STACKSIZE_IDLE (4096)
|
||||||
#endif
|
#define NATIVE_ISR_STACKSIZE (16384)
|
||||||
|
#define TRANSCEIVER_STACK_SIZE (16384)
|
||||||
#define KERNEL_CONF_STACKSIZE_IDLE 4096
|
|
||||||
#define NATIVE_ISR_STACKSIZE 8192
|
|
||||||
|
|
||||||
#define _SIG_LTC4150 SIGRTMIN + 0
|
|
||||||
|
|
||||||
/* TODO: check for overflow (SIGRTMAX) */
|
|
||||||
|
|
||||||
/* for cc110x_ng */
|
/* for cc110x_ng */
|
||||||
#define RX_BUF_SIZE (10)
|
#define RX_BUF_SIZE (10)
|
||||||
|
|||||||
@ -46,5 +46,6 @@ int unregister_interrupt(int sig);
|
|||||||
/* this should be defined elsewhere */
|
/* this should be defined elsewhere */
|
||||||
void thread_yield(void);
|
void thread_yield(void);
|
||||||
|
|
||||||
|
extern volatile ucontext_t *interrupted_contexts[MAXTHREADS];
|
||||||
/** @} */
|
/** @} */
|
||||||
#endif //_CPU_H
|
#endif //_CPU_H
|
||||||
|
|||||||
@ -37,6 +37,74 @@ struct int_handler_t {
|
|||||||
};
|
};
|
||||||
static struct int_handler_t native_irq_handlers[255];
|
static struct int_handler_t native_irq_handlers[255];
|
||||||
|
|
||||||
|
volatile ucontext_t *interrupted_contexts[MAXTHREADS];
|
||||||
|
|
||||||
|
void print_thread_sigmask(ucontext_t *cp)
|
||||||
|
{
|
||||||
|
sigset_t *p = &cp->uc_sigmask;
|
||||||
|
if (sigemptyset(p) == -1) {
|
||||||
|
err(1, "print_thread_sigmask: sigemptyset");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i<(SIGRTMAX); i++) {
|
||||||
|
if (native_irq_handlers[i].func != NULL) {
|
||||||
|
printf("%s: %s\n",
|
||||||
|
strsignal(i),
|
||||||
|
(sigismember(&native_sig_set, i) ? "blocked": "unblocked")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (sigismember(p, i)) {
|
||||||
|
printf("%s: pending\n", strsignal(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_sigmasks(void)
|
||||||
|
{
|
||||||
|
ucontext_t *p;
|
||||||
|
//tcb_t *cb = NULL;
|
||||||
|
|
||||||
|
for (int i=0; i<MAXTHREADS; i++) {
|
||||||
|
if (sched_threads[i] != NULL) {
|
||||||
|
printf("%s:\n", sched_threads[i]->name);
|
||||||
|
//print_thread_sigmask(sched_threads[i]->sp);
|
||||||
|
p = sched_threads[i]->stack_start;
|
||||||
|
print_thread_sigmask(p);
|
||||||
|
puts("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void native_print_signals()
|
||||||
|
{
|
||||||
|
sigset_t p, q;
|
||||||
|
puts("native signals:\n");
|
||||||
|
if (sigemptyset(&p) == -1) {
|
||||||
|
err(1, "native_print_signals: sigemptyset");
|
||||||
|
}
|
||||||
|
if (sigpending(&p) == -1) {
|
||||||
|
err(1, "native_print_signals: sigpending");
|
||||||
|
}
|
||||||
|
if (sigprocmask(SIG_SETMASK, NULL, &q) == -1) {
|
||||||
|
err(1, "native_print_signals(): sigprocmask");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i<(SIGRTMAX); i++) {
|
||||||
|
if (native_irq_handlers[i].func != NULL || i == SIGUSR1) {
|
||||||
|
printf("%s: %s\n",
|
||||||
|
strsignal(i),
|
||||||
|
(sigismember(&native_sig_set, i) ? "blocked": "unblocked")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (sigismember(&p, i)) {
|
||||||
|
printf("%s: pending\n", strsignal(i));
|
||||||
|
}
|
||||||
|
if (sigismember(&q, i)) {
|
||||||
|
printf("%s: currently blocked\n", strsignal(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* block signals
|
* block signals
|
||||||
*/
|
*/
|
||||||
@ -83,6 +151,9 @@ unsigned enableIRQ(void)
|
|||||||
prev_state = native_interrupts_enabled;
|
prev_state = native_interrupts_enabled;
|
||||||
native_interrupts_enabled = 1;
|
native_interrupts_enabled = 1;
|
||||||
|
|
||||||
|
//print_sigmasks();
|
||||||
|
//native_print_signals();
|
||||||
|
|
||||||
return prev_state;
|
return prev_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,6 +259,15 @@ void native_isr_entry(int sig, siginfo_t *info, void *context)
|
|||||||
|
|
||||||
makecontext(&native_context, native_irq_handler, 0);
|
makecontext(&native_context, native_irq_handler, 0);
|
||||||
|
|
||||||
|
#ifdef NATIVEUSESWAPCONTEXT
|
||||||
|
/**
|
||||||
|
* XXX:
|
||||||
|
* This seems to be the cause of undefined behavior. Try saving
|
||||||
|
* the context passed to this function and using setcontext to
|
||||||
|
* leave the handler.
|
||||||
|
* Also it is probably wise to makecontext the isr context
|
||||||
|
* elsewehere.
|
||||||
|
* */
|
||||||
if ((swapcontext((ucontext_t*)active_thread->sp, &native_context)) == -1) {
|
if ((swapcontext((ucontext_t*)active_thread->sp, &native_context)) == -1) {
|
||||||
err(1, "swapcontext failed");
|
err(1, "swapcontext failed");
|
||||||
}
|
}
|
||||||
@ -196,6 +276,15 @@ void native_isr_entry(int sig, siginfo_t *info, void *context)
|
|||||||
}
|
}
|
||||||
native_in_irs = 0;
|
native_in_irs = 0;
|
||||||
enableIRQ();
|
enableIRQ();
|
||||||
|
#else
|
||||||
|
interrupted_contexts[thread_getpid()] = context;
|
||||||
|
/**
|
||||||
|
* signal masks are broken
|
||||||
|
*/
|
||||||
|
//active_thread->sp = context;
|
||||||
|
setcontext(&native_context);
|
||||||
|
DEBUG("\n\n\tnever reached\n\n\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -210,13 +299,14 @@ int register_interrupt(int sig, void *handler)
|
|||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
DEBUG("XXX: register_interrupt()\n");
|
DEBUG("XXX: register_interrupt()\n");
|
||||||
|
|
||||||
if (sigaddset(&native_sig_set, sig)) {
|
if (sigdelset(&native_sig_set, sig)) {
|
||||||
err(1, "register_interrupt: sigaddset");
|
err(1, "register_interrupt: sigdelset");
|
||||||
}
|
}
|
||||||
|
|
||||||
native_irq_handlers[sig].func = handler;
|
native_irq_handlers[sig].func = handler;
|
||||||
|
|
||||||
sa.sa_sigaction = (void*) native_isr_entry;
|
sa.sa_sigaction = (void*) native_isr_entry;
|
||||||
|
/* sa.sa_handler = (void*) native_isr_entry; */
|
||||||
|
|
||||||
if (sigemptyset(&sa.sa_mask) == -1) {
|
if (sigemptyset(&sa.sa_mask) == -1) {
|
||||||
err(1, "register_interrupt: sigemptyset");
|
err(1, "register_interrupt: sigemptyset");
|
||||||
@ -242,12 +332,13 @@ int unregister_interrupt(int sig)
|
|||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
DEBUG("XXX: unregister_interrupt()\n");
|
DEBUG("XXX: unregister_interrupt()\n");
|
||||||
|
|
||||||
if (sigdelset(&native_sig_set, sig) == -1) {
|
if (sigaddset(&native_sig_set, sig) == -1) {
|
||||||
err(1, "unregister_interrupt: sigdelset");
|
err(1, "unregister_interrupt: sigaddset");
|
||||||
}
|
}
|
||||||
native_irq_handlers[sig].func = NULL;
|
native_irq_handlers[sig].func = NULL;
|
||||||
|
|
||||||
sa.sa_sigaction = SIG_IGN;
|
/* sa.sa_sigaction = SIG_IGN; */
|
||||||
|
sa.sa_handler = SIG_IGN;
|
||||||
if (sigemptyset(&sa.sa_mask) == -1) {
|
if (sigemptyset(&sa.sa_mask) == -1) {
|
||||||
err(1, "unregister_interrupt: sigemptyset");
|
err(1, "unregister_interrupt: sigemptyset");
|
||||||
}
|
}
|
||||||
@ -271,6 +362,8 @@ void native_interrupt_init(void)
|
|||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
DEBUG("XXX: native_interrupt_init()\n");
|
DEBUG("XXX: native_interrupt_init()\n");
|
||||||
|
|
||||||
|
native_interrupts_enabled = 1;
|
||||||
|
|
||||||
for (int i = 0; i<255; i++) {
|
for (int i = 0; i<255; i++) {
|
||||||
native_irq_handlers[i].func = NULL;
|
native_irq_handlers[i].func = NULL;
|
||||||
}
|
}
|
||||||
@ -281,17 +374,38 @@ void native_interrupt_init(void)
|
|||||||
}
|
}
|
||||||
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||||
|
|
||||||
|
/*
|
||||||
if (sigemptyset(&native_sig_set) == -1) {
|
if (sigemptyset(&native_sig_set) == -1) {
|
||||||
err(1, "native_interrupt_init: sigemptyset");
|
err(1, "native_interrupt_init: sigemptyset");
|
||||||
}
|
}
|
||||||
if (sigaddset(&native_sig_set, SIGUSR1) == -1) {
|
*/
|
||||||
err(1, "native_interrupt_init: sigaddset");
|
if (sigprocmask(SIG_SETMASK, NULL, &native_sig_set) == -1) {
|
||||||
|
err(1, "native_interrupt_init(): sigprocmask");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigdelset(&native_sig_set, SIGUSR1) == -1) {
|
||||||
|
err(1, "native_interrupt_init: sigdelset");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sigaction(SIGUSR1, &sa, NULL)) {
|
if (sigaction(SIGUSR1, &sa, NULL)) {
|
||||||
err(1, "native_interrupt_init: sigaction");
|
err(1, "native_interrupt_init: sigaction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sigdelset(&native_sig_set, SIGALRM) == -1) {
|
||||||
|
err(1, "native_interrupt_init: sigdelset");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sigaction(SIGALRM, &sa, NULL)) {
|
||||||
|
err(1, "native_interrupt_init: sigaction");
|
||||||
|
}
|
||||||
|
if (sigprocmask(SIG_SETMASK, &native_sig_set, NULL) == -1) {
|
||||||
|
err(1, "native_interrupt_init(): sigprocmask");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i<MAXTHREADS; i++) {
|
||||||
|
interrupted_contexts[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
puts("RIOT native interrupts/signals initialized.");
|
puts("RIOT native interrupts/signals initialized.");
|
||||||
}
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@ -75,28 +75,53 @@ char *thread_stack_init(void *task_func, void *stack_start, int stacksize)
|
|||||||
|
|
||||||
void cpu_switch_context_exit(void)
|
void cpu_switch_context_exit(void)
|
||||||
{
|
{
|
||||||
|
ucontext_t *ctx;
|
||||||
|
|
||||||
DEBUG("XXX: cpu_switch_context_exit()\n");
|
DEBUG("XXX: cpu_switch_context_exit()\n");
|
||||||
//active_thread = sched_threads[0];
|
//active_thread = sched_threads[0];
|
||||||
sched_run();
|
sched_run();
|
||||||
|
|
||||||
DEBUG("XXX: cpu_switch_context_exit(): calling setcontext(%s)\n\n", active_thread->name);
|
DEBUG("XXX: cpu_switch_context_exit(): calling setcontext(%s)\n\n", active_thread->name);
|
||||||
if (setcontext((ucontext_t*)(active_thread->sp)) == -1) {
|
if (interrupted_contexts[thread_getpid()] == NULL) {
|
||||||
|
ctx = (ucontext_t*)(active_thread->sp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ctx = interrupted_contexts[thread_getpid()];
|
||||||
|
interrupted_contexts[thread_getpid()] = NULL;
|
||||||
|
}
|
||||||
|
if (setcontext(ctx) == -1) {
|
||||||
err(1, "cpu_switch_context_exit(): setcontext():");
|
err(1, "cpu_switch_context_exit(): setcontext():");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_yield()
|
void thread_yield()
|
||||||
{
|
{
|
||||||
ucontext_t *oc;
|
/**
|
||||||
|
* XXX: check whether it is advisable to switch context for sched_run()
|
||||||
|
*/
|
||||||
|
ucontext_t *oc, *nc;
|
||||||
|
|
||||||
DEBUG("thread_yield()\n");
|
DEBUG("thread_yield()\n");
|
||||||
|
|
||||||
oc = (ucontext_t*)(active_thread->sp);
|
if (interrupted_contexts[thread_getpid()] == NULL) {
|
||||||
|
oc = (ucontext_t*)(active_thread->sp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oc = interrupted_contexts[thread_getpid()];
|
||||||
|
interrupted_contexts[thread_getpid()] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
sched_run();
|
sched_run();
|
||||||
|
|
||||||
DEBUG("thread_yield(): calling swapcontext(%s)\n\n", active_thread->name);
|
nc = (ucontext_t*)(active_thread->sp);
|
||||||
if (swapcontext(oc, (ucontext_t*)(active_thread->sp)) == -1) {
|
if (nc != oc) {
|
||||||
err(1, "thread_yield(): swapcontext()");
|
DEBUG("thread_yield(): calling swapcontext(%s)\n\n", active_thread->name);
|
||||||
|
if (swapcontext(oc, nc) == -1) {
|
||||||
|
err(1, "thread_yield(): swapcontext()");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DEBUG("thread_yield(): old = new, returning to context (%s)\n\n", active_thread->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,11 +4,13 @@
|
|||||||
#include <radio/types.h>
|
#include <radio/types.h>
|
||||||
|
|
||||||
/* Stack size for transceiver thread */
|
/* Stack size for transceiver thread */
|
||||||
|
#ifndef TRANSCEIVER_STACK_SIZE
|
||||||
#ifdef ENABLE_DEBUG
|
#ifdef ENABLE_DEBUG
|
||||||
#define TRANSCEIVER_STACK_SIZE (2048)
|
#define TRANSCEIVER_STACK_SIZE (2048)
|
||||||
#else
|
#else
|
||||||
#define TRANSCEIVER_STACK_SIZE (512)
|
#define TRANSCEIVER_STACK_SIZE (512)
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PAYLOAD_SIZE (58)
|
#define PAYLOAD_SIZE (58)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user