|
ChibiOS/RT
2.6.0 |
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 /** @} */