From 3b33eb4b36445ee045f4cbac27f9331988205467 Mon Sep 17 00:00:00 2001 From: bernie Date: Sun, 17 Aug 2008 15:49:48 +0000 Subject: [PATCH] irq: more emancipation from proc/preempt git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1651 38d2e660-2303-0410-9eaa-f027e97ec537 --- app/demo/demo.c | 10 ++-- app/demo/demo.mk | 7 +-- bertos/kern/irq.c | 105 ++++++++++++++++++++++++++++++++++++++++++ bertos/kern/irq.h | 44 ++++++++++++++++++ bertos/kern/preempt.c | 61 +++--------------------- bertos/kern/proc.c | 53 +++++++++++---------- bertos/kern/proc.h | 8 ++-- 7 files changed, 195 insertions(+), 93 deletions(-) create mode 100644 bertos/kern/irq.c create mode 100644 bertos/kern/irq.h diff --git a/app/demo/demo.c b/app/demo/demo.c index ed64a12d..86d8356e 100644 --- a/app/demo/demo.c +++ b/app/demo/demo.c @@ -26,21 +26,20 @@ * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. * - * Copyright 2006 Develer S.r.l. (http://www.develer.com/) - * + * Copyright 2006, 2008 Develer S.r.l. (http://www.develer.com/) * --> * - * \version $Id: demo.c 18242 2007-10-08 17:35:23Z marco $ + * \brief Multifunction system test for BeRTOS modules. * + * \version $Id: demo.c 18242 2007-10-08 17:35:23Z marco $ * \author Bernie Innocenti - * - * \brief Windowing system test. */ #include #include +#include #include #include @@ -294,6 +293,7 @@ static struct Menu main_menu = { main_items, "Main Menu", MF_STICKY, &lcd_bitmap int main(int argc, char *argv[]) { emul_init(&argc, argv); + irq_init(); timer_init(); buz_init(); kbd_init(); diff --git a/app/demo/demo.mk b/app/demo/demo.mk index 672de108..51b71bd0 100644 --- a/app/demo/demo.mk +++ b/app/demo/demo.mk @@ -18,8 +18,8 @@ demo_DEBUG = 1 TRG += demo # FIXME: we want to use g++ for C source too -CC = g++-4.1 -CXX = g++-4.1 +CC = g++-4.3 +CXX = g++-4.3 demo_CXXSRC = \ bertos/emul/emul.cpp \ @@ -52,9 +52,10 @@ demo_CSRC = \ bertos/mware/observer.c \ bertos/mware/resource.c \ bertos/mware/sprintf.c \ + bertos/kern/irq.c \ + bertos/kern/preempt.c \ bertos/kern/proc.c \ bertos/kern/proc_test.c \ - bertos/kern/preempt.c \ bertos/kern/sem.c \ bertos/kern/signal.c \ bertos/kern/monitor.c \ diff --git a/bertos/kern/irq.c b/bertos/kern/irq.c new file mode 100644 index 00000000..23d19afa --- /dev/null +++ b/bertos/kern/irq.c @@ -0,0 +1,105 @@ +/** + * \file + * + * + * \brief Process scheduler (public interface). + * + * \version $Id: proc.h 1646 2008-08-17 13:49:48Z bernie $ + * \author Bernie Innocenti + */ +#include "irq.h" + +#include +#include + +#include + +#include // FIXME: move POSIX stuff to irq_posix.h + + +MOD_DEFINE(irq) + +// FIXME +static void (*irq_handlers[100])(void); + +/* signal handler */ +void irq_entry(int signum) +{ + Process * const old_process = CurrentProcess; + + irq_handlers[signum](); + +#if CONFIG_KERN_PREEMPT + if (!CurrentProcess) + { + TRACEMSG("no runnable processes!"); + IRQ_ENABLE; + pause(); + } + else + { + if (old_process != CurrentProcess) + { + TRACEMSG("switching from %p:%s to %p:%s", + old_process, old_process ? old_process->monitor.name : "-", + CurrentProcess, CurrentProcess->monitor.name); + + if (old_process) + swapcontext(&old_process->context, &CurrentProcess->context); + else + setcontext(&CurrentProcess->context); + + // not reached + } + TRACEMSG("keeping %p:%s", CurrentProcess, CurrentProcess->monitor.name); + } +#endif // CONFIG_KERN_PREEMPT +} + +void irq_register(int irq, void (*callback)(void)) +{ + irq_handlers[irq] = callback; +} + +void irq_init(void) +{ + struct sigaction act; + act.sa_handler = irq_entry; + sigemptyset(&act.sa_mask); + //sigaddset(&act.sa_mask, irq); + act.sa_flags = SA_RESTART; // | SA_SIGINFO; + + sigaction(SIGUSR1, &act, NULL); + #if !(ARCH & ARCH_QT) + sigaction(SIGALRM, &act, NULL); + #endif + + MOD_INIT(irq); +} diff --git a/bertos/kern/irq.h b/bertos/kern/irq.h new file mode 100644 index 00000000..e170ed04 --- /dev/null +++ b/bertos/kern/irq.h @@ -0,0 +1,44 @@ +/** + * \file + * + * + * \brief Process scheduler (public interface). + * + * \version $Id: proc.h 1646 2008-08-17 13:49:48Z bernie $ + * \author Bernie Innocenti + */ +#ifndef KERN_IRQ_H +#define KERN_IRQ_H + +void irq_entry(int irq); +void irq_register(int irq, void (*handler)(void)); +void irq_init(); + +#endif // KERN_IRQ_H diff --git a/bertos/kern/preempt.c b/bertos/kern/preempt.c index 339dc09f..9af6c0d1 100644 --- a/bertos/kern/preempt.c +++ b/bertos/kern/preempt.c @@ -39,8 +39,10 @@ #include "proc_p.h" #include "proc.h" +#include #include // CPU_IDLE #include +#include /* @@ -82,8 +84,6 @@ void proc_permit(void) --CurrentProcess->forbid_cnt; } -static void (*irq_handlers[100])(void); // FIXME - void proc_preempt(void) { @@ -156,63 +156,14 @@ void proc_entry(void (*user_entry)(void)) proc_exit(); } -/* signal handler */ -void irq_entry(int signum) -{ - Process * const old_process = CurrentProcess; - - irq_handlers[signum](); - - if (!CurrentProcess) - { - TRACEMSG("no runnable processes!"); - IRQ_ENABLE; - pause(); - } - else - { - if (old_process != CurrentProcess) - { - TRACEMSG("switching from %p:%s to %p:%s", - old_process, old_process ? old_process->monitor.name : "-", - CurrentProcess, CurrentProcess->monitor.name); - - if (old_process) - swapcontext(&old_process->context, &CurrentProcess->context); - else - setcontext(&CurrentProcess->context); - - /* not reached */ - } - TRACEMSG("keeping %p:%s", CurrentProcess, CurrentProcess->monitor.name); - } -} - -void irq_register(int irq, void (*callback)(void)) -{ - irq_handlers[irq] = callback; -} - -void irq_init(void) -{ - struct sigaction act; - act.sa_handler = irq_entry; - sigemptyset(&act.sa_mask); - //sigaddset(&act.sa_mask, irq); - act.sa_flags = SA_RESTART; /* | SA_SIGINFO; */ - - sigaction(SIGUSR1, &act, NULL); - #if !(ARCH & ARCH_QT) - sigaction(SIGALRM, &act, NULL); - #endif -} - void preempt_init(void) { - irq_init(); // FIXME: move before + MOD_CHECK(irq); + MOD_CHECK(timer); + irq_register(SIGUSR1, proc_preempt); - timer_setSoftInt(&preempt_timer, proc_preempt_timer, NULL); + timer_setSoftint(&preempt_timer, proc_preempt_timer, NULL); timer_setDelay(&preempt_timer, CONFIG_KERN_QUANTUM); timer_add(&preempt_timer); } diff --git a/bertos/kern/proc.c b/bertos/kern/proc.c index 8692c170..d4f980af 100644 --- a/bertos/kern/proc.c +++ b/bertos/kern/proc.c @@ -135,7 +135,6 @@ void proc_init(void) struct Process *proc_new_with_name(UNUSED(const char *, name), void (*entry)(void), iptr_t data, size_t stack_size, cpustack_t *stack_base) { Process *proc; - size_t i; const size_t PROC_SIZE_WORDS = ROUND2(sizeof(Process), sizeof(cpustack_t)) / sizeof(cpustack_t); #if CONFIG_KERN_HEAP bool free_stack = false; @@ -200,31 +199,35 @@ struct Process *proc_new_with_name(UNUSED(const char *, name), void (*entry)(voi #endif #endif -#if CONFIG_KERN_PREEMPT - // FIXME: proc_exit - getcontext(&proc->context); - proc->context.uc_stack.ss_sp = stack_base; - proc->context.uc_stack.ss_size = stack_size; - proc->context.uc_link = NULL; - makecontext(&proc->context, (void (*)(void))proc_entry, 1, entry); - -#else // !CONFIG_KERN_PREEMPT - /* Initialize process stack frame */ - CPU_PUSH_CALL_FRAME(proc->stack, proc_exit); - CPU_PUSH_CALL_FRAME(proc->stack, entry); - - /* Push a clean set of CPU registers for asm_switch_context() */ - for (i = 0; i < CPU_SAVED_REGS_CNT; i++) - CPU_PUSH_WORD(proc->stack, CPU_REG_INIT_VALUE(i)); - - /* Add to ready list */ - ATOMIC(SCHED_ENQUEUE(proc)); - ATOMIC(LIST_ASSERT_VALID(&ProcReadyList)); -#endif // CONFIG_KERN_PREEMPT + #if CONFIG_KERN_PREEMPT + // FIXME: proc_exit + getcontext(&proc->context); + proc->context.uc_stack.ss_sp = stack_base; + proc->context.uc_stack.ss_size = stack_size; + proc->context.uc_link = NULL; + makecontext(&proc->context, (void (*)(void))proc_entry, 1, entry); -#if CONFIG_KERN_MONITOR - monitor_add(proc, name); -#endif + #else // !CONFIG_KERN_PREEMPT + { + size_t i; + + /* Initialize process stack frame */ + CPU_PUSH_CALL_FRAME(proc->stack, proc_exit); + CPU_PUSH_CALL_FRAME(proc->stack, entry); + + /* Push a clean set of CPU registers for asm_switch_context() */ + for (i = 0; i < CPU_SAVED_REGS_CNT; i++) + CPU_PUSH_WORD(proc->stack, CPU_REG_INIT_VALUE(i)); + + /* Add to ready list */ + ATOMIC(SCHED_ENQUEUE(proc)); + ATOMIC(LIST_ASSERT_VALID(&ProcReadyList)); + } + #endif // CONFIG_KERN_PREEMPT + + #if CONFIG_KERN_MONITOR + monitor_add(proc, name); + #endif return proc; } diff --git a/bertos/kern/proc.h b/bertos/kern/proc.h index 00ad4a09..482fb7a3 100644 --- a/bertos/kern/proc.h +++ b/bertos/kern/proc.h @@ -26,15 +26,13 @@ * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. * - * Copyright 2001,2004 Develer S.r.l. (http://www.develer.com/) - * Copyright 1999,2000,2001 Bernie Innocenti - * + * Copyright 2001, 2004 Develer S.r.l. (http://www.develer.com/) + * Copyright 1999, 2000, 2001, 2008 Bernie Innocenti * --> * * \brief Process scheduler (public interface). * * \version $Id$ - * * \author Bernie Innocenti */ #ifndef KERN_PROC_H @@ -142,5 +140,5 @@ void proc_rename(struct Process *proc, const char* name); #error No cpustack_t size supported! #endif #endif -#endif /* KERN_PROC_H */ +#endif /* KERN_PROC_H */ -- 2.25.1