From 908fe1986f478f0a7e1051cb238acf6fbfc0c5d5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 26 Mar 2010 07:40:25 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1778 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ports/GCC/ARM7/chcore.h | 5 +- os/ports/GCC/ARMCMx/chcore.h | 5 +- os/ports/GCC/AVR/chcore.c | 51 ++++++++------ os/ports/GCC/AVR/chcore.h | 152 +++++++++++++++++++++++++++--------------- os/ports/GCC/SIMIA32/chcore.c | 8 +-- os/ports/GCC/SIMIA32/chcore.h | 2 +- 6 files changed, 142 insertions(+), 81 deletions(-) (limited to 'os') diff --git a/os/ports/GCC/ARM7/chcore.h b/os/ports/GCC/ARM7/chcore.h index fe6a2f885..a6cc59d56 100644 --- a/os/ports/GCC/ARM7/chcore.h +++ b/os/ports/GCC/ARM7/chcore.h @@ -102,7 +102,10 @@ struct intctx { #if !defined(__DOXYGEN__) /** - * @brief ATM7 port context structure. + * @brief Platform dependent part of the @p Thread structure. + * @details In the ARM7 port this structure just holds a pointer to the + * @p intctx structure representing the stack pointer at the time + * of the context switch. */ struct context { struct intctx *r13; diff --git a/os/ports/GCC/ARMCMx/chcore.h b/os/ports/GCC/ARMCMx/chcore.h index 4f355ecd0..26838f17b 100644 --- a/os/ports/GCC/ARMCMx/chcore.h +++ b/os/ports/GCC/ARMCMx/chcore.h @@ -121,7 +121,10 @@ struct intctx { #if !defined(__DOXYGEN__) /** - * @brief Cortex-M3 port context structure. + * @brief Platform dependent part of the @p Thread structure. + * @details In the Cortex-Mx port this structure just holds a pointer to the + * @p intctx structure representing the stack pointer at the time + * of the context switch. */ struct context { struct intctx *r13; diff --git a/os/ports/GCC/AVR/chcore.c b/os/ports/GCC/AVR/chcore.c index 8242f7b1c..f84e6aed1 100644 --- a/os/ports/GCC/AVR/chcore.c +++ b/os/ports/GCC/AVR/chcore.c @@ -18,8 +18,9 @@ */ /** - * @file AVR/chcore.c - * @brief AVR architecture port code. + * @file AVR/chcore.c + * @brief AVR architecture port code. + * * @addtogroup AVR_CORE * @{ */ @@ -27,16 +28,21 @@ #include "ch.h" /** - * Performs a context switch between two threads. - * @param otp the thread to be switched out - * @param ntp the thread to be switched in - * @note The function is declared as a weak symbol, it is possible to redefine - * it in your application code. + * @brief Performs a context switch between two threads. + * @details This is the most critical code in any port, this function + * is responsible for the context switch between 2 threads. + * @note The implementation of this code affects directly the context + * switch performance so optimize here as much as you can. + * @note The function is declared as a weak symbol, it is possible to + * redefine it in your application code. + * + * @param[in] ntp the thread to be switched in + * @param[in] otp the thread to be switched out */ -/** @cond never */ +#if !defined(__DOXYGEN__) __attribute__((naked, weak)) -/** @endcond */ -void port_switch(Thread *otp, Thread *ntp) { +#endif +void port_switch(Thread *ntp, Thread *otp) { asm volatile ("push r2"); asm volatile ("push r3"); @@ -59,13 +65,13 @@ void port_switch(Thread *otp, Thread *ntp) { asm volatile ("push r28"); asm volatile ("push r29"); - asm volatile ("movw r30, r24"); + asm volatile ("movw r30, r22"); asm volatile ("in r0, 0x3d"); asm volatile ("std Z+6, r0"); asm volatile ("in r0, 0x3e"); asm volatile ("std Z+7, r0"); - asm volatile ("movw r30, r22"); + asm volatile ("movw r30, r24"); asm volatile ("ldd r0, Z+6"); asm volatile ("out 0x3d, r0"); asm volatile ("ldd r0, Z+7"); @@ -95,13 +101,17 @@ void port_switch(Thread *otp, Thread *ntp) { } /** - * Disables the interrupts and halts the system. - * @note The function is declared as a weak symbol, it is possible to redefine - * it in your application code. + * @brief Halts the system. + * @details 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). + * @note The function is declared as a weak symbol, it is possible to + * redefine it in your application code. */ -/** @cond never */ +#if !defined(__DOXYGEN__) __attribute__((weak)) -/** @endcond */ +#endif void port_halt(void) { port_disable(); @@ -110,10 +120,11 @@ void port_halt(void) { } /** - * Start a thread by invoking its work function. - * If the work function returns @p chThdExit() is automatically invoked. + * @brief Start a thread by invoking its work function. + * @details If the work function returns @p chThdExit() is automatically + * invoked. */ -void threadstart(void) { +void _port_thread_start(void) { asm volatile ("sei"); asm volatile ("movw r24, r4"); diff --git a/os/ports/GCC/AVR/chcore.h b/os/ports/GCC/AVR/chcore.h index 8507ed752..047fd1a9d 100644 --- a/os/ports/GCC/AVR/chcore.h +++ b/os/ports/GCC/AVR/chcore.h @@ -18,8 +18,9 @@ */ /** - * @file AVR/chcore.h - * @brief AVR architecture port macros and structures. + * @file AVR/chcore.h + * @brief AVR architecture port macros and structures. + * * @addtogroup AVR_CORE * @{ */ @@ -31,19 +32,19 @@ #include /** - * If enabled allows the idle thread to enter a low power mode. + * @brief If enabled allows the idle thread to enter a low power mode. */ #ifndef ENABLE_WFI_IDLE #define ENABLE_WFI_IDLE 0 #endif /** - * Macro defining the AVR architecture. + * @brief Macro defining the AVR architecture. */ #define CH_ARCHITECTURE_AVR /** - * Name of the implemented architecture. + * @brief Name of the implemented architecture. */ #define CH_ARCHITECTURE_NAME "AVR" @@ -53,15 +54,17 @@ #define CH_CORE_VARIANT_NAME "MegaAVR" /** - * 8 bit stack alignment. + * @brief 8 bits stack and memory alignment enforcement. */ typedef uint8_t stkalign_t; -/** @cond never */ +#if !defined(__DOXYGEN__) /** - * Interrupt saved context. - * @note The field @p _next is not part of the context, it represents the - * offset of the structure relative to the stack pointer. + * @brief Interrupt saved context. + * @details This structure represents the stack frame saved during a + * preemption-capable interrupt handler. + * @note The field @p _next is not part of the context, it represents the + * offset of the structure relative to the stack pointer. */ struct extctx { uint8_t _next; @@ -82,13 +85,15 @@ struct extctx { uint8_t r0; uint16_t pc; }; -/** @endcond */ +#endif -/** @cond never */ +#if !defined(__DOXYGEN__) /** - * System saved context. - * @note The field @p _next is not part of the context, it represents the - * offset of the structure relative to the stack pointer. + * @brief System saved context. + * @details This structure represents the inner stack frame during a context + * switching. + * @note The field @p _next is not part of the context, it represents the + * offset of the structure relative to the stack pointer. */ struct intctx { uint8_t _next; @@ -115,22 +120,24 @@ struct intctx { uint8_t pcl; uint8_t pch; }; -/** @endcond */ +#endif -/** @cond never */ +#if !defined(__DOXYGEN__) /** - * In the AVR port this structure just holds a pointer to the @p intctx - * structure representing the stack pointer at the time of the context switch. + * @brief Platform dependent part of the @p Thread structure. + * @details In the AVR port this structure just holds a pointer to the + * @p intctx structure representing the stack pointer at the time + * of the context switch. */ struct context { struct intctx *sp; }; -/** @endcond */ +#endif /** - * Platform dependent part of the @p chThdInit() API. - * This code usually setup the context switching frame represented by a - * @p intctx structure. + * @brief Platform dependent part of the @p chThdInit() API. + * @details This code usually setup the context switching frame represented + * by an @p intctx structure. */ #define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ tp->p_ctx.sp = (struct intctx*)((uint8_t *)workspace + wsize - \ @@ -139,34 +146,41 @@ struct context { tp->p_ctx.sp->r3 = (int)pf >> 8; \ tp->p_ctx.sp->r4 = (int)arg; \ tp->p_ctx.sp->r5 = (int)arg >> 8; \ - tp->p_ctx.sp->pcl = (int)threadstart >> 8; \ - tp->p_ctx.sp->pch = (int)threadstart; \ + tp->p_ctx.sp->pcl = (int)_port_thread_start >> 8; \ + tp->p_ctx.sp->pch = (int)_port_thread_start; \ } /** - * The default idle thread implementation requires no extra stack space in - * this port. + * @brief Stack size for the system idle thread. + * @details This size depends on the idle thread implementation, usually + * the idle thread should take no more space than those reserved + * by @p INT_REQUIRED_STACK. + * @note In this port it is set to 8. */ #ifndef IDLE_THREAD_STACK_SIZE #define IDLE_THREAD_STACK_SIZE 8 #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. + * @brief Per-thread stack overhead for interrupts servicing. + * @details This constant is used in the calculation of the correct working + * area size. + * This value can be zero on those architecture where there is a + * separate interrupt stack and the stack space between @p intctx and + * @p extctx is known to be zero. + * @note 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. + * @brief Enforces a correct alignment for a stack area size value. */ #define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1) /** - * Computes the thread working area global size. + * @brief Computes the thread working area global size. */ #define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ (sizeof(struct intctx) - 1) + \ @@ -174,16 +188,18 @@ struct context { (n) + (INT_REQUIRED_STACK)) /** - * Macro used to allocate a thread working area aligned as both position and - * size. + * @brief Static working area allocation. + * @details This macro is used to allocate a static thread working area + * aligned as both position and size. */ #define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]; /** - * IRQ prologue code, inserted at the start of all IRQ handlers enabled to - * invoke system APIs. - * This code tricks the compiler to save all the specified registers by - * "touching" them. + * @brief IRQ prologue code. + * @details This macro must be inserted at the start of all IRQ handlers + * enabled to invoke system APIs. + * @note This code tricks the compiler to save all the specified registers + * by "touching" them. */ #define PORT_IRQ_PROLOGUE() { \ asm ("" : : : "r18", "r19", "r20", "r21", "r22", "r23", "r24", \ @@ -191,8 +207,9 @@ struct context { } /** - * IRQ epilogue code, inserted at the end of all IRQ handlers enabled to - * invoke system APIs. + * @brief IRQ epilogue code. + * @details This macro must be inserted at the end of all IRQ handlers + * enabled to invoke system APIs. */ #define PORT_IRQ_EPILOGUE() { \ if (chSchIsRescRequiredExI()) \ @@ -200,54 +217,81 @@ struct context { } /** - * IRQ handler function declaration. Note, it just aliases the WinAVR "ISR" - * macro. + * @brief IRQ handler function declaration. + * @note @p id can be a function name or a vector number depending on the + * port implementation. */ #define PORT_IRQ_HANDLER(id) ISR(id) /** - * This function is empty in this port. + * @brief Port-related initialization code. + * @note This function is empty in this port. */ #define port_init() /** - * Implemented as global interrupt disable. + * @brief Kernel-lock action. + * @details Usually this function just disables interrupts but may perform more + * actions. + * @note Implemented as global interrupt disable. */ #define port_lock() asm volatile ("cli") /** - * Implemented as global interrupt enable. + * @brief Kernel-unlock action. + * @details Usually this function just disables interrupts but may perform more + * actions. + * @note Implemented as global interrupt enable. */ #define port_unlock() asm volatile ("sei") /** - * This function is empty in this port. + * @brief Kernel-lock action from an interrupt handler. + * @details This function is invoked before invoking I-class APIs from + * interrupt handlers. The implementation is architecture dependent, + * in its simplest form it is void. + * @note This function is empty in this port. */ #define port_lock_from_isr() /** - * This function is empty in this port. + * @brief Kernel-unlock action from an interrupt handler. + * @details This function is invoked after invoking I-class APIs from interrupt + * handlers. The implementation is architecture dependent, in its + * simplest form it is void. + * @note This function is empty in this port. */ #define port_unlock_from_isr() /** - * Implemented as global interrupt disable. + * @brief Disables all the interrupt sources. + * @note Of course non maskable interrupt sources are not included. + * @note Implemented as global interrupt disable. */ #define port_disable() asm volatile ("cli") /** - * Same as @p port_disable() in this port, there is no difference between the - * two states. + * @brief Disables the interrupt sources below kernel-level priority. + * @note Interrupt sources above kernel level remains enabled. + * @note Same as @p port_disable() in this port, there is no difference + * between the two states. */ #define port_suspend() asm volatile ("cli") /** - * Implemented as global interrupt enable. + * @brief Enables all the interrupt sources. + * @note Implemented as global interrupt enable. */ #define port_enable() asm volatile ("sei") /** - * This port function is implemented as inlined code for performance reasons. + * @brief Enters an architecture-dependent IRQ-waiting mode. + * @details The function is meant to return when an interrupt becomes pending. + * The simplest implementation is an empty function or macro but this + * would not take advantage of architecture-specific power saving + * modes. + * @note This port function is implemented as inlined code for performance + * reasons. */ #if ENABLE_WFI_IDLE != 0 #define port_wait_for_interrupt() { \ @@ -260,9 +304,9 @@ struct context { #ifdef __cplusplus extern "C" { #endif - void port_switch(Thread *otp, Thread *ntp); + void port_switch(Thread *ntp, Thread *otp); void port_halt(void); - void threadstart(void); + void _port_thread_start(void); #ifdef __cplusplus } #endif diff --git a/os/ports/GCC/SIMIA32/chcore.c b/os/ports/GCC/SIMIA32/chcore.c index 56073bb50..e2531cd4e 100644 --- a/os/ports/GCC/SIMIA32/chcore.c +++ b/os/ports/GCC/SIMIA32/chcore.c @@ -33,8 +33,8 @@ * @param ntp the thread to be switched in */ __attribute__((used)) -static void __dummy(Thread *otp, Thread *ntp) { - (void)otp; (void)ntp; +static void __dummy(Thread *ntp, Thread *otp) { + (void)ntp; (void)otp; #if defined(WIN32) asm volatile (".globl @port_switch@8 \n\t" \ "@port_switch@8:"); @@ -49,8 +49,8 @@ static void __dummy(Thread *otp, Thread *ntp) { "push %esi \n\t" \ "push %edi \n\t" \ "push %ebx \n\t" \ - "movl %esp, 12(%ecx) \n\t" \ - "movl 12(%edx), %esp \n\t" \ + "movl %esp, 12(%edx) \n\t" \ + "movl 12(%ecx), %esp \n\t" \ "pop %ebx \n\t" \ "pop %edi \n\t" \ "pop %esi \n\t" \ diff --git a/os/ports/GCC/SIMIA32/chcore.h b/os/ports/GCC/SIMIA32/chcore.h index 2e5175c70..aa5e5a5ae 100644 --- a/os/ports/GCC/SIMIA32/chcore.h +++ b/os/ports/GCC/SIMIA32/chcore.h @@ -207,7 +207,7 @@ struct context { #ifdef __cplusplus extern "C" { #endif - __attribute__((fastcall)) void port_switch(Thread *otp, Thread *ntp); + __attribute__((fastcall)) void port_switch(Thread *ntp, Thread *otp); __attribute__((fastcall)) void port_halt(void); void threadexit(void); void ChkIntSources(void); -- cgit v1.2.3