ChibiOS/RT
2.6.0
chcore.h
Go to the documentation of this file.
00001 /*
00002     ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
00003                  2011,2012,2013 Giovanni Di Sirio.
00004 
00005     This file is part of ChibiOS/RT.
00006 
00007     ChibiOS/RT is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     ChibiOS/RT is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 
00020                                       ---
00021 
00022     A special exception to the GPL can be applied should you wish to distribute
00023     a combined work that includes ChibiOS/RT, without being obliged to provide
00024     the source code for any proprietary components. See the file exception.txt
00025     for full details of how and when the exception can be applied.
00026 */
00027 
00028 /**
00029  * @file    MSP430/chcore.h
00030  * @brief   MSP430 architecture port macros and structures.
00031  *
00032  * @addtogroup MSP430_CORE
00033  * @{
00034  */
00035 
00036 #ifndef _CHCORE_H_
00037 #define _CHCORE_H_
00038 
00039 #include <iomacros.h>
00040 #include <isr_compat.h>
00041 
00042 #if CH_DBG_ENABLE_STACK_CHECK
00043 #error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port"
00044 #endif
00045 
00046 /**
00047  * @brief   Enables the use of a wait state in the idle thread loop.
00048  */
00049 #ifndef ENABLE_WFI_IDLE
00050 #define ENABLE_WFI_IDLE                 0
00051 #endif
00052 
00053 /**
00054  * @brief   Macro defining the MSP430 architecture.
00055  */
00056 #define CH_ARCHITECTURE_MSP430
00057 
00058 /**
00059  * @brief   Name of the implemented architecture.
00060  */
00061 #define CH_ARCHITECTURE_NAME            "MSP430"
00062 
00063 /**
00064  * @brief   Name of the architecture variant (optional).
00065  */
00066 #define CH_CORE_VARIANT_NAME            "MSP430"
00067 
00068 /**
00069  * @brief   Name of the compiler supported by this port.
00070  */
00071 #define CH_COMPILER_NAME                "GCC " __VERSION__
00072 
00073 /**
00074  * @brief   Port-specific information string.
00075  */
00076 #define CH_PORT_INFO                    "None"
00077 
00078 /**
00079  * @brief   16 bits stack and memory alignment enforcement.
00080  */
00081 typedef uint16_t stkalign_t;
00082 
00083 /**
00084  * @brief   Generic MSP430 register.
00085  */
00086 typedef void *regmsp_t;
00087 
00088 /**
00089  * @brief   Interrupt saved context.
00090  * @details This structure represents the stack frame saved during a
00091  *          preemption-capable interrupt handler.
00092  */
00093 struct extctx {
00094   regmsp_t      r12;
00095   regmsp_t      r13;
00096   regmsp_t      r14;
00097   regmsp_t      r15;
00098   regmsp_t      sr;
00099   regmsp_t      pc;
00100 };
00101 
00102 /**
00103  * @brief   System saved context.
00104  * @details This structure represents the inner stack frame during a context
00105  *          switching.
00106  */
00107 struct intctx {
00108   regmsp_t      r4;
00109   regmsp_t      r5;
00110   regmsp_t      r6;
00111   regmsp_t      r7;
00112   regmsp_t      r8;
00113   regmsp_t      r9;
00114   regmsp_t      r10;
00115   regmsp_t      r11;
00116   regmsp_t      pc;
00117 };
00118 
00119 /**
00120  * @brief   Platform dependent part of the @p Thread structure.
00121  * @details This structure usually contains just the saved stack pointer
00122  *          defined as a pointer to a @p intctx structure.
00123  */
00124 struct context {
00125   struct intctx *sp;
00126 };
00127 
00128 /**
00129  * @brief   Platform dependent part of the @p chThdCreateI() API.
00130  * @details This code usually setup the context switching frame represented
00131  *          by an @p intctx structure.
00132  */
00133 #define SETUP_CONTEXT(workspace, wsize, pf, arg) {                          \
00134   tp->p_ctx.sp = (struct intctx *)((uint8_t *)workspace +                   \
00135                                    wsize -                                  \
00136                                    sizeof(struct intctx));                  \
00137   tp->p_ctx.sp->r10 = pf;                                                   \
00138   tp->p_ctx.sp->r11 = arg;                                                  \
00139   tp->p_ctx.sp->pc = _port_thread_start;                                    \
00140 }
00141 
00142 /**
00143  * @brief   Stack size for the system idle thread.
00144  * @details This size depends on the idle thread implementation, usually
00145  *          the idle thread should take no more space than those reserved
00146  *          by @p PORT_INT_REQUIRED_STACK.
00147  */
00148 #ifndef PORT_IDLE_THREAD_STACK_SIZE
00149 #define PORT_IDLE_THREAD_STACK_SIZE     0
00150 #endif
00151 
00152 /**
00153  * @brief   Per-thread stack overhead for interrupts servicing.
00154  * @details This constant is used in the calculation of the correct working
00155  *          area size.
00156  *          This value can be zero on those architecture where there is a
00157  *          separate interrupt stack and the stack space between @p intctx and
00158  *          @p extctx is known to be zero.
00159  * @note    In this port the default is 32 bytes per thread.
00160  */
00161 #ifndef PORT_INT_REQUIRED_STACK
00162 #define PORT_INT_REQUIRED_STACK         32
00163 #endif
00164 
00165 /**
00166  * @brief   Enforces a correct alignment for a stack area size value.
00167  */
00168 #define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1)
00169 
00170 /**
00171  * @brief   Computes the thread working area global size.
00172  */
00173 #define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) +                         \
00174                                    sizeof(struct intctx) +                  \
00175                                    sizeof(struct extctx) +                  \
00176                                    (n) + (PORT_INT_REQUIRED_STACK))
00177 
00178 /**
00179  * @brief   Static working area allocation.
00180  * @details This macro is used to allocate a static thread working area
00181  *          aligned as both position and size.
00182  */
00183 #define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)]
00184 
00185 /**
00186  * @brief   IRQ prologue code.
00187  * @details This macro must be inserted at the start of all IRQ handlers
00188  *          enabled to invoke system APIs.
00189  */
00190 #define PORT_IRQ_PROLOGUE()
00191 
00192 /**
00193  * @brief   IRQ epilogue code.
00194  * @details This macro must be inserted at the end of all IRQ handlers
00195  *          enabled to invoke system APIs.
00196  */
00197 #define PORT_IRQ_EPILOGUE() {                                               \
00198   dbg_check_lock();                                                         \
00199   if (chSchIsPreemptionRequired())                                          \
00200     chSchDoReschedule();                                                    \
00201   dbg_check_unlock();                                                       \
00202 }
00203 
00204 #define ISRNAME(pre, id) pre##id
00205 
00206 /**
00207  * @brief   IRQ handler function declaration.
00208  * @note    @p id can be a function name or a vector number depending on the
00209  *          port implementation.
00210  */
00211 #define PORT_IRQ_HANDLER(id) ISR(id, ISRNAME(vect, id))
00212 
00213 /**
00214  * @brief   Port-related initialization code.
00215  * @note    This function is empty in this port.
00216  */
00217 #define port_init()
00218 
00219 /**
00220  * @brief   Kernel-lock action.
00221  * @details Usually this function just disables interrupts but may perform more
00222  *          actions.
00223  * @note    Implemented as global interrupt disable.
00224  */
00225 #define port_lock() asm volatile ("dint" : : : "memory")
00226 
00227 /**
00228  * @brief   Kernel-unlock action.
00229  * @details Usually this function just enables interrupts but may perform more
00230  *          actions.
00231  * @note    Implemented as global interrupt enable.
00232  */
00233 #define port_unlock() asm volatile ("eint" : : : "memory")
00234 
00235 /**
00236  * @brief   Kernel-lock action from an interrupt handler.
00237  * @details This function is invoked before invoking I-class APIs from
00238  *          interrupt handlers. The implementation is architecture dependen#define PORT_IRQ_EPILOGUE() {                                           \
00239   if (chSchIsPreemptionRequired())                                      \
00240     chSchDoReschedule();                                                \
00241 }
00242  *          t,
00243  *          in its simplest form it is void.
00244  * @note    This function is empty in this port.
00245  */
00246 #define port_lock_from_isr()
00247 
00248 /**
00249  * @brief   Kernel-unlock action from an interrupt handler.
00250  * @details This function is invoked after invoking I-class APIs from interrupt
00251  *          handlers. The implementation is architecture dependent, in its
00252  *          simplest form it is void.
00253  * @note    This function is empty in this port.
00254  */
00255 #define port_unlock_from_isr()
00256 
00257 /**
00258  * @brief   Disables all the interrupt sources.
00259  * @note    Of course non-maskable interrupt sources are not included.
00260  * @note    Implemented as global interrupt disable.
00261  */
00262 #define port_disable() asm volatile ("dint" : : : "memory")
00263 
00264 /**
00265  * @brief   Disables the interrupt sources below kernel-level priority.
00266  * @note    Interrupt sources above kernel level remains enabled.
00267  * @note    Same as @p port_disable() in this port, there is no difference
00268  *          between the two states.
00269  */
00270 #define port_suspend() asm volatile ("dint" : : : "memory")
00271 
00272 /**
00273  * @brief   Enables all the interrupt sources.
00274  * @note    Implemented as global interrupt enable.
00275  */
00276 #define port_enable() asm volatile ("eint" : : : "memory")
00277 
00278 /**
00279  * @brief   Enters an architecture-dependent IRQ-waiting mode.
00280  * @details The function is meant to return when an interrupt becomes pending.
00281  *          The simplest implementation is an empty function or macro but this
00282  *          would not take advantage of architecture-specific power saving
00283  *          modes.
00284  * @note    This port function is implemented as inlined code for performance
00285  *          reasons.
00286  * @note    The port code does not define a low power mode, this macro has to
00287  *          be defined externally. The default implementation is a "nop", not
00288  *          a real low power mode.
00289  */
00290 #if ENABLE_WFI_IDLE != 0
00291 #ifndef port_wait_for_interrupt
00292 #define port_wait_for_interrupt() {                                         \
00293   asm volatile ("nop" : : : "memory");                                      \
00294 }
00295 #endif
00296 #else
00297 #define port_wait_for_interrupt()
00298 #endif
00299 
00300 /**
00301  * @brief   Wrapper of the assembler @p _port_switch() function.
00302  */
00303 #define port_switch(ntp, otp) _port_switch(ntp, otp)
00304 
00305 /**
00306  * @brief   Wrapper of the assembler @p _port_halt() function.
00307  */
00308 #define port_halt() _port_halt()
00309 
00310 #ifdef __cplusplus
00311 extern "C" {
00312 #endif
00313   void _port_switch(Thread *ntp, Thread *otp);
00314   void _port_halt(void);
00315   void _port_thread_start(void);
00316 #ifdef __cplusplus
00317 }
00318 #endif
00319 
00320 #endif /* _CHCORE_H_ */
00321 
00322 /** @} */