From a07bd21d4427c9f254aae8f6da10dabdaedea43e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 9 Jan 2009 10:48:30 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@594 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- ports/ARMCM3/chcore.c | 2 +- ports/MSP430/chcore.c | 71 +++++++---------------------- ports/MSP430/chcore.h | 119 +++++++++++++++++++++++++++++++++++++++++-------- src/templates/chcore.c | 39 +++++++++++++++- 4 files changed, 155 insertions(+), 76 deletions(-) diff --git a/ports/ARMCM3/chcore.c b/ports/ARMCM3/chcore.c index 7110035f1..6b4811904 100644 --- a/ports/ARMCM3/chcore.c +++ b/ports/ARMCM3/chcore.c @@ -39,7 +39,7 @@ void sys_puts(char *msg) { void sys_halt(void) { asm volatile ("cpsid i"); - while(TRUE) { + while (TRUE) { } } diff --git a/ports/MSP430/chcore.c b/ports/MSP430/chcore.c index dc340f9c9..e9a5dc574 100644 --- a/ports/MSP430/chcore.c +++ b/ports/MSP430/chcore.c @@ -17,70 +17,31 @@ along with this program. If not, see . */ -#include - -/** - * This function implements the idle thread infinite loop. The function should - * put the processor in the lowest power mode capable to serve interrupts. - * The priority is internally set to the minimum system value so that this - * thread is executed only if there are no other ready threads in the system. - */ -void _idle(void *p) { - - while (TRUE) - ; -} - /** - * Abonormal system termination handler. Invoked by the ChibiOS/RT when an - * abnormal unrecoverable condition is met. + * @addtogroup MSP430_CORE + * @{ */ -void chSysHalt(void) { - - chSysLock(); - while (TRUE) - ; -} +#include -/** - * Context switch. +/* + * This file is a template of the system driver functions provided by a port. + * Some of the following functions may be implemented as macros in chcore.h if + * the implementer decides that there is an advantage in doing so, as example + * because performance concerns. */ -__attribute__((naked)) -void chSysSwitchI(Thread *otp, Thread *ntp) { - register struct intctx *sp asm("r1"); - asm volatile ("push r11 \n\t" \ - "push r10 \n\t" \ - "push r9 \n\t" \ - "push r8 \n\t" \ - "push r7 \n\t" \ - "push r6 \n\t" \ - "push r6 \n\t" \ - "push r4"); - otp->p_ctx.sp = sp; - sp = ntp->p_ctx.sp; - asm volatile ("pop r4 \n\t" \ - "pop r5 \n\t" \ - "pop r6 \n\t" \ - "pop r7 \n\t" \ - "pop r8 \n\t" \ - "pop r9 \n\t" \ - "pop r10 \n\t" \ - "pop r11 \n\t" \ - "ret" : : "r" (sp)); +void sys_puts(char *msg) { } -/** - * Prints a message on the system console (if any). - */ -void chSysPuts(char *msg) { +void sys_switch(Thread *otp, Thread *ntp) { } -void threadstart(void) { +void sys_halt(void) { - asm volatile ("eint \n\t" \ - "mov r11, r15 \n\t" \ - "call r10 \n\t" \ - "call #chThdExit"); + sys_disable(); + while (TRUE) { + } } + +/** @} */ diff --git a/ports/MSP430/chcore.h b/ports/MSP430/chcore.h index bf8e0d82d..db0d25f77 100644 --- a/ports/MSP430/chcore.h +++ b/ports/MSP430/chcore.h @@ -17,6 +17,11 @@ along with this program. If not, see . */ +/** + * @addtogroup MSP430_CORE + * @{ + */ + #ifndef _CHCORE_H_ #define _CHCORE_H_ @@ -24,21 +29,28 @@ #include /* + * Port-related configuration parameters. + */ +#ifndef ENABLE_WFI_IDLE +#define ENABLE_WFI_IDLE 0 /* Enables the use of the WFI ins. */ +#endif + +/** * Macro defining the MSP430 architecture. */ #define CH_ARCHITECTURE_MSP430 -/* +/** * 16 bit stack alignment. */ typedef uint16_t stkalign_t; -/* +/** * Generic MSP430 register. */ typedef void *regmsp_t; -/* +/** * Interrupt saved context. */ struct extctx { @@ -50,8 +62,9 @@ struct extctx { regmsp_t pc; }; -/* +/** * System saved context. + * This structure represents the inner stack frame during a context switching. */ struct intctx { regmsp_t r4; @@ -62,14 +75,21 @@ struct intctx { regmsp_t r9; regmsp_t r10; regmsp_t r11; -// regmsp_t sr; regmsp_t pc; }; +/** + * Platform dependent part of the @p Thread structure. + * In the MSP430 port this structure just holds a pointer to the @p intctx + * structure representing the stack pointer at the time of the context switch. + */ typedef struct { struct intctx *sp; } Context; +/** + * Platform dependent part of the @p chThdInit() API. + */ #define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ tp->p_ctx.sp = (struct intctx *)((uint8_t *)workspace + \ wsize - \ @@ -79,42 +99,103 @@ typedef struct { tp->p_ctx.sp->pc = threadstart; \ } +/** + * The default idle thread implementation requires no extra stack space in + * this port. + */ +#ifndef IDLE_THREAD_STACK_SIZE #define IDLE_THREAD_STACK_SIZE 0 +#endif +/** + * Per-thread stack overhead for interrupts servicing, it is used in the + * calculation of the correct working area size. In this port the default is + * 32 bytes per thread. + */ #ifndef INT_REQUIRED_STACK #define INT_REQUIRED_STACK 32 #endif +/** + * Enforces a correct alignment for a stack area size value. + */ #define STACK_ALIGN(n) ((((n) - 1) | sizeof(stkalign_t)) + 1) + /** + * Computes the thread working area global size. + */ #define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ sizeof(struct intctx) + \ sizeof(struct extctx) + \ - (n) + \ - INT_REQUIRED_STACK) + (n) + (INT_REQUIRED_STACK)) +/** + * Macro used to allocate a thread working area aligned as both position and + * size. + */ #define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]; -#define chSysLock() asm volatile ("dint") -#define chSysUnlock() asm volatile ("eint") -#define chSysEnable() asm volatile ("eint") +/** + * IRQ prologue code, inserted at the start of all IRQ handlers enabled to + * invoke system APIs. + */ +#define SYS_IRQ_PROLOGUE() -#define chSysIRQEnterI() -#define chSysIRQExitI() { \ - if (chSchRescRequiredI()) \ - chSchDoRescheduleI(); \ +/** + * IRQ epilogue code, inserted at the end of all IRQ handlers enabled to + * invoke system APIs. + */ +#define SYS_IRQ_EPILOGUE() { \ +if (chSchRescRequiredI()) \ + chSchDoRescheduleI(); \ +} + +/** + * This port function is implemented as inlined code for performance reasons. + */ +#define sys_disable() asm volatile ("dint") + +/** + * This port function is implemented as inlined code for performance reasons. + */ +#define sys_enable() asm volatile ("eint") + +/** + * This port function is implemented as inlined code for performance reasons. + */ +#define sys_disable_from_isr() sys_disable() + +/** + * This port function is implemented as inlined code for performance reasons. + */ +#define sys_enable_from_isr() sys_enable() + +#if ENABLE_WFI_IDLE != 0 +/** + * This port function is implemented as inlined code for performance reasons. + */ +#define sys_wait_for_interrupt() { \ + asm volatile ("wfi"); \ } +#else +#define sys_wait_for_interrupt() +#endif + +/** + * IRQ handler function modifier. + */ +#define SYS_IRQ_HANDLER #ifdef __cplusplus extern "C" { #endif - void _idle(void *p) __attribute__((weak, noreturn)); - void chSysHalt(void); - void chSysSwitchI(Thread *otp, Thread *ntp); - void chSysPuts(char *msg); - void threadstart(void); + void sys_puts(char *msg); + void sys_switch(Thread *otp, Thread *ntp); + void sys_halt(void); #ifdef __cplusplus } #endif #endif /* _CHCORE_H_ */ + +/** @} */ diff --git a/src/templates/chcore.c b/src/templates/chcore.c index 06e584089..65d8e155d 100644 --- a/src/templates/chcore.c +++ b/src/templates/chcore.c @@ -31,30 +31,67 @@ * because performance concerns. */ +/** + * Prints a message on the system console. + * @param msg pointer to the message + */ void sys_puts(char *msg) { } +/** + * Performs a context switch between two threads. + * @param otp the thread to be switched out + * @param ntp the thread to be switched in + */ void sys_switch(Thread *otp, Thread *ntp) { } +/** + * Kernel-unlock action. Usually this function just enables interrupts. + */ void sys_enable(void) { } +/** + * Kernel-lock action. Usually this function just disables interrupts. + */ void sys_disable(void) { } +/** + * Kernel-lock action from an interrupt handler. This function is invoked + * before invoking I-class APIs from interrupt handlers. The implementation + * is architecture dependent, in its simplest form it is void. + */ void sys_disable_from_isr(void) { } +/** + * Kernel-unlock action from an interrupt handler. This function is invoked + * after invoking I-class APIs from interrupt handlers. The implementation + * is architecture dependent, in its simplest form it is void. + */ void sys_enable_from_isr(void) { } +/** + * Enters an architecture-dependent halt mode. The function is meant to return + * when an interrupt becomes pending. The simplest implementation is an empty + * function but this will not take advantage of architecture-specific power + * saving modes. + */ void sys_wait_for_interrupt(void) { } +/** + * Halts the system. This function is invoked by the operating system when an + * unrecoverable error is detected (as example because a programming error in + * the application code that triggers an assertion while in debug mode). + */ void sys_halt(void) { - while(TRUE) { + sys_disable(); + while (TRUE) { } } -- cgit v1.2.3