Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard. Support for nucleo F401RE
Dependents: rtos_basic_stm32_F401
Fork of mbed-rtos by
rt_HAL_CM.h
00001 /*---------------------------------------------------------------------------- 00002 * RL-ARM - RTX 00003 *---------------------------------------------------------------------------- 00004 * Name: RT_HAL_CM.H 00005 * Purpose: Hardware Abstraction Layer for Cortex-M definitions 00006 * Rev.: V4.60 00007 *---------------------------------------------------------------------------- 00008 * 00009 * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH 00010 * All rights reserved. 00011 * Redistribution and use in source and binary forms, with or without 00012 * modification, are permitted provided that the following conditions are met: 00013 * - Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * - Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in the 00017 * documentation and/or other materials provided with the distribution. 00018 * - Neither the name of ARM nor the names of its contributors may be used 00019 * to endorse or promote products derived from this software without 00020 * specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE 00026 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00027 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00028 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00029 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00030 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00031 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 *---------------------------------------------------------------------------*/ 00034 00035 /* Definitions */ 00036 #define INITIAL_xPSR 0x01000000 00037 #define DEMCR_TRCENA 0x01000000 00038 #define ITM_ITMENA 0x00000001 00039 #define MAGIC_WORD 0xE25A2EA5 00040 00041 #if defined (__CC_ARM) /* ARM Compiler */ 00042 00043 #if ((__TARGET_ARCH_7_M || __TARGET_ARCH_7E_M) && !NO_EXCLUSIVE_ACCESS) 00044 #define __USE_EXCLUSIVE_ACCESS 00045 #else 00046 #undef __USE_EXCLUSIVE_ACCESS 00047 #endif 00048 00049 #elif defined (__GNUC__) /* GNU Compiler */ 00050 00051 #undef __USE_EXCLUSIVE_ACCESS 00052 00053 #if defined (__CORTEX_M0) || defined (__CORTEX_M0PLUS) 00054 #define __TARGET_ARCH_6S_M 1 00055 #else 00056 #define __TARGET_ARCH_6S_M 0 00057 #endif 00058 00059 #if defined (__VFP_FP__) && !defined(__SOFTFP__) 00060 #define __TARGET_FPU_VFP 1 00061 #else 00062 #define __TARGET_FPU_VFP 0 00063 #endif 00064 00065 #define __inline inline 00066 #define __weak __attribute__((weak)) 00067 00068 #ifndef __CMSIS_GENERIC 00069 00070 __attribute__((always_inline)) static inline void __enable_irq(void) 00071 { 00072 __asm volatile ("cpsie i"); 00073 } 00074 00075 __attribute__((always_inline)) static inline U32 __disable_irq(void) 00076 { 00077 U32 result; 00078 00079 __asm volatile ("mrs %0, primask" : "=r" (result)); 00080 __asm volatile ("cpsid i"); 00081 return(result & 1); 00082 } 00083 00084 #endif 00085 00086 __attribute__(( always_inline)) static inline U8 __clz(U32 value) 00087 { 00088 U8 result; 00089 00090 __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); 00091 return(result); 00092 } 00093 00094 #elif defined (__ICCARM__) /* IAR Compiler */ 00095 00096 #undef __USE_EXCLUSIVE_ACCESS 00097 00098 #if (__CORE__ == __ARM6M__) 00099 #define __TARGET_ARCH_6S_M 1 00100 #else 00101 #define __TARGET_ARCH_6S_M 0 00102 #endif 00103 00104 #if defined __ARMVFP__ 00105 #define __TARGET_FPU_VFP 1 00106 #else 00107 #define __TARGET_FPU_VFP 0 00108 #endif 00109 00110 #define __inline inline 00111 00112 #ifndef __CMSIS_GENERIC 00113 00114 static inline void __enable_irq(void) 00115 { 00116 __asm volatile ("cpsie i"); 00117 } 00118 00119 static inline U32 __disable_irq(void) 00120 { 00121 U32 result; 00122 00123 __asm volatile ("mrs %0, primask" : "=r" (result)); 00124 __asm volatile ("cpsid i"); 00125 return(result & 1); 00126 } 00127 00128 #endif 00129 00130 static inline U8 __clz(U32 value) 00131 { 00132 U8 result; 00133 00134 __asm volatile ("clz %0, %1" : "=r" (result) : "r" (value)); 00135 return(result); 00136 } 00137 00138 #endif 00139 00140 /* NVIC registers */ 00141 #define NVIC_ST_CTRL (*((volatile U32 *)0xE000E010)) 00142 #define NVIC_ST_RELOAD (*((volatile U32 *)0xE000E014)) 00143 #define NVIC_ST_CURRENT (*((volatile U32 *)0xE000E018)) 00144 #define NVIC_ISER ((volatile U32 *)0xE000E100) 00145 #define NVIC_ICER ((volatile U32 *)0xE000E180) 00146 #if (__TARGET_ARCH_6S_M) 00147 #define NVIC_IP ((volatile U32 *)0xE000E400) 00148 #else 00149 #define NVIC_IP ((volatile U8 *)0xE000E400) 00150 #endif 00151 #define NVIC_INT_CTRL (*((volatile U32 *)0xE000ED04)) 00152 #define NVIC_AIR_CTRL (*((volatile U32 *)0xE000ED0C)) 00153 #define NVIC_SYS_PRI2 (*((volatile U32 *)0xE000ED1C)) 00154 #define NVIC_SYS_PRI3 (*((volatile U32 *)0xE000ED20)) 00155 00156 #define OS_PEND_IRQ() NVIC_INT_CTRL = (1<<28) 00157 #define OS_PENDING ((NVIC_INT_CTRL >> 26) & (1<<2 | 1)) 00158 #define OS_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_PENDING) << 25 00159 #define OS_PEND(fl,p) NVIC_INT_CTRL = (fl | p<<2) << 26 00160 #define OS_LOCK() NVIC_ST_CTRL = 0x0005 00161 #define OS_UNLOCK() NVIC_ST_CTRL = 0x0007 00162 00163 #define OS_X_PENDING ((NVIC_INT_CTRL >> 28) & 1) 00164 #define OS_X_UNPEND(fl) NVIC_INT_CTRL = (*fl = OS_X_PENDING) << 27 00165 #define OS_X_PEND(fl,p) NVIC_INT_CTRL = (fl | p) << 28 00166 #if (__TARGET_ARCH_6S_M) 00167 #define OS_X_INIT(n) NVIC_IP[n>>2] |= 0xFF << (8*(n & 0x03)); \ 00168 NVIC_ISER[n>>5] = 1 << (n & 0x1F) 00169 #else 00170 #define OS_X_INIT(n) NVIC_IP[n] = 0xFF; \ 00171 NVIC_ISER[n>>5] = 1 << (n & 0x1F) 00172 #endif 00173 #define OS_X_LOCK(n) NVIC_ICER[n>>5] = 1 << (n & 0x1F) 00174 #define OS_X_UNLOCK(n) NVIC_ISER[n>>5] = 1 << (n & 0x1F) 00175 00176 /* Core Debug registers */ 00177 #define DEMCR (*((volatile U32 *)0xE000EDFC)) 00178 00179 /* ITM registers */ 00180 #define ITM_CONTROL (*((volatile U32 *)0xE0000E80)) 00181 #define ITM_ENABLE (*((volatile U32 *)0xE0000E00)) 00182 #define ITM_PORT30_U32 (*((volatile U32 *)0xE0000078)) 00183 #define ITM_PORT31_U32 (*((volatile U32 *)0xE000007C)) 00184 #define ITM_PORT31_U16 (*((volatile U16 *)0xE000007C)) 00185 #define ITM_PORT31_U8 (*((volatile U8 *)0xE000007C)) 00186 00187 /* Variables */ 00188 extern BIT dbg_msg; 00189 00190 /* Functions */ 00191 #ifdef __USE_EXCLUSIVE_ACCESS 00192 #define rt_inc(p) while(__strex((__ldrex(p)+1),p)) 00193 #define rt_dec(p) while(__strex((__ldrex(p)-1),p)) 00194 #else 00195 #define rt_inc(p) __disable_irq();(*p)++;__enable_irq(); 00196 #define rt_dec(p) __disable_irq();(*p)--;__enable_irq(); 00197 #endif 00198 00199 __inline static U32 rt_inc_qi (U32 size, U8 *count, U8 *first) { 00200 U32 cnt,c2; 00201 #ifdef __USE_EXCLUSIVE_ACCESS 00202 do { 00203 if ((cnt = __ldrex(count)) == size) { 00204 __clrex(); 00205 return (cnt); } 00206 } while (__strex(cnt+1, count)); 00207 do { 00208 c2 = (cnt = __ldrex(first)) + 1; 00209 if (c2 == size) c2 = 0; 00210 } while (__strex(c2, first)); 00211 #else 00212 __disable_irq(); 00213 if ((cnt = *count) < size) { 00214 *count = cnt+1; 00215 c2 = (cnt = *first) + 1; 00216 if (c2 == size) c2 = 0; 00217 *first = c2; 00218 } 00219 __enable_irq (); 00220 #endif 00221 return (cnt); 00222 } 00223 00224 __inline static void rt_systick_init (void) { 00225 NVIC_ST_RELOAD = os_trv; 00226 NVIC_ST_CURRENT = 0; 00227 NVIC_ST_CTRL = 0x0007; 00228 NVIC_SYS_PRI3 |= 0xFF000000; 00229 } 00230 00231 __inline static void rt_svc_init (void) { 00232 #if !(__TARGET_ARCH_6S_M) 00233 int sh,prigroup; 00234 #endif 00235 NVIC_SYS_PRI3 |= 0x00FF0000; 00236 #if (__TARGET_ARCH_6S_M) 00237 NVIC_SYS_PRI2 |= (NVIC_SYS_PRI3<<(8+1)) & 0xFC000000; 00238 #else 00239 sh = 8 - __clz (~((NVIC_SYS_PRI3 << 8) & 0xFF000000)); 00240 prigroup = ((NVIC_AIR_CTRL >> 8) & 0x07); 00241 if (prigroup >= sh) { 00242 sh = prigroup + 1; 00243 } 00244 NVIC_SYS_PRI2 = ((0xFEFFFFFF << sh) & 0xFF000000) | (NVIC_SYS_PRI2 & 0x00FFFFFF); 00245 #endif 00246 } 00247 00248 extern void rt_set_PSP (U32 stack); 00249 extern U32 rt_get_PSP (void); 00250 extern void os_set_env (void); 00251 extern void *_alloc_box (void *box_mem); 00252 extern int _free_box (void *box_mem, void *box); 00253 00254 extern void rt_init_stack (P_TCB p_TCB, FUNCP task_body); 00255 extern void rt_ret_val (P_TCB p_TCB, U32 v0); 00256 extern void rt_ret_val2 (P_TCB p_TCB, U32 v0, U32 v1); 00257 00258 extern void dbg_init (void); 00259 extern void dbg_task_notify (P_TCB p_tcb, BOOL create); 00260 extern void dbg_task_switch (U32 task_id); 00261 00262 #ifdef DBG_MSG 00263 #define DBG_INIT() dbg_init() 00264 #define DBG_TASK_NOTIFY(p_tcb,create) if (dbg_msg) dbg_task_notify(p_tcb,create) 00265 #define DBG_TASK_SWITCH(task_id) if (dbg_msg && (os_tsk.new_tsk != os_tsk.run)) \ 00266 dbg_task_switch(task_id) 00267 #else 00268 #define DBG_INIT() 00269 #define DBG_TASK_NOTIFY(p_tcb,create) 00270 #define DBG_TASK_SWITCH(task_id) 00271 #endif 00272 00273 /*---------------------------------------------------------------------------- 00274 * end of file 00275 *---------------------------------------------------------------------------*/ 00276
Generated on Tue Jul 12 2022 20:53:01 by 1.7.2