|
ChibiOS/RT
2.5.1 |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, 00003 2011,2012 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 * @file RC/STM8/chcore.h 00023 * @brief STM8 (Raisonance) architecture port macros and structures. 00024 * 00025 * @addtogroup STM8_RAISONANCE_CORE 00026 * @{ 00027 */ 00028 00029 #ifndef _CHCORE_H_ 00030 #define _CHCORE_H_ 00031 00032 #include <intrins.h> 00033 00034 #if CH_DBG_ENABLE_STACK_CHECK 00035 #error "option CH_DBG_ENABLE_STACK_CHECK not supported by this port" 00036 #endif 00037 00038 /*===========================================================================*/ 00039 /* Port configurable parameters. */ 00040 /*===========================================================================*/ 00041 00042 /** 00043 * @brief Enables the use of the WFI instruction in the idle thread loop. 00044 */ 00045 #ifndef STM8_ENABLE_WFI_IDLE 00046 #define STM8_ENABLE_WFI_IDLE FALSE 00047 #endif 00048 00049 /*===========================================================================*/ 00050 /* Port exported info. */ 00051 /*===========================================================================*/ 00052 00053 /** 00054 * @brief Unique macro for the implemented architecture. 00055 */ 00056 #define CH_ARCHITECTURE_STM8 00057 00058 /** 00059 * @brief Name of the implemented architecture. 00060 */ 00061 #define CH_ARCHITECTURE_NAME "STM8" 00062 00063 /** 00064 * @brief Name of the compiler supported by this port. 00065 */ 00066 #define CH_COMPILER_NAME "Raisonance" 00067 00068 /** 00069 * @brief Port-specific information string. 00070 */ 00071 #define CH_PORT_INFO "None" 00072 00073 /*===========================================================================*/ 00074 /* Port implementation part. */ 00075 /*===========================================================================*/ 00076 00077 /** 00078 * @brief Base type for stack alignment. 00079 * @note No alignment constraints so uint8_t. 00080 */ 00081 typedef uint8_t stkalign_t; 00082 00083 /** 00084 * @brief Generic STM8 function pointer. 00085 * @note It is used to allocate the proper size for return addresses in 00086 * context-related structures. 00087 */ 00088 typedef void (*stm8func_t)(void); 00089 00090 /** 00091 * @brief Interrupt saved context. 00092 * @details This structure represents the stack frame saved during a 00093 * preemption-capable interrupt handler. 00094 * @note The structure requires one dummy field at its start because the 00095 * stack is handled as preincremented/postdecremented. 00096 */ 00097 struct extctx { 00098 uint8_t _next; 00099 uint16_t cx; 00100 uint16_t bx; 00101 uint8_t cc; 00102 uint8_t a; 00103 uint16_t x; 00104 uint16_t y; 00105 uint8_t pce; 00106 uint8_t pch; 00107 uint8_t pcl; 00108 }; 00109 00110 /** 00111 * @brief System saved context. 00112 * @details This structure represents the inner stack frame during a context 00113 * switching.. 00114 * @note The structure requires one dummy field at its start because the 00115 * stack is handled as preincremented/postdecremented. 00116 */ 00117 struct intctx { 00118 uint8_t _next; 00119 stm8func_t pc; /* Function pointer sized return address. */ 00120 }; 00121 00122 /** 00123 * @brief Platform dependent part of the @p Thread structure. 00124 * @details This structure usually contains just the saved stack pointer 00125 * defined as a pointer to a @p intctx structure. 00126 */ 00127 struct context { 00128 struct intctx *sp; 00129 }; 00130 00131 /** 00132 * @brief Start context. 00133 * @details This context is the stack organization for the trampoline code 00134 * @p _port_thread_start(). 00135 */ 00136 struct stm8_startctx { 00137 uint8_t _next; 00138 stm8func_t ts; /* Trampoline address. */ 00139 void *arg; /* Thread argument. */ 00140 stm8func_t pc; /* Thread function address. */ 00141 stm8func_t ret; /* chThdExit() address. */ 00142 }; 00143 00144 /** 00145 * @brief Platform dependent part of the @p chThdCreateI() API. 00146 * @details This code usually setup the context switching frame represented 00147 * by an @p intctx structure. 00148 */ 00149 #define SETUP_CONTEXT(workspace, wsize, pf, arg) { \ 00150 struct stm8_startctx *scp; \ 00151 scp = (struct stm8_startctx *)((uint8_t *)workspace + wsize - \ 00152 sizeof(struct stm8_startctx)); \ 00153 scp->ts = _port_thread_start; \ 00154 scp->arg = arg; \ 00155 scp->pc = (stm8func_t)pf; \ 00156 scp->ret = (stm8func_t)chThdExit; \ 00157 tp->p_ctx.sp = (struct intctx *)scp; \ 00158 } 00159 00160 /** 00161 * @brief Stack size for the system idle thread. 00162 * @details This size depends on the idle thread implementation, usually 00163 * the idle thread should take no more space than those reserved 00164 * by @p PORT_INT_REQUIRED_STACK. 00165 */ 00166 #ifndef PORT_IDLE_THREAD_STACK_SIZE 00167 #define PORT_IDLE_THREAD_STACK_SIZE 0 00168 #endif 00169 00170 /** 00171 * @brief Per-thread stack overhead for interrupts servicing. 00172 * @details This is a safe value, you may trim it down after reading the 00173 * right size in the map file. 00174 */ 00175 #ifndef PORT_INT_REQUIRED_STACK 00176 #define PORT_INT_REQUIRED_STACK 48 00177 #endif 00178 00179 /** 00180 * @brief Enforces a correct alignment for a stack area size value. 00181 */ 00182 #define STACK_ALIGN(n) ((((n) - 1) | (sizeof(stkalign_t) - 1)) + 1) 00183 00184 /** 00185 * @brief Computes the thread working area global size. 00186 */ 00187 #define THD_WA_SIZE(n) STACK_ALIGN(sizeof(Thread) + \ 00188 (sizeof(struct intctx) - 1) + \ 00189 (sizeof(struct extctx) - 1) + \ 00190 (n) + (PORT_INT_REQUIRED_STACK)) 00191 00192 /** 00193 * @brief Static working area allocation. 00194 * @details This macro is used to allocate a static thread working area 00195 * aligned as both position and size. 00196 */ 00197 #define WORKING_AREA(s, n) stkalign_t s[THD_WA_SIZE(n) / sizeof(stkalign_t)] 00198 00199 /** 00200 * @brief IRQ prologue code. 00201 * @details This macro must be inserted at the start of all IRQ handlers 00202 * enabled to invoke system APIs. 00203 */ 00204 #define PORT_IRQ_PROLOGUE() { \ 00205 } 00206 00207 /** 00208 * @brief IRQ epilogue code. 00209 * @details This macro must be inserted at the end of all IRQ handlers 00210 * enabled to invoke system APIs. 00211 */ 00212 #define PORT_IRQ_EPILOGUE() { \ 00213 dbg_check_lock(); \ 00214 if (chSchIsPreemptionRequired()) \ 00215 chSchDoReschedule(); \ 00216 dbg_check_unlock(); \ 00217 } 00218 00219 /** 00220 * @brief IRQ handler function declaration. 00221 * @note @p id can be a function name or a vector number depending on the 00222 * port implementation. 00223 */ 00224 #define PORT_IRQ_HANDLER(id) void vector##id(void) interrupt id 00225 00226 /** 00227 * @brief Port-related initialization code. 00228 * @note None in this port. 00229 */ 00230 #define port_init() 00231 00232 /** 00233 * @brief Kernel-lock action. 00234 * @note Implemented as global interrupts disable. 00235 */ 00236 #define port_lock() _sim_() 00237 00238 /** 00239 * @brief Kernel-unlock action. 00240 * @note Implemented as global interrupts enable. 00241 */ 00242 #define port_unlock() _rim_() 00243 00244 /** 00245 * @brief Kernel-lock action from an interrupt handler. 00246 * @note This function is empty in this port. 00247 */ 00248 #define port_lock_from_isr() 00249 00250 /** 00251 * @brief Kernel-unlock action from an interrupt handler. 00252 * @note This function is empty in this port. 00253 */ 00254 #define port_unlock_from_isr() 00255 00256 /** 00257 * @brief Disables all the interrupt sources. 00258 * @note Implemented as global interrupts disable. 00259 * @note Of course non-maskable interrupt sources are not included. 00260 */ 00261 #define port_disable() _sim_() 00262 00263 /** 00264 * @brief Disables the interrupt sources that are not supposed to preempt 00265 * the kernel. 00266 * @note Same as @p port_disable() in this port, there is no difference 00267 * between the two states. 00268 */ 00269 #define port_suspend() _sim_() 00270 00271 /** 00272 * @brief Enables all the interrupt sources. 00273 * @note Implemented as global interrupt enable. 00274 */ 00275 #define port_enable() _rim_() 00276 00277 /** 00278 * @brief Enters an architecture-dependent halt mode. 00279 * @note Implemented with the specific "wfi" instruction. 00280 */ 00281 #if STM8_ENABLE_WFI_IDLE || defined(__DOXYGEN__) 00282 #define port_wait_for_interrupt() _wfi_() 00283 #else 00284 #define port_wait_for_interrupt() 00285 #endif 00286 00287 /** 00288 * @brief Performs a context switch between two threads. 00289 * @details This is the most critical code in any port, this function 00290 * is responsible for the context switch between 2 threads. 00291 * @note Implemented as a call to a low level assembler routine. 00292 * 00293 * @param ntp the thread to be switched in 00294 * @param otp the thread to be switched out 00295 */ 00296 #define port_switch(ntp, otp) _port_switch(otp) 00297 00298 #ifdef __cplusplus 00299 extern "C" { 00300 #endif 00301 void _port_switch(Thread *otp); 00302 void _port_thread_start(void); 00303 void port_halt(void); 00304 #ifdef __cplusplus 00305 } 00306 #endif 00307 00308 /*===========================================================================*/ 00309 /* Scheduler captured code. */ 00310 /*===========================================================================*/ 00311 00312 #define PORT_OPTIMIZED_RLIST_VAR 00313 #define PORT_OPTIMIZED_RLIST_EXT 00314 #define PORT_OPTIMIZED_READYLIST_STRUCT 00315 00316 typedef struct { 00317 ThreadsQueue r_queue; 00318 tprio_t r_prio; 00319 Thread *r_current; 00320 #if CH_USE_REGISTRY 00321 Thread *r_newer; 00322 Thread *r_older; 00323 #endif 00324 /* End of the fields shared with the Thread structure.*/ 00325 #if CH_TIME_QUANTUM > 0 00326 cnt_t r_preempt; 00327 #endif 00328 } ReadyList; 00329 00330 page0 extern ReadyList rlist; 00331 00332 #endif /* _CHCORE_H_ */ 00333 00334 /** @} */