my version

Dependents:   aps_so_c2

Fork of mbed-rtos by mbed official

Committer:
feupos
Date:
Sat Nov 18 18:27:08 2017 +0000
Revision:
127:bf4dda6a6a1b
Parent:
123:58563e6cba1e
ok

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 48:e9a2c7cb57a4 1 /*----------------------------------------------------------------------------
mbed_official 48:e9a2c7cb57a4 2 * RL-ARM - RTX
mbed_official 48:e9a2c7cb57a4 3 *----------------------------------------------------------------------------
mbed_official 48:e9a2c7cb57a4 4 * Name: rt_CMSIS.c
mbed_official 48:e9a2c7cb57a4 5 * Purpose: CMSIS RTOS API
mbed_official 92:bc9729798a19 6 * Rev.: V4.74
mbed_official 48:e9a2c7cb57a4 7 *----------------------------------------------------------------------------
mbed_official 48:e9a2c7cb57a4 8 *
mbed_official 92:bc9729798a19 9 * Copyright (c) 1999-2009 KEIL, 2009-2013 ARM Germany GmbH
mbed_official 48:e9a2c7cb57a4 10 * All rights reserved.
mbed_official 48:e9a2c7cb57a4 11 * Redistribution and use in source and binary forms, with or without
mbed_official 48:e9a2c7cb57a4 12 * modification, are permitted provided that the following conditions are met:
mbed_official 48:e9a2c7cb57a4 13 * - Redistributions of source code must retain the above copyright
mbed_official 48:e9a2c7cb57a4 14 * notice, this list of conditions and the following disclaimer.
mbed_official 48:e9a2c7cb57a4 15 * - Redistributions in binary form must reproduce the above copyright
mbed_official 48:e9a2c7cb57a4 16 * notice, this list of conditions and the following disclaimer in the
mbed_official 48:e9a2c7cb57a4 17 * documentation and/or other materials provided with the distribution.
mbed_official 68:d3d0e710b443 18 * - Neither the name of ARM nor the names of its contributors may be used
mbed_official 68:d3d0e710b443 19 * to endorse or promote products derived from this software without
mbed_official 48:e9a2c7cb57a4 20 * specific prior written permission.
mbed_official 48:e9a2c7cb57a4 21 *
mbed_official 68:d3d0e710b443 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
mbed_official 68:d3d0e710b443 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
mbed_official 48:e9a2c7cb57a4 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
mbed_official 48:e9a2c7cb57a4 25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
mbed_official 48:e9a2c7cb57a4 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
mbed_official 68:d3d0e710b443 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
mbed_official 68:d3d0e710b443 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
mbed_official 68:d3d0e710b443 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
mbed_official 68:d3d0e710b443 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
mbed_official 48:e9a2c7cb57a4 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 48:e9a2c7cb57a4 32 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 48:e9a2c7cb57a4 33 *---------------------------------------------------------------------------*/
mbed_official 48:e9a2c7cb57a4 34
mbed_official 48:e9a2c7cb57a4 35 #define __CMSIS_GENERIC
mbed_official 48:e9a2c7cb57a4 36
mbed_official 48:e9a2c7cb57a4 37 #if defined (__CORTEX_M4) || defined (__CORTEX_M4F)
mbed_official 48:e9a2c7cb57a4 38 #include "core_cm4.h"
mbed_official 48:e9a2c7cb57a4 39 #elif defined (__CORTEX_M3)
mbed_official 48:e9a2c7cb57a4 40 #include "core_cm3.h"
mbed_official 48:e9a2c7cb57a4 41 #elif defined (__CORTEX_M0)
mbed_official 48:e9a2c7cb57a4 42 #include "core_cm0.h"
mbed_official 48:e9a2c7cb57a4 43 #elif defined (__CORTEX_A9)
mbed_official 48:e9a2c7cb57a4 44 #include "core_ca9.h"
mbed_official 48:e9a2c7cb57a4 45 #else
mbed_official 48:e9a2c7cb57a4 46 #error "Missing __CORTEX_xx definition"
mbed_official 48:e9a2c7cb57a4 47 #endif
mbed_official 48:e9a2c7cb57a4 48
mbed_official 48:e9a2c7cb57a4 49 #include "rt_TypeDef.h"
mbed_official 48:e9a2c7cb57a4 50 #include "RTX_Config.h"
mbed_official 48:e9a2c7cb57a4 51 #include "rt_System.h"
mbed_official 48:e9a2c7cb57a4 52 #include "rt_Task.h"
mbed_official 48:e9a2c7cb57a4 53 #include "rt_Event.h"
mbed_official 48:e9a2c7cb57a4 54 #include "rt_List.h"
mbed_official 48:e9a2c7cb57a4 55 #include "rt_Time.h"
mbed_official 48:e9a2c7cb57a4 56 #include "rt_Mutex.h"
mbed_official 48:e9a2c7cb57a4 57 #include "rt_Semaphore.h"
mbed_official 48:e9a2c7cb57a4 58 #include "rt_Mailbox.h"
mbed_official 48:e9a2c7cb57a4 59 #include "rt_MemBox.h"
mbed_official 48:e9a2c7cb57a4 60 #include "rt_Memory.h"
mbed_official 48:e9a2c7cb57a4 61 #include "rt_HAL_CM.h"
mbed_official 48:e9a2c7cb57a4 62
mbed_official 48:e9a2c7cb57a4 63 #define os_thread_cb OS_TCB
mbed_official 48:e9a2c7cb57a4 64
mbed_official 48:e9a2c7cb57a4 65 #include "cmsis_os.h"
mbed_official 48:e9a2c7cb57a4 66
mbed_official 48:e9a2c7cb57a4 67 #if (osFeature_Signals != 16)
mbed_official 48:e9a2c7cb57a4 68 #error Invalid "osFeature_Signals" value!
mbed_official 48:e9a2c7cb57a4 69 #endif
mbed_official 48:e9a2c7cb57a4 70 #if (osFeature_Semaphore > 65535)
mbed_official 48:e9a2c7cb57a4 71 #error Invalid "osFeature_Semaphore" value!
mbed_official 48:e9a2c7cb57a4 72 #endif
mbed_official 48:e9a2c7cb57a4 73 #if (osFeature_Wait != 0)
mbed_official 48:e9a2c7cb57a4 74 #error osWait not supported!
mbed_official 48:e9a2c7cb57a4 75 #endif
mbed_official 48:e9a2c7cb57a4 76
mbed_official 48:e9a2c7cb57a4 77
mbed_official 48:e9a2c7cb57a4 78 // ==== Enumeration, structures, defines ====
mbed_official 48:e9a2c7cb57a4 79
mbed_official 48:e9a2c7cb57a4 80 // Service Calls defines
mbed_official 48:e9a2c7cb57a4 81
mbed_official 48:e9a2c7cb57a4 82 #if defined (__CC_ARM) /* ARM Compiler */
mbed_official 48:e9a2c7cb57a4 83
mbed_official 48:e9a2c7cb57a4 84 #define __NO_RETURN __declspec(noreturn)
mbed_official 48:e9a2c7cb57a4 85
mbed_official 48:e9a2c7cb57a4 86 #define osEvent_type osEvent
mbed_official 48:e9a2c7cb57a4 87 #define osEvent_ret_status ret
mbed_official 48:e9a2c7cb57a4 88 #define osEvent_ret_value ret
mbed_official 48:e9a2c7cb57a4 89 #define osEvent_ret_msg ret
mbed_official 48:e9a2c7cb57a4 90 #define osEvent_ret_mail ret
mbed_official 48:e9a2c7cb57a4 91
mbed_official 48:e9a2c7cb57a4 92 #define osCallback_type osCallback
mbed_official 48:e9a2c7cb57a4 93 #define osCallback_ret ret
mbed_official 48:e9a2c7cb57a4 94
mbed_official 48:e9a2c7cb57a4 95 #define SVC_0_1(f,t,...) \
mbed_official 48:e9a2c7cb57a4 96 __svc_indirect(0) t _##f (t(*)()); \
mbed_official 48:e9a2c7cb57a4 97 t f (void); \
mbed_official 48:e9a2c7cb57a4 98 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 99 static __inline t __##f (void) { \
mbed_official 48:e9a2c7cb57a4 100 return _##f(f); \
mbed_official 48:e9a2c7cb57a4 101 }
mbed_official 48:e9a2c7cb57a4 102
mbed_official 92:bc9729798a19 103 #define SVC_1_0(f,t,t1,...) \
mbed_official 92:bc9729798a19 104 __svc_indirect(0) t _##f (t(*)(t1),t1); \
mbed_official 92:bc9729798a19 105 t f (t1 a1); \
mbed_official 92:bc9729798a19 106 __attribute__((always_inline)) \
mbed_official 92:bc9729798a19 107 static __inline t __##f (t1 a1) { \
mbed_official 92:bc9729798a19 108 _##f(f,a1); \
mbed_official 92:bc9729798a19 109 }
mbed_official 92:bc9729798a19 110
mbed_official 48:e9a2c7cb57a4 111 #define SVC_1_1(f,t,t1,...) \
mbed_official 48:e9a2c7cb57a4 112 __svc_indirect(0) t _##f (t(*)(t1),t1); \
mbed_official 48:e9a2c7cb57a4 113 t f (t1 a1); \
mbed_official 48:e9a2c7cb57a4 114 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 115 static __inline t __##f (t1 a1) { \
mbed_official 48:e9a2c7cb57a4 116 return _##f(f,a1); \
mbed_official 48:e9a2c7cb57a4 117 }
mbed_official 48:e9a2c7cb57a4 118
mbed_official 48:e9a2c7cb57a4 119 #define SVC_2_1(f,t,t1,t2,...) \
mbed_official 48:e9a2c7cb57a4 120 __svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \
mbed_official 48:e9a2c7cb57a4 121 t f (t1 a1, t2 a2); \
mbed_official 48:e9a2c7cb57a4 122 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 123 static __inline t __##f (t1 a1, t2 a2) { \
mbed_official 48:e9a2c7cb57a4 124 return _##f(f,a1,a2); \
mbed_official 48:e9a2c7cb57a4 125 }
mbed_official 48:e9a2c7cb57a4 126
mbed_official 48:e9a2c7cb57a4 127 #define SVC_3_1(f,t,t1,t2,t3,...) \
mbed_official 48:e9a2c7cb57a4 128 __svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \
mbed_official 48:e9a2c7cb57a4 129 t f (t1 a1, t2 a2, t3 a3); \
mbed_official 48:e9a2c7cb57a4 130 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 131 static __inline t __##f (t1 a1, t2 a2, t3 a3) { \
mbed_official 48:e9a2c7cb57a4 132 return _##f(f,a1,a2,a3); \
mbed_official 48:e9a2c7cb57a4 133 }
mbed_official 48:e9a2c7cb57a4 134
mbed_official 48:e9a2c7cb57a4 135 #define SVC_4_1(f,t,t1,t2,t3,t4,...) \
mbed_official 48:e9a2c7cb57a4 136 __svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \
mbed_official 48:e9a2c7cb57a4 137 t f (t1 a1, t2 a2, t3 a3, t4 a4); \
mbed_official 48:e9a2c7cb57a4 138 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 139 static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
mbed_official 48:e9a2c7cb57a4 140 return _##f(f,a1,a2,a3,a4); \
mbed_official 48:e9a2c7cb57a4 141 }
mbed_official 48:e9a2c7cb57a4 142
mbed_official 68:d3d0e710b443 143 #define SVC_1_2 SVC_1_1
mbed_official 68:d3d0e710b443 144 #define SVC_1_3 SVC_1_1
mbed_official 68:d3d0e710b443 145 #define SVC_2_3 SVC_2_1
mbed_official 48:e9a2c7cb57a4 146
mbed_official 48:e9a2c7cb57a4 147 #elif defined (__GNUC__) /* GNU Compiler */
mbed_official 48:e9a2c7cb57a4 148
mbed_official 48:e9a2c7cb57a4 149 #define __NO_RETURN __attribute__((noreturn))
mbed_official 48:e9a2c7cb57a4 150
mbed_official 48:e9a2c7cb57a4 151 typedef uint32_t __attribute__((vector_size(8))) ret64;
mbed_official 48:e9a2c7cb57a4 152 typedef uint32_t __attribute__((vector_size(16))) ret128;
mbed_official 48:e9a2c7cb57a4 153
mbed_official 48:e9a2c7cb57a4 154 #define RET_pointer __r0
mbed_official 48:e9a2c7cb57a4 155 #define RET_int32_t __r0
mbed_official 67:63988a2238f7 156 #define RET_uint32_t __r0
mbed_official 48:e9a2c7cb57a4 157 #define RET_osStatus __r0
mbed_official 48:e9a2c7cb57a4 158 #define RET_osPriority __r0
mbed_official 48:e9a2c7cb57a4 159 #define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}}
mbed_official 48:e9a2c7cb57a4 160 #define RET_osCallback {(void *)__r0, (void *)__r1}
mbed_official 48:e9a2c7cb57a4 161
mbed_official 67:63988a2238f7 162 #if defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 163
mbed_official 67:63988a2238f7 164 #define osEvent_type void
mbed_official 67:63988a2238f7 165 #define osEvent_ret_status { __asm ("MOV r0, %0;" \
mbed_official 67:63988a2238f7 166 : /* no outputs */ \
mbed_official 67:63988a2238f7 167 : "r"(ret.status) \
mbed_official 67:63988a2238f7 168 : "r0" \
mbed_official 67:63988a2238f7 169 ); \
mbed_official 67:63988a2238f7 170 }
mbed_official 67:63988a2238f7 171 #define osEvent_ret_value { __asm ("MOV r1, %0;" \
mbed_official 67:63988a2238f7 172 "MOV r0, %1;" \
mbed_official 67:63988a2238f7 173 : /* no outputs */ \
mbed_official 67:63988a2238f7 174 : "r"(ret.value.v), \
mbed_official 67:63988a2238f7 175 "r"(ret.status) \
mbed_official 67:63988a2238f7 176 : "r0", "r1" \
mbed_official 67:63988a2238f7 177 ); \
mbed_official 67:63988a2238f7 178 }
mbed_official 67:63988a2238f7 179 #define osEvent_ret_msg { __asm ("MOV r2, %0;" \
mbed_official 67:63988a2238f7 180 "MOV r1, %1;" \
mbed_official 67:63988a2238f7 181 "MOV r0, %2;" \
mbed_official 67:63988a2238f7 182 : /* no outputs */ \
mbed_official 67:63988a2238f7 183 : "r"(ret.def.message_id), \
mbed_official 67:63988a2238f7 184 "r"(ret.value.v), \
mbed_official 67:63988a2238f7 185 "r"(ret.status) \
mbed_official 67:63988a2238f7 186 : "r0", "r1" , "r2" \
mbed_official 67:63988a2238f7 187 ); \
mbed_official 67:63988a2238f7 188 }
mbed_official 67:63988a2238f7 189
mbed_official 67:63988a2238f7 190 #define osEvent_ret_mail { __asm ("MOV r2, %0;" \
mbed_official 67:63988a2238f7 191 "MOV r1, %1;" \
mbed_official 67:63988a2238f7 192 "MOV r0, %2;" \
mbed_official 67:63988a2238f7 193 : /* no outputs */ \
mbed_official 67:63988a2238f7 194 : "r"(ret.def.mail_id), \
mbed_official 67:63988a2238f7 195 "r"(ret.value.v), \
mbed_official 67:63988a2238f7 196 "r"(ret.status) \
mbed_official 67:63988a2238f7 197 : "r0", "r1" , "r2" \
mbed_official 67:63988a2238f7 198 ); \
mbed_official 67:63988a2238f7 199 }
mbed_official 67:63988a2238f7 200
mbed_official 67:63988a2238f7 201 #define osCallback_type void
mbed_official 67:63988a2238f7 202 #define osCallback_ret { __asm ("MOV r1, %0;" \
mbed_official 67:63988a2238f7 203 "MOV r0, %1;" \
mbed_official 67:63988a2238f7 204 : /* no outputs */ \
mbed_official 67:63988a2238f7 205 : "r"(ret.arg), \
mbed_official 67:63988a2238f7 206 "r"(ret.fp) \
mbed_official 67:63988a2238f7 207 : "r0", "r1" \
mbed_official 67:63988a2238f7 208 ); \
mbed_official 67:63988a2238f7 209 }
mbed_official 67:63988a2238f7 210
mbed_official 67:63988a2238f7 211 #else /* defined (__ARM_PCS_VFP) */
mbed_official 67:63988a2238f7 212
mbed_official 48:e9a2c7cb57a4 213 #define osEvent_type ret128
mbed_official 48:e9a2c7cb57a4 214 #define osEvent_ret_status (ret128){ret.status}
mbed_official 48:e9a2c7cb57a4 215 #define osEvent_ret_value (ret128){ret.status, ret.value.v}
mbed_official 48:e9a2c7cb57a4 216 #define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id}
mbed_official 48:e9a2c7cb57a4 217 #define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id}
mbed_official 48:e9a2c7cb57a4 218
mbed_official 48:e9a2c7cb57a4 219 #define osCallback_type ret64
mbed_official 48:e9a2c7cb57a4 220 #define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg}
mbed_official 48:e9a2c7cb57a4 221
mbed_official 67:63988a2238f7 222 #endif /* defined (__ARM_PCS_VFP) */
mbed_official 67:63988a2238f7 223
mbed_official 48:e9a2c7cb57a4 224 #define SVC_ArgN(n) \
mbed_official 48:e9a2c7cb57a4 225 register int __r##n __asm("r"#n);
mbed_official 48:e9a2c7cb57a4 226
mbed_official 48:e9a2c7cb57a4 227 #define SVC_ArgR(n,t,a) \
mbed_official 48:e9a2c7cb57a4 228 register t __r##n __asm("r"#n) = a;
mbed_official 48:e9a2c7cb57a4 229
mbed_official 48:e9a2c7cb57a4 230 #define SVC_Arg0() \
mbed_official 48:e9a2c7cb57a4 231 SVC_ArgN(0) \
mbed_official 48:e9a2c7cb57a4 232 SVC_ArgN(1) \
mbed_official 48:e9a2c7cb57a4 233 SVC_ArgN(2) \
mbed_official 48:e9a2c7cb57a4 234 SVC_ArgN(3)
mbed_official 48:e9a2c7cb57a4 235
mbed_official 48:e9a2c7cb57a4 236 #define SVC_Arg1(t1) \
mbed_official 48:e9a2c7cb57a4 237 SVC_ArgR(0,t1,a1) \
mbed_official 48:e9a2c7cb57a4 238 SVC_ArgN(1) \
mbed_official 48:e9a2c7cb57a4 239 SVC_ArgN(2) \
mbed_official 48:e9a2c7cb57a4 240 SVC_ArgN(3)
mbed_official 48:e9a2c7cb57a4 241
mbed_official 48:e9a2c7cb57a4 242 #define SVC_Arg2(t1,t2) \
mbed_official 48:e9a2c7cb57a4 243 SVC_ArgR(0,t1,a1) \
mbed_official 48:e9a2c7cb57a4 244 SVC_ArgR(1,t2,a2) \
mbed_official 48:e9a2c7cb57a4 245 SVC_ArgN(2) \
mbed_official 48:e9a2c7cb57a4 246 SVC_ArgN(3)
mbed_official 48:e9a2c7cb57a4 247
mbed_official 48:e9a2c7cb57a4 248 #define SVC_Arg3(t1,t2,t3) \
mbed_official 48:e9a2c7cb57a4 249 SVC_ArgR(0,t1,a1) \
mbed_official 48:e9a2c7cb57a4 250 SVC_ArgR(1,t2,a2) \
mbed_official 48:e9a2c7cb57a4 251 SVC_ArgR(2,t3,a3) \
mbed_official 48:e9a2c7cb57a4 252 SVC_ArgN(3)
mbed_official 48:e9a2c7cb57a4 253
mbed_official 48:e9a2c7cb57a4 254 #define SVC_Arg4(t1,t2,t3,t4) \
mbed_official 48:e9a2c7cb57a4 255 SVC_ArgR(0,t1,a1) \
mbed_official 48:e9a2c7cb57a4 256 SVC_ArgR(1,t2,a2) \
mbed_official 48:e9a2c7cb57a4 257 SVC_ArgR(2,t3,a3) \
mbed_official 48:e9a2c7cb57a4 258 SVC_ArgR(3,t4,a4)
mbed_official 48:e9a2c7cb57a4 259
mbed_official 48:e9a2c7cb57a4 260 #if (defined (__CORTEX_M0))
mbed_official 48:e9a2c7cb57a4 261 #define SVC_Call(f) \
mbed_official 48:e9a2c7cb57a4 262 __asm volatile \
mbed_official 48:e9a2c7cb57a4 263 ( \
mbed_official 48:e9a2c7cb57a4 264 "ldr r7,="#f"\n\t" \
mbed_official 48:e9a2c7cb57a4 265 "mov r12,r7\n\t" \
mbed_official 48:e9a2c7cb57a4 266 "svc 0" \
mbed_official 48:e9a2c7cb57a4 267 : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \
mbed_official 48:e9a2c7cb57a4 268 : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \
mbed_official 48:e9a2c7cb57a4 269 : "r7", "r12", "lr", "cc" \
mbed_official 48:e9a2c7cb57a4 270 );
mbed_official 48:e9a2c7cb57a4 271 #else
mbed_official 48:e9a2c7cb57a4 272 #define SVC_Call(f) \
mbed_official 48:e9a2c7cb57a4 273 __asm volatile \
mbed_official 48:e9a2c7cb57a4 274 ( \
mbed_official 48:e9a2c7cb57a4 275 "ldr r12,="#f"\n\t" \
mbed_official 48:e9a2c7cb57a4 276 "svc 0" \
mbed_official 48:e9a2c7cb57a4 277 : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \
mbed_official 48:e9a2c7cb57a4 278 : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \
mbed_official 48:e9a2c7cb57a4 279 : "r12", "lr", "cc" \
mbed_official 48:e9a2c7cb57a4 280 );
mbed_official 48:e9a2c7cb57a4 281 #endif
mbed_official 48:e9a2c7cb57a4 282
mbed_official 48:e9a2c7cb57a4 283 #define SVC_0_1(f,t,rv) \
mbed_official 48:e9a2c7cb57a4 284 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 285 static inline t __##f (void) { \
mbed_official 48:e9a2c7cb57a4 286 SVC_Arg0(); \
mbed_official 48:e9a2c7cb57a4 287 SVC_Call(f); \
mbed_official 48:e9a2c7cb57a4 288 return (t) rv; \
mbed_official 48:e9a2c7cb57a4 289 }
mbed_official 48:e9a2c7cb57a4 290
mbed_official 92:bc9729798a19 291 #define SVC_1_0(f,t,t1) \
mbed_official 92:bc9729798a19 292 __attribute__((always_inline)) \
mbed_official 92:bc9729798a19 293 static inline t __##f (t1 a1) { \
mbed_official 92:bc9729798a19 294 SVC_Arg1(t1); \
mbed_official 92:bc9729798a19 295 SVC_Call(f); \
mbed_official 92:bc9729798a19 296 }
mbed_official 92:bc9729798a19 297
mbed_official 48:e9a2c7cb57a4 298 #define SVC_1_1(f,t,t1,rv) \
mbed_official 48:e9a2c7cb57a4 299 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 300 static inline t __##f (t1 a1) { \
mbed_official 48:e9a2c7cb57a4 301 SVC_Arg1(t1); \
mbed_official 48:e9a2c7cb57a4 302 SVC_Call(f); \
mbed_official 48:e9a2c7cb57a4 303 return (t) rv; \
mbed_official 48:e9a2c7cb57a4 304 }
mbed_official 48:e9a2c7cb57a4 305
mbed_official 48:e9a2c7cb57a4 306 #define SVC_2_1(f,t,t1,t2,rv) \
mbed_official 48:e9a2c7cb57a4 307 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 308 static inline t __##f (t1 a1, t2 a2) { \
mbed_official 48:e9a2c7cb57a4 309 SVC_Arg2(t1,t2); \
mbed_official 48:e9a2c7cb57a4 310 SVC_Call(f); \
mbed_official 48:e9a2c7cb57a4 311 return (t) rv; \
mbed_official 48:e9a2c7cb57a4 312 }
mbed_official 48:e9a2c7cb57a4 313
mbed_official 48:e9a2c7cb57a4 314 #define SVC_3_1(f,t,t1,t2,t3,rv) \
mbed_official 48:e9a2c7cb57a4 315 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 316 static inline t __##f (t1 a1, t2 a2, t3 a3) { \
mbed_official 48:e9a2c7cb57a4 317 SVC_Arg3(t1,t2,t3); \
mbed_official 48:e9a2c7cb57a4 318 SVC_Call(f); \
mbed_official 48:e9a2c7cb57a4 319 return (t) rv; \
mbed_official 48:e9a2c7cb57a4 320 }
mbed_official 48:e9a2c7cb57a4 321
mbed_official 48:e9a2c7cb57a4 322 #define SVC_4_1(f,t,t1,t2,t3,t4,rv) \
mbed_official 48:e9a2c7cb57a4 323 __attribute__((always_inline)) \
mbed_official 48:e9a2c7cb57a4 324 static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
mbed_official 48:e9a2c7cb57a4 325 SVC_Arg4(t1,t2,t3,t4); \
mbed_official 48:e9a2c7cb57a4 326 SVC_Call(f); \
mbed_official 48:e9a2c7cb57a4 327 return (t) rv; \
mbed_official 48:e9a2c7cb57a4 328 }
mbed_official 48:e9a2c7cb57a4 329
mbed_official 68:d3d0e710b443 330 #define SVC_1_2 SVC_1_1
mbed_official 68:d3d0e710b443 331 #define SVC_1_3 SVC_1_1
mbed_official 68:d3d0e710b443 332 #define SVC_2_3 SVC_2_1
mbed_official 48:e9a2c7cb57a4 333
mbed_official 48:e9a2c7cb57a4 334 #elif defined (__ICCARM__) /* IAR Compiler */
mbed_official 48:e9a2c7cb57a4 335
mbed_official 48:e9a2c7cb57a4 336 #define __NO_RETURN __noreturn
mbed_official 48:e9a2c7cb57a4 337
mbed_official 48:e9a2c7cb57a4 338 #define RET_osEvent "=r"(ret.status), "=r"(ret.value), "=r"(ret.def)
mbed_official 48:e9a2c7cb57a4 339 #define RET_osCallback "=r"(ret.fp), "=r"(ret.arg)
mbed_official 48:e9a2c7cb57a4 340
mbed_official 48:e9a2c7cb57a4 341 #define osEvent_type osEvent
mbed_official 48:e9a2c7cb57a4 342 #define osEvent_ret_status ret
mbed_official 48:e9a2c7cb57a4 343 #define osEvent_ret_value ret
mbed_official 48:e9a2c7cb57a4 344 #define osEvent_ret_msg ret
mbed_official 48:e9a2c7cb57a4 345 #define osEvent_ret_mail ret
mbed_official 48:e9a2c7cb57a4 346
mbed_official 48:e9a2c7cb57a4 347 #define osCallback_type uint64_t
mbed_official 48:e9a2c7cb57a4 348 #define osCallback_ret ((uint64_t)ret.fp | ((uint64_t)ret.arg)<<32)
mbed_official 48:e9a2c7cb57a4 349
mbed_official 48:e9a2c7cb57a4 350 #define SVC_Setup(f) \
mbed_official 48:e9a2c7cb57a4 351 __asm( \
mbed_official 48:e9a2c7cb57a4 352 "mov r12,%0\n" \
mbed_official 48:e9a2c7cb57a4 353 :: "r"(&f): "r12" \
mbed_official 48:e9a2c7cb57a4 354 );
mbed_official 48:e9a2c7cb57a4 355
mbed_official 48:e9a2c7cb57a4 356 #define SVC_Ret3() \
mbed_official 48:e9a2c7cb57a4 357 __asm( \
mbed_official 48:e9a2c7cb57a4 358 "ldr r0,[sp,#0]\n" \
mbed_official 48:e9a2c7cb57a4 359 "ldr r1,[sp,#4]\n" \
mbed_official 48:e9a2c7cb57a4 360 "ldr r2,[sp,#8]\n" \
mbed_official 48:e9a2c7cb57a4 361 );
mbed_official 48:e9a2c7cb57a4 362
mbed_official 48:e9a2c7cb57a4 363 #define SVC_0_1(f,t,...) \
mbed_official 48:e9a2c7cb57a4 364 t f (void); \
mbed_official 48:e9a2c7cb57a4 365 _Pragma("swi_number=0") __swi t _##f (void); \
mbed_official 48:e9a2c7cb57a4 366 static inline t __##f (void) { \
mbed_official 48:e9a2c7cb57a4 367 SVC_Setup(f); \
mbed_official 48:e9a2c7cb57a4 368 return _##f(); \
mbed_official 48:e9a2c7cb57a4 369 }
mbed_official 48:e9a2c7cb57a4 370
mbed_official 92:bc9729798a19 371 #define SVC_1_0(f,t,t1,...) \
mbed_official 92:bc9729798a19 372 t f (t1 a1); \
mbed_official 92:bc9729798a19 373 _Pragma("swi_number=0") __swi t _##f (t1 a1); \
mbed_official 92:bc9729798a19 374 static inline t __##f (t1 a1) { \
mbed_official 92:bc9729798a19 375 SVC_Setup(f); \
mbed_official 92:bc9729798a19 376 _##f(a1); \
mbed_official 92:bc9729798a19 377 }
mbed_official 92:bc9729798a19 378
mbed_official 48:e9a2c7cb57a4 379 #define SVC_1_1(f,t,t1,...) \
mbed_official 48:e9a2c7cb57a4 380 t f (t1 a1); \
mbed_official 48:e9a2c7cb57a4 381 _Pragma("swi_number=0") __swi t _##f (t1 a1); \
mbed_official 48:e9a2c7cb57a4 382 static inline t __##f (t1 a1) { \
mbed_official 48:e9a2c7cb57a4 383 SVC_Setup(f); \
mbed_official 48:e9a2c7cb57a4 384 return _##f(a1); \
mbed_official 48:e9a2c7cb57a4 385 }
mbed_official 48:e9a2c7cb57a4 386
mbed_official 48:e9a2c7cb57a4 387 #define SVC_2_1(f,t,t1,t2,...) \
mbed_official 48:e9a2c7cb57a4 388 t f (t1 a1, t2 a2); \
mbed_official 48:e9a2c7cb57a4 389 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \
mbed_official 48:e9a2c7cb57a4 390 static inline t __##f (t1 a1, t2 a2) { \
mbed_official 48:e9a2c7cb57a4 391 SVC_Setup(f); \
mbed_official 48:e9a2c7cb57a4 392 return _##f(a1,a2); \
mbed_official 48:e9a2c7cb57a4 393 }
mbed_official 48:e9a2c7cb57a4 394
mbed_official 48:e9a2c7cb57a4 395 #define SVC_3_1(f,t,t1,t2,t3,...) \
mbed_official 48:e9a2c7cb57a4 396 t f (t1 a1, t2 a2, t3 a3); \
mbed_official 48:e9a2c7cb57a4 397 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \
mbed_official 48:e9a2c7cb57a4 398 static inline t __##f (t1 a1, t2 a2, t3 a3) { \
mbed_official 48:e9a2c7cb57a4 399 SVC_Setup(f); \
mbed_official 48:e9a2c7cb57a4 400 return _##f(a1,a2,a3); \
mbed_official 48:e9a2c7cb57a4 401 }
mbed_official 48:e9a2c7cb57a4 402
mbed_official 48:e9a2c7cb57a4 403 #define SVC_4_1(f,t,t1,t2,t3,t4,...) \
mbed_official 48:e9a2c7cb57a4 404 t f (t1 a1, t2 a2, t3 a3, t4 a4); \
mbed_official 48:e9a2c7cb57a4 405 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \
mbed_official 48:e9a2c7cb57a4 406 static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
mbed_official 48:e9a2c7cb57a4 407 SVC_Setup(f); \
mbed_official 48:e9a2c7cb57a4 408 return _##f(a1,a2,a3,a4); \
mbed_official 48:e9a2c7cb57a4 409 }
mbed_official 48:e9a2c7cb57a4 410
mbed_official 48:e9a2c7cb57a4 411 #define SVC_1_2(f,t,t1,rr) \
mbed_official 48:e9a2c7cb57a4 412 uint64_t f (t1 a1); \
mbed_official 48:e9a2c7cb57a4 413 _Pragma("swi_number=0") __swi uint64_t _##f (t1 a1); \
mbed_official 48:e9a2c7cb57a4 414 static inline t __##f (t1 a1) { \
mbed_official 48:e9a2c7cb57a4 415 t ret; \
mbed_official 48:e9a2c7cb57a4 416 SVC_Setup(f); \
mbed_official 48:e9a2c7cb57a4 417 _##f(a1); \
mbed_official 48:e9a2c7cb57a4 418 __asm("" : rr : :); \
mbed_official 48:e9a2c7cb57a4 419 return ret; \
mbed_official 48:e9a2c7cb57a4 420 }
mbed_official 48:e9a2c7cb57a4 421
mbed_official 48:e9a2c7cb57a4 422 #define SVC_1_3(f,t,t1,rr) \
mbed_official 48:e9a2c7cb57a4 423 t f (t1 a1); \
mbed_official 48:e9a2c7cb57a4 424 void f##_ (t1 a1) { \
mbed_official 48:e9a2c7cb57a4 425 f(a1); \
mbed_official 48:e9a2c7cb57a4 426 SVC_Ret3(); \
mbed_official 48:e9a2c7cb57a4 427 } \
mbed_official 48:e9a2c7cb57a4 428 _Pragma("swi_number=0") __swi void _##f (t1 a1); \
mbed_official 48:e9a2c7cb57a4 429 static inline t __##f (t1 a1) { \
mbed_official 48:e9a2c7cb57a4 430 t ret; \
mbed_official 48:e9a2c7cb57a4 431 SVC_Setup(f##_); \
mbed_official 48:e9a2c7cb57a4 432 _##f(a1); \
mbed_official 48:e9a2c7cb57a4 433 __asm("" : rr : :); \
mbed_official 48:e9a2c7cb57a4 434 return ret; \
mbed_official 48:e9a2c7cb57a4 435 }
mbed_official 48:e9a2c7cb57a4 436
mbed_official 48:e9a2c7cb57a4 437 #define SVC_2_3(f,t,t1,t2,rr) \
mbed_official 48:e9a2c7cb57a4 438 t f (t1 a1, t2 a2); \
mbed_official 48:e9a2c7cb57a4 439 void f##_ (t1 a1, t2 a2) { \
mbed_official 48:e9a2c7cb57a4 440 f(a1,a2); \
mbed_official 48:e9a2c7cb57a4 441 SVC_Ret3(); \
mbed_official 48:e9a2c7cb57a4 442 } \
mbed_official 48:e9a2c7cb57a4 443 _Pragma("swi_number=0") __swi void _##f (t1 a1, t2 a2); \
mbed_official 48:e9a2c7cb57a4 444 static inline t __##f (t1 a1, t2 a2) { \
mbed_official 48:e9a2c7cb57a4 445 t ret; \
mbed_official 48:e9a2c7cb57a4 446 SVC_Setup(f##_); \
mbed_official 48:e9a2c7cb57a4 447 _##f(a1,a2); \
mbed_official 48:e9a2c7cb57a4 448 __asm("" : rr : :); \
mbed_official 48:e9a2c7cb57a4 449 return ret; \
mbed_official 48:e9a2c7cb57a4 450 }
mbed_official 48:e9a2c7cb57a4 451
mbed_official 48:e9a2c7cb57a4 452 #endif
mbed_official 48:e9a2c7cb57a4 453
mbed_official 48:e9a2c7cb57a4 454
mbed_official 48:e9a2c7cb57a4 455 // Callback structure
mbed_official 48:e9a2c7cb57a4 456 typedef struct {
mbed_official 48:e9a2c7cb57a4 457 void *fp; // Function pointer
mbed_official 48:e9a2c7cb57a4 458 void *arg; // Function argument
mbed_official 48:e9a2c7cb57a4 459 } osCallback;
mbed_official 48:e9a2c7cb57a4 460
mbed_official 48:e9a2c7cb57a4 461
mbed_official 48:e9a2c7cb57a4 462 // OS Section definitions
mbed_official 48:e9a2c7cb57a4 463 #ifdef OS_SECTIONS_LINK_INFO
mbed_official 48:e9a2c7cb57a4 464 extern const uint32_t os_section_id$$Base;
mbed_official 48:e9a2c7cb57a4 465 extern const uint32_t os_section_id$$Limit;
mbed_official 48:e9a2c7cb57a4 466 #endif
mbed_official 48:e9a2c7cb57a4 467
mbed_official 85:ef0a22cdf839 468 #ifndef __MBED_CMSIS_RTOS_CA9
mbed_official 48:e9a2c7cb57a4 469 // OS Stack Memory for Threads definitions
mbed_official 48:e9a2c7cb57a4 470 extern uint64_t os_stack_mem[];
mbed_official 48:e9a2c7cb57a4 471 extern const uint32_t os_stack_sz;
mbed_official 85:ef0a22cdf839 472 #endif
mbed_official 48:e9a2c7cb57a4 473
mbed_official 48:e9a2c7cb57a4 474 // OS Timers external resources
mbed_official 48:e9a2c7cb57a4 475 extern const osThreadDef_t os_thread_def_osTimerThread;
mbed_official 48:e9a2c7cb57a4 476 extern osThreadId osThreadId_osTimerThread;
mbed_official 48:e9a2c7cb57a4 477 extern const osMessageQDef_t os_messageQ_def_osTimerMessageQ;
mbed_official 48:e9a2c7cb57a4 478 extern osMessageQId osMessageQId_osTimerMessageQ;
mbed_official 48:e9a2c7cb57a4 479
mbed_official 48:e9a2c7cb57a4 480 extern U32 IRQNestLevel; /* Indicates whether inside an ISR, and the depth of nesting. 0 = not in ISR. */
mbed_official 48:e9a2c7cb57a4 481
c1728p9 123:58563e6cba1e 482 // Thread creation and destruction
c1728p9 123:58563e6cba1e 483 osMutexDef(osThreadMutex);
c1728p9 123:58563e6cba1e 484 osMutexId osMutexId_osThreadMutex;
c1728p9 123:58563e6cba1e 485 void sysThreadTerminate(osThreadId id);
mbed_official 48:e9a2c7cb57a4 486
mbed_official 48:e9a2c7cb57a4 487 // ==== Helper Functions ====
mbed_official 48:e9a2c7cb57a4 488
mbed_official 48:e9a2c7cb57a4 489 /// Convert timeout in millisec to system ticks
mbed_official 48:e9a2c7cb57a4 490 static uint32_t rt_ms2tick (uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 491 uint32_t tick;
mbed_official 48:e9a2c7cb57a4 492
mbed_official 48:e9a2c7cb57a4 493 if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout
mbed_official 48:e9a2c7cb57a4 494 if (millisec > 4000000) return 0xFFFE; // Max ticks supported
mbed_official 48:e9a2c7cb57a4 495
mbed_official 48:e9a2c7cb57a4 496 tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate;
mbed_official 48:e9a2c7cb57a4 497 if (tick > 0xFFFE) return 0xFFFE;
mbed_official 68:d3d0e710b443 498
mbed_official 48:e9a2c7cb57a4 499 return tick;
mbed_official 48:e9a2c7cb57a4 500 }
mbed_official 48:e9a2c7cb57a4 501
mbed_official 48:e9a2c7cb57a4 502 /// Convert Thread ID to TCB pointer
mbed_official 48:e9a2c7cb57a4 503 static P_TCB rt_tid2ptcb (osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 504 P_TCB ptcb;
mbed_official 48:e9a2c7cb57a4 505
mbed_official 48:e9a2c7cb57a4 506 if (thread_id == NULL) return NULL;
mbed_official 48:e9a2c7cb57a4 507
mbed_official 48:e9a2c7cb57a4 508 if ((uint32_t)thread_id & 3) return NULL;
mbed_official 48:e9a2c7cb57a4 509
mbed_official 48:e9a2c7cb57a4 510 #ifdef OS_SECTIONS_LINK_INFO
mbed_official 48:e9a2c7cb57a4 511 if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) {
mbed_official 48:e9a2c7cb57a4 512 if (thread_id < (osThreadId)os_section_id$$Base) return NULL;
mbed_official 48:e9a2c7cb57a4 513 if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL;
mbed_official 48:e9a2c7cb57a4 514 }
mbed_official 48:e9a2c7cb57a4 515 #endif
mbed_official 48:e9a2c7cb57a4 516
mbed_official 48:e9a2c7cb57a4 517 ptcb = thread_id;
mbed_official 48:e9a2c7cb57a4 518
mbed_official 48:e9a2c7cb57a4 519 if (ptcb->cb_type != TCB) return NULL;
mbed_official 48:e9a2c7cb57a4 520
mbed_official 48:e9a2c7cb57a4 521 return ptcb;
mbed_official 48:e9a2c7cb57a4 522 }
mbed_official 48:e9a2c7cb57a4 523
mbed_official 48:e9a2c7cb57a4 524 /// Convert ID pointer to Object pointer
mbed_official 48:e9a2c7cb57a4 525 static void *rt_id2obj (void *id) {
mbed_official 48:e9a2c7cb57a4 526
mbed_official 48:e9a2c7cb57a4 527 if ((uint32_t)id & 3) return NULL;
mbed_official 48:e9a2c7cb57a4 528
mbed_official 48:e9a2c7cb57a4 529 #ifdef OS_SECTIONS_LINK_INFO
mbed_official 48:e9a2c7cb57a4 530 if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) {
mbed_official 48:e9a2c7cb57a4 531 if (id < (void *)os_section_id$$Base) return NULL;
mbed_official 48:e9a2c7cb57a4 532 if (id >= (void *)os_section_id$$Limit) return NULL;
mbed_official 48:e9a2c7cb57a4 533 }
mbed_official 48:e9a2c7cb57a4 534 #endif
mbed_official 48:e9a2c7cb57a4 535
mbed_official 48:e9a2c7cb57a4 536 return id;
mbed_official 48:e9a2c7cb57a4 537 }
mbed_official 48:e9a2c7cb57a4 538
mbed_official 48:e9a2c7cb57a4 539 // === Helper functions for system call interface ===
mbed_official 48:e9a2c7cb57a4 540
mbed_official 48:e9a2c7cb57a4 541 static __inline char __get_mode(void) {
mbed_official 48:e9a2c7cb57a4 542 return (char)(__get_CPSR() & 0x1f);
mbed_official 48:e9a2c7cb57a4 543 }
mbed_official 48:e9a2c7cb57a4 544
mbed_official 48:e9a2c7cb57a4 545 static __inline char __exceptional_mode(void) {
c1728p9 123:58563e6cba1e 546 // Interrupts disabled
c1728p9 123:58563e6cba1e 547 if (__get_CPSR() & 0x80) {
c1728p9 123:58563e6cba1e 548 return 1;
c1728p9 123:58563e6cba1e 549 }
c1728p9 123:58563e6cba1e 550
mbed_official 48:e9a2c7cb57a4 551 switch(__get_mode()) {
mbed_official 48:e9a2c7cb57a4 552 case MODE_USR:
mbed_official 48:e9a2c7cb57a4 553 case MODE_SYS:
mbed_official 48:e9a2c7cb57a4 554 return 0;
mbed_official 48:e9a2c7cb57a4 555 case MODE_SVC:
mbed_official 48:e9a2c7cb57a4 556 if (IRQNestLevel == 0)
mbed_official 48:e9a2c7cb57a4 557 return 0; /* handling a regular service call */
mbed_official 48:e9a2c7cb57a4 558 else
mbed_official 48:e9a2c7cb57a4 559 return 1; /* handling an ISR in SVC mode */
mbed_official 48:e9a2c7cb57a4 560 default:
mbed_official 48:e9a2c7cb57a4 561 return 1;
mbed_official 48:e9a2c7cb57a4 562 }
mbed_official 48:e9a2c7cb57a4 563 }
mbed_official 48:e9a2c7cb57a4 564
mbed_official 48:e9a2c7cb57a4 565 // ==== Kernel Control ====
mbed_official 48:e9a2c7cb57a4 566
mbed_official 48:e9a2c7cb57a4 567 uint8_t os_initialized; // Kernel Initialized flag
mbed_official 48:e9a2c7cb57a4 568 uint8_t os_running; // Kernel Running flag
mbed_official 48:e9a2c7cb57a4 569
mbed_official 48:e9a2c7cb57a4 570 // Kernel Control Service Calls declarations
mbed_official 48:e9a2c7cb57a4 571 SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 572 SVC_0_1(svcKernelStart, osStatus, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 573 SVC_0_1(svcKernelRunning, int32_t, RET_int32_t)
mbed_official 92:bc9729798a19 574 SVC_0_1(svcKernelSysTick, uint32_t, RET_uint32_t)
mbed_official 48:e9a2c7cb57a4 575
mbed_official 48:e9a2c7cb57a4 576 static void sysThreadError (osStatus status);
mbed_official 48:e9a2c7cb57a4 577 osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument);
mbed_official 48:e9a2c7cb57a4 578 osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id);
mbed_official 48:e9a2c7cb57a4 579
mbed_official 48:e9a2c7cb57a4 580 // Kernel Control Service Calls
mbed_official 48:e9a2c7cb57a4 581
mbed_official 48:e9a2c7cb57a4 582 /// Initialize the RTOS Kernel for creating objects
mbed_official 48:e9a2c7cb57a4 583 osStatus svcKernelInitialize (void) {
mbed_official 85:ef0a22cdf839 584 #ifdef __MBED_CMSIS_RTOS_CA9
mbed_official 85:ef0a22cdf839 585 if (!os_initialized) {
mbed_official 85:ef0a22cdf839 586 rt_sys_init(); // RTX System Initialization
mbed_official 85:ef0a22cdf839 587 }
mbed_official 85:ef0a22cdf839 588 #else
mbed_official 48:e9a2c7cb57a4 589 int ret;
mbed_official 48:e9a2c7cb57a4 590
mbed_official 48:e9a2c7cb57a4 591 if (!os_initialized) {
mbed_official 48:e9a2c7cb57a4 592
mbed_official 48:e9a2c7cb57a4 593 // Init Thread Stack Memory (must be 8-byte aligned)
mbed_official 48:e9a2c7cb57a4 594 if ((uint32_t)os_stack_mem & 7) return osErrorNoMemory;
mbed_official 48:e9a2c7cb57a4 595 ret = rt_init_mem(os_stack_mem, os_stack_sz);
mbed_official 48:e9a2c7cb57a4 596 if (ret != 0) return osErrorNoMemory;
mbed_official 48:e9a2c7cb57a4 597
mbed_official 48:e9a2c7cb57a4 598 rt_sys_init(); // RTX System Initialization
mbed_official 48:e9a2c7cb57a4 599 }
mbed_official 85:ef0a22cdf839 600 #endif
mbed_official 48:e9a2c7cb57a4 601
mbed_official 48:e9a2c7cb57a4 602 os_tsk.run->prio = 255; // Highest priority
mbed_official 48:e9a2c7cb57a4 603
mbed_official 48:e9a2c7cb57a4 604 if (!os_initialized) {
mbed_official 48:e9a2c7cb57a4 605 // Create OS Timers resources (Message Queue & Thread)
mbed_official 48:e9a2c7cb57a4 606 osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL);
mbed_official 48:e9a2c7cb57a4 607 osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL);
c1728p9 123:58563e6cba1e 608 // Initialize thread mutex
c1728p9 123:58563e6cba1e 609 osMutexId_osThreadMutex = osMutexCreate(osMutex(osThreadMutex));
mbed_official 48:e9a2c7cb57a4 610 }
mbed_official 48:e9a2c7cb57a4 611
mbed_official 48:e9a2c7cb57a4 612 sysThreadError(osOK);
mbed_official 48:e9a2c7cb57a4 613
mbed_official 48:e9a2c7cb57a4 614 os_initialized = 1;
mbed_official 92:bc9729798a19 615 os_running = 0;
mbed_official 48:e9a2c7cb57a4 616
mbed_official 48:e9a2c7cb57a4 617 return osOK;
mbed_official 48:e9a2c7cb57a4 618 }
mbed_official 48:e9a2c7cb57a4 619
mbed_official 48:e9a2c7cb57a4 620 /// Start the RTOS Kernel
mbed_official 48:e9a2c7cb57a4 621 osStatus svcKernelStart (void) {
mbed_official 48:e9a2c7cb57a4 622
mbed_official 48:e9a2c7cb57a4 623 if (os_running) return osOK;
mbed_official 48:e9a2c7cb57a4 624
mbed_official 92:bc9729798a19 625 rt_tsk_prio(0, os_tsk.run->prio_base); // Restore priority
mbed_official 92:bc9729798a19 626 if (os_tsk.run->task_id == 0xFF) { // Idle Thread
mbed_official 92:bc9729798a19 627 __set_PSP(os_tsk.run->tsk_stack + 8*4); // Setup PSP
mbed_official 92:bc9729798a19 628 }
mbed_official 48:e9a2c7cb57a4 629 os_tsk.run = NULL; // Force context switch
mbed_official 48:e9a2c7cb57a4 630
mbed_official 48:e9a2c7cb57a4 631 rt_sys_start();
mbed_official 48:e9a2c7cb57a4 632
mbed_official 48:e9a2c7cb57a4 633 os_running = 1;
mbed_official 48:e9a2c7cb57a4 634
mbed_official 48:e9a2c7cb57a4 635 return osOK;
mbed_official 48:e9a2c7cb57a4 636 }
mbed_official 48:e9a2c7cb57a4 637
mbed_official 48:e9a2c7cb57a4 638 /// Check if the RTOS kernel is already started
mbed_official 48:e9a2c7cb57a4 639 int32_t svcKernelRunning(void) {
mbed_official 48:e9a2c7cb57a4 640 return os_running;
mbed_official 48:e9a2c7cb57a4 641 }
mbed_official 48:e9a2c7cb57a4 642
mbed_official 92:bc9729798a19 643 /// Get the RTOS kernel system timer counter
mbed_official 92:bc9729798a19 644 uint32_t svcKernelSysTick (void) {
mbed_official 92:bc9729798a19 645 uint32_t tick, tick0;
mbed_official 92:bc9729798a19 646
mbed_official 92:bc9729798a19 647 tick = os_tick_val();
mbed_official 92:bc9729798a19 648 if (os_tick_ovf()) {
mbed_official 92:bc9729798a19 649 tick0 = os_tick_val();
mbed_official 92:bc9729798a19 650 if (tick0 < tick) tick = tick0;
mbed_official 92:bc9729798a19 651 tick += (os_trv + 1) * (os_time + 1);
mbed_official 92:bc9729798a19 652 } else {
mbed_official 92:bc9729798a19 653 tick += (os_trv + 1) * os_time;
mbed_official 92:bc9729798a19 654 }
mbed_official 92:bc9729798a19 655
mbed_official 92:bc9729798a19 656 return tick;
mbed_official 92:bc9729798a19 657 }
mbed_official 92:bc9729798a19 658
mbed_official 48:e9a2c7cb57a4 659 // Kernel Control Public API
mbed_official 48:e9a2c7cb57a4 660
mbed_official 48:e9a2c7cb57a4 661 /// Initialize the RTOS Kernel for creating objects
mbed_official 48:e9a2c7cb57a4 662 osStatus osKernelInitialize (void) {
mbed_official 48:e9a2c7cb57a4 663 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 664 if (__get_mode() != MODE_USR) {
mbed_official 48:e9a2c7cb57a4 665 return svcKernelInitialize();
mbed_official 48:e9a2c7cb57a4 666 } else {
mbed_official 48:e9a2c7cb57a4 667 return __svcKernelInitialize();
mbed_official 48:e9a2c7cb57a4 668 }
mbed_official 48:e9a2c7cb57a4 669 }
mbed_official 48:e9a2c7cb57a4 670
mbed_official 48:e9a2c7cb57a4 671 /// Start the RTOS Kernel
mbed_official 48:e9a2c7cb57a4 672 osStatus osKernelStart (void) {
mbed_official 48:e9a2c7cb57a4 673 char mode = __get_mode();
mbed_official 48:e9a2c7cb57a4 674
mbed_official 48:e9a2c7cb57a4 675 switch(mode) {
mbed_official 48:e9a2c7cb57a4 676 case MODE_USR:
mbed_official 48:e9a2c7cb57a4 677 if (os_flags & 1) return osErrorOS; // Privileged Thread mode requested from Unprivileged
mbed_official 48:e9a2c7cb57a4 678 break;
mbed_official 48:e9a2c7cb57a4 679 case MODE_SYS:
mbed_official 48:e9a2c7cb57a4 680 if (!(os_flags & 1)) {
mbed_official 48:e9a2c7cb57a4 681 __set_CPS_USR();
mbed_official 48:e9a2c7cb57a4 682 }
mbed_official 48:e9a2c7cb57a4 683 break;
mbed_official 48:e9a2c7cb57a4 684 default:
mbed_official 48:e9a2c7cb57a4 685 return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 686 }
mbed_official 48:e9a2c7cb57a4 687 return __svcKernelStart();
mbed_official 48:e9a2c7cb57a4 688 }
mbed_official 48:e9a2c7cb57a4 689
mbed_official 48:e9a2c7cb57a4 690 /// Check if the RTOS kernel is already started
mbed_official 48:e9a2c7cb57a4 691 int32_t osKernelRunning(void) {
mbed_official 48:e9a2c7cb57a4 692 if(__get_mode() != MODE_USR) {
mbed_official 48:e9a2c7cb57a4 693 return os_running;
mbed_official 48:e9a2c7cb57a4 694 } else {
mbed_official 48:e9a2c7cb57a4 695 return __svcKernelRunning();
mbed_official 48:e9a2c7cb57a4 696 }
mbed_official 48:e9a2c7cb57a4 697 }
mbed_official 48:e9a2c7cb57a4 698
mbed_official 92:bc9729798a19 699 /// Get the RTOS kernel system timer counter
mbed_official 92:bc9729798a19 700 uint32_t osKernelSysTick (void) {
mbed_official 92:bc9729798a19 701 if (__exceptional_mode()) return 0; // Not allowed in ISR
mbed_official 92:bc9729798a19 702 return __svcKernelSysTick();
mbed_official 92:bc9729798a19 703 }
mbed_official 92:bc9729798a19 704
mbed_official 48:e9a2c7cb57a4 705
mbed_official 48:e9a2c7cb57a4 706 // ==== Thread Management ====
mbed_official 48:e9a2c7cb57a4 707
mbed_official 48:e9a2c7cb57a4 708 /// Set Thread Error (for Create functions which return IDs)
mbed_official 48:e9a2c7cb57a4 709 static void sysThreadError (osStatus status) {
mbed_official 48:e9a2c7cb57a4 710 // To Do
mbed_official 48:e9a2c7cb57a4 711 }
mbed_official 48:e9a2c7cb57a4 712
mbed_official 48:e9a2c7cb57a4 713 __NO_RETURN void osThreadExit (void);
mbed_official 48:e9a2c7cb57a4 714
mbed_official 48:e9a2c7cb57a4 715 // Thread Service Calls declarations
mbed_official 48:e9a2c7cb57a4 716 SVC_2_1(svcThreadCreate, osThreadId, const osThreadDef_t *, void *, RET_pointer)
mbed_official 48:e9a2c7cb57a4 717 SVC_0_1(svcThreadGetId, osThreadId, RET_pointer)
mbed_official 48:e9a2c7cb57a4 718 SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 719 SVC_0_1(svcThreadYield, osStatus, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 720 SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 721 SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority)
c1728p9 123:58563e6cba1e 722 SVC_2_3(svcThreadGetInfo, os_InRegs osEvent, osThreadId, osThreadInfo, RET_osEvent)
mbed_official 48:e9a2c7cb57a4 723
mbed_official 48:e9a2c7cb57a4 724 // Thread Service Calls
mbed_official 48:e9a2c7cb57a4 725
mbed_official 48:e9a2c7cb57a4 726 /// Create a thread and add it to Active Threads and set it to state READY
mbed_official 48:e9a2c7cb57a4 727 osThreadId svcThreadCreate (const osThreadDef_t *thread_def, void *argument) {
mbed_official 48:e9a2c7cb57a4 728 P_TCB ptcb;
mbed_official 48:e9a2c7cb57a4 729 OS_TID tsk;
mbed_official 48:e9a2c7cb57a4 730 void *stk;
mbed_official 48:e9a2c7cb57a4 731
mbed_official 48:e9a2c7cb57a4 732 if ((thread_def == NULL) ||
mbed_official 48:e9a2c7cb57a4 733 (thread_def->pthread == NULL) ||
mbed_official 48:e9a2c7cb57a4 734 (thread_def->tpriority < osPriorityIdle) ||
mbed_official 48:e9a2c7cb57a4 735 (thread_def->tpriority > osPriorityRealtime)) {
mbed_official 68:d3d0e710b443 736 sysThreadError(osErrorParameter);
mbed_official 68:d3d0e710b443 737 return NULL;
mbed_official 48:e9a2c7cb57a4 738 }
mbed_official 48:e9a2c7cb57a4 739
mbed_official 85:ef0a22cdf839 740 #ifdef __MBED_CMSIS_RTOS_CA9
mbed_official 85:ef0a22cdf839 741 if (thread_def->stacksize != 0) { // Custom stack size
mbed_official 85:ef0a22cdf839 742 stk = (void *)thread_def->stack_pointer;
mbed_official 85:ef0a22cdf839 743 } else { // Default stack size
mbed_official 85:ef0a22cdf839 744 stk = NULL;
mbed_official 85:ef0a22cdf839 745 }
mbed_official 85:ef0a22cdf839 746 #else
mbed_official 48:e9a2c7cb57a4 747 if (thread_def->stacksize != 0) { // Custom stack size
mbed_official 48:e9a2c7cb57a4 748 stk = rt_alloc_mem( // Allocate stack
mbed_official 48:e9a2c7cb57a4 749 os_stack_mem,
mbed_official 48:e9a2c7cb57a4 750 thread_def->stacksize
mbed_official 48:e9a2c7cb57a4 751 );
mbed_official 68:d3d0e710b443 752 if (stk == NULL) {
mbed_official 48:e9a2c7cb57a4 753 sysThreadError(osErrorNoMemory); // Out of memory
mbed_official 48:e9a2c7cb57a4 754 return NULL;
mbed_official 48:e9a2c7cb57a4 755 }
mbed_official 48:e9a2c7cb57a4 756 } else { // Default stack size
mbed_official 48:e9a2c7cb57a4 757 stk = NULL;
mbed_official 48:e9a2c7cb57a4 758 }
mbed_official 85:ef0a22cdf839 759 #endif
mbed_official 48:e9a2c7cb57a4 760
mbed_official 48:e9a2c7cb57a4 761 tsk = rt_tsk_create( // Create task
mbed_official 48:e9a2c7cb57a4 762 (FUNCP)thread_def->pthread, // Task function pointer
mbed_official 48:e9a2c7cb57a4 763 (thread_def->tpriority-osPriorityIdle+1) | // Task priority
mbed_official 48:e9a2c7cb57a4 764 (thread_def->stacksize << 8), // Task stack size in bytes
mbed_official 48:e9a2c7cb57a4 765 stk, // Pointer to task's stack
mbed_official 48:e9a2c7cb57a4 766 argument // Argument to the task
mbed_official 48:e9a2c7cb57a4 767 );
mbed_official 48:e9a2c7cb57a4 768
mbed_official 48:e9a2c7cb57a4 769 if (tsk == 0) { // Invalid task ID
mbed_official 85:ef0a22cdf839 770 #ifndef __MBED_CMSIS_RTOS_CA9
mbed_official 48:e9a2c7cb57a4 771 if (stk != NULL) {
mbed_official 48:e9a2c7cb57a4 772 rt_free_mem(os_stack_mem, stk); // Free allocated stack
mbed_official 48:e9a2c7cb57a4 773 }
mbed_official 85:ef0a22cdf839 774 #endif
mbed_official 48:e9a2c7cb57a4 775 sysThreadError(osErrorNoMemory); // Create task failed (Out of memory)
mbed_official 48:e9a2c7cb57a4 776 return NULL;
mbed_official 48:e9a2c7cb57a4 777 }
mbed_official 48:e9a2c7cb57a4 778
mbed_official 48:e9a2c7cb57a4 779 ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer
mbed_official 48:e9a2c7cb57a4 780
mbed_official 48:e9a2c7cb57a4 781 *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit;
mbed_official 48:e9a2c7cb57a4 782
mbed_official 48:e9a2c7cb57a4 783 return ptcb;
mbed_official 48:e9a2c7cb57a4 784 }
mbed_official 48:e9a2c7cb57a4 785
mbed_official 48:e9a2c7cb57a4 786 /// Return the thread ID of the current running thread
mbed_official 48:e9a2c7cb57a4 787 osThreadId svcThreadGetId (void) {
mbed_official 48:e9a2c7cb57a4 788 OS_TID tsk;
mbed_official 48:e9a2c7cb57a4 789
mbed_official 48:e9a2c7cb57a4 790 tsk = rt_tsk_self();
mbed_official 48:e9a2c7cb57a4 791 if (tsk == 0) return NULL;
mbed_official 48:e9a2c7cb57a4 792 return (P_TCB)os_active_TCB[tsk - 1];
mbed_official 48:e9a2c7cb57a4 793 }
mbed_official 48:e9a2c7cb57a4 794
mbed_official 48:e9a2c7cb57a4 795 /// Terminate execution of a thread and remove it from ActiveThreads
mbed_official 48:e9a2c7cb57a4 796 osStatus svcThreadTerminate (osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 797 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 798 P_TCB ptcb;
mbed_official 85:ef0a22cdf839 799 #ifndef __MBED_CMSIS_RTOS_CA9
mbed_official 48:e9a2c7cb57a4 800 void *stk;
mbed_official 85:ef0a22cdf839 801 #endif
mbed_official 48:e9a2c7cb57a4 802
mbed_official 48:e9a2c7cb57a4 803 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 48:e9a2c7cb57a4 804 if (ptcb == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 805
mbed_official 85:ef0a22cdf839 806 #ifndef __MBED_CMSIS_RTOS_CA9
mbed_official 48:e9a2c7cb57a4 807 stk = ptcb->priv_stack ? ptcb->stack : NULL; // Private stack
mbed_official 85:ef0a22cdf839 808 #endif
mbed_official 48:e9a2c7cb57a4 809
mbed_official 48:e9a2c7cb57a4 810 res = rt_tsk_delete(ptcb->task_id); // Delete task
mbed_official 48:e9a2c7cb57a4 811
mbed_official 48:e9a2c7cb57a4 812 if (res == OS_R_NOK) return osErrorResource; // Delete task failed
mbed_official 48:e9a2c7cb57a4 813
mbed_official 85:ef0a22cdf839 814 #ifndef __MBED_CMSIS_RTOS_CA9
mbed_official 68:d3d0e710b443 815 if (stk != NULL) {
mbed_official 48:e9a2c7cb57a4 816 rt_free_mem(os_stack_mem, stk); // Free private stack
mbed_official 48:e9a2c7cb57a4 817 }
mbed_official 85:ef0a22cdf839 818 #endif
mbed_official 48:e9a2c7cb57a4 819
mbed_official 48:e9a2c7cb57a4 820 return osOK;
mbed_official 48:e9a2c7cb57a4 821 }
mbed_official 48:e9a2c7cb57a4 822
mbed_official 48:e9a2c7cb57a4 823 /// Pass control to next thread that is in state READY
mbed_official 48:e9a2c7cb57a4 824 osStatus svcThreadYield (void) {
mbed_official 48:e9a2c7cb57a4 825 rt_tsk_pass(); // Pass control to next task
mbed_official 48:e9a2c7cb57a4 826 return osOK;
mbed_official 48:e9a2c7cb57a4 827 }
mbed_official 48:e9a2c7cb57a4 828
mbed_official 48:e9a2c7cb57a4 829 /// Change priority of an active thread
mbed_official 48:e9a2c7cb57a4 830 osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) {
mbed_official 48:e9a2c7cb57a4 831 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 832 P_TCB ptcb;
mbed_official 48:e9a2c7cb57a4 833
mbed_official 48:e9a2c7cb57a4 834 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 48:e9a2c7cb57a4 835 if (ptcb == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 836
mbed_official 48:e9a2c7cb57a4 837 if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) {
mbed_official 48:e9a2c7cb57a4 838 return osErrorValue;
mbed_official 48:e9a2c7cb57a4 839 }
mbed_official 48:e9a2c7cb57a4 840
mbed_official 48:e9a2c7cb57a4 841 res = rt_tsk_prio( // Change task priority
mbed_official 48:e9a2c7cb57a4 842 ptcb->task_id, // Task ID
mbed_official 48:e9a2c7cb57a4 843 priority - osPriorityIdle + 1 // New task priority
mbed_official 48:e9a2c7cb57a4 844 );
mbed_official 48:e9a2c7cb57a4 845
mbed_official 48:e9a2c7cb57a4 846 if (res == OS_R_NOK) return osErrorResource; // Change task priority failed
mbed_official 48:e9a2c7cb57a4 847
mbed_official 48:e9a2c7cb57a4 848 return osOK;
mbed_official 48:e9a2c7cb57a4 849 }
mbed_official 48:e9a2c7cb57a4 850
mbed_official 48:e9a2c7cb57a4 851 /// Get current priority of an active thread
mbed_official 48:e9a2c7cb57a4 852 osPriority svcThreadGetPriority (osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 853 P_TCB ptcb;
mbed_official 48:e9a2c7cb57a4 854
mbed_official 48:e9a2c7cb57a4 855 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 48:e9a2c7cb57a4 856 if (ptcb == NULL) return osPriorityError;
mbed_official 48:e9a2c7cb57a4 857
mbed_official 68:d3d0e710b443 858 return (osPriority)(ptcb->prio - 1 + osPriorityIdle);
mbed_official 48:e9a2c7cb57a4 859 }
mbed_official 48:e9a2c7cb57a4 860
c1728p9 123:58563e6cba1e 861 /// Get info from an active thread
c1728p9 123:58563e6cba1e 862 os_InRegs osEvent_type svcThreadGetInfo (osThreadId thread_id, osThreadInfo info) {
c1728p9 123:58563e6cba1e 863 P_TCB ptcb;
c1728p9 123:58563e6cba1e 864 osEvent ret;
c1728p9 123:58563e6cba1e 865 ret.status = osOK;
c1728p9 123:58563e6cba1e 866
c1728p9 123:58563e6cba1e 867 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
c1728p9 123:58563e6cba1e 868 if (ptcb == NULL) {
c1728p9 123:58563e6cba1e 869 ret.status = osErrorValue;
c1728p9 123:58563e6cba1e 870 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
c1728p9 123:58563e6cba1e 871 osEvent_ret_status;
c1728p9 123:58563e6cba1e 872 return;
c1728p9 123:58563e6cba1e 873 #else
c1728p9 123:58563e6cba1e 874 return osEvent_ret_status;
c1728p9 123:58563e6cba1e 875 #endif
c1728p9 123:58563e6cba1e 876 }
c1728p9 123:58563e6cba1e 877
c1728p9 123:58563e6cba1e 878 if (osThreadInfoStackSize == info) {
c1728p9 123:58563e6cba1e 879 uint32_t size;
c1728p9 123:58563e6cba1e 880 size = ptcb->priv_stack;
c1728p9 123:58563e6cba1e 881 if (0 == size) {
c1728p9 123:58563e6cba1e 882 // This is an OS task - always a fixed size
c1728p9 123:58563e6cba1e 883 size = os_stackinfo & 0x3FFFF;
c1728p9 123:58563e6cba1e 884 }
c1728p9 123:58563e6cba1e 885 ret.value.v = size;
c1728p9 123:58563e6cba1e 886 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
c1728p9 123:58563e6cba1e 887 osEvent_ret_value;
c1728p9 123:58563e6cba1e 888 return;
c1728p9 123:58563e6cba1e 889 #else
c1728p9 123:58563e6cba1e 890 return osEvent_ret_value;
c1728p9 123:58563e6cba1e 891 #endif
c1728p9 123:58563e6cba1e 892 }
c1728p9 123:58563e6cba1e 893
c1728p9 123:58563e6cba1e 894 if (osThreadInfoStackMax == info) {
c1728p9 123:58563e6cba1e 895 // Cortex-A RTX does not have stack init so
c1728p9 123:58563e6cba1e 896 // the maximum stack usage cannot be obtained.
c1728p9 123:58563e6cba1e 897 ret.status = osErrorResource;
c1728p9 123:58563e6cba1e 898 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
c1728p9 123:58563e6cba1e 899 osEvent_ret_status;
c1728p9 123:58563e6cba1e 900 return;
c1728p9 123:58563e6cba1e 901 #else
c1728p9 123:58563e6cba1e 902 return osEvent_ret_status;
c1728p9 123:58563e6cba1e 903 #endif
c1728p9 123:58563e6cba1e 904 }
c1728p9 123:58563e6cba1e 905
c1728p9 123:58563e6cba1e 906 if (osThreadInfoEntry == info) {
c1728p9 123:58563e6cba1e 907 ret.value.p = (void*)ptcb->ptask;
c1728p9 123:58563e6cba1e 908 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
c1728p9 123:58563e6cba1e 909 osEvent_ret_value;
c1728p9 123:58563e6cba1e 910 return;
c1728p9 123:58563e6cba1e 911 #else
c1728p9 123:58563e6cba1e 912 return osEvent_ret_value;
c1728p9 123:58563e6cba1e 913 #endif
c1728p9 123:58563e6cba1e 914 }
c1728p9 123:58563e6cba1e 915
c1728p9 123:58563e6cba1e 916 if (osThreadInfoArg == info) {
c1728p9 123:58563e6cba1e 917 ret.value.p = (void*)ptcb->argv;
c1728p9 123:58563e6cba1e 918 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
c1728p9 123:58563e6cba1e 919 osEvent_ret_value;
c1728p9 123:58563e6cba1e 920 return;
c1728p9 123:58563e6cba1e 921 #else
c1728p9 123:58563e6cba1e 922 return osEvent_ret_value;
c1728p9 123:58563e6cba1e 923 #endif
c1728p9 123:58563e6cba1e 924 }
c1728p9 123:58563e6cba1e 925
c1728p9 123:58563e6cba1e 926 // Unsupported option so return error
c1728p9 123:58563e6cba1e 927 ret.status = osErrorParameter;
c1728p9 123:58563e6cba1e 928 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
c1728p9 123:58563e6cba1e 929 osEvent_ret_status;
c1728p9 123:58563e6cba1e 930 return;
c1728p9 123:58563e6cba1e 931 #else
c1728p9 123:58563e6cba1e 932 return osEvent_ret_status;
c1728p9 123:58563e6cba1e 933 #endif
c1728p9 123:58563e6cba1e 934 }
mbed_official 48:e9a2c7cb57a4 935
mbed_official 48:e9a2c7cb57a4 936 // Thread Public API
mbed_official 48:e9a2c7cb57a4 937
mbed_official 48:e9a2c7cb57a4 938 /// Create a thread and add it to Active Threads and set it to state READY
mbed_official 48:e9a2c7cb57a4 939 osThreadId osThreadCreate (const osThreadDef_t *thread_def, void *argument) {
mbed_official 48:e9a2c7cb57a4 940 if (__exceptional_mode()) return NULL; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 941 if ((__get_mode() != MODE_USR) && (os_running == 0)) {
mbed_official 48:e9a2c7cb57a4 942 // Privileged and not running
mbed_official 48:e9a2c7cb57a4 943 return svcThreadCreate(thread_def, argument);
mbed_official 48:e9a2c7cb57a4 944 } else {
c1728p9 123:58563e6cba1e 945 osThreadId id;
c1728p9 123:58563e6cba1e 946 osMutexWait(osMutexId_osThreadMutex, osWaitForever);
c1728p9 123:58563e6cba1e 947 // Thread mutex must be held when a thread is created or terminated
c1728p9 123:58563e6cba1e 948 id = __svcThreadCreate(thread_def, argument);
c1728p9 123:58563e6cba1e 949 osMutexRelease(osMutexId_osThreadMutex);
c1728p9 123:58563e6cba1e 950 return id;
mbed_official 48:e9a2c7cb57a4 951 }
mbed_official 48:e9a2c7cb57a4 952 }
mbed_official 48:e9a2c7cb57a4 953
mbed_official 48:e9a2c7cb57a4 954 /// Return the thread ID of the current running thread
mbed_official 48:e9a2c7cb57a4 955 osThreadId osThreadGetId (void) {
mbed_official 48:e9a2c7cb57a4 956 if (__exceptional_mode()) return NULL; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 957 return __svcThreadGetId();
mbed_official 48:e9a2c7cb57a4 958 }
mbed_official 48:e9a2c7cb57a4 959
mbed_official 48:e9a2c7cb57a4 960 /// Terminate execution of a thread and remove it from ActiveThreads
mbed_official 48:e9a2c7cb57a4 961 osStatus osThreadTerminate (osThreadId thread_id) {
c1728p9 123:58563e6cba1e 962 osStatus status;
mbed_official 48:e9a2c7cb57a4 963 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
c1728p9 123:58563e6cba1e 964 osMutexWait(osMutexId_osThreadMutex, osWaitForever);
c1728p9 123:58563e6cba1e 965 sysThreadTerminate(thread_id);
c1728p9 123:58563e6cba1e 966 // Thread mutex must be held when a thread is created or terminated
c1728p9 123:58563e6cba1e 967 status = __svcThreadTerminate(thread_id);
c1728p9 123:58563e6cba1e 968 osMutexRelease(osMutexId_osThreadMutex);
c1728p9 123:58563e6cba1e 969 return status;
mbed_official 48:e9a2c7cb57a4 970 }
mbed_official 48:e9a2c7cb57a4 971
mbed_official 48:e9a2c7cb57a4 972 /// Pass control to next thread that is in state READY
mbed_official 48:e9a2c7cb57a4 973 osStatus osThreadYield (void) {
mbed_official 48:e9a2c7cb57a4 974 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 975 return __svcThreadYield();
mbed_official 48:e9a2c7cb57a4 976 }
mbed_official 48:e9a2c7cb57a4 977
mbed_official 48:e9a2c7cb57a4 978 /// Change priority of an active thread
mbed_official 48:e9a2c7cb57a4 979 osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) {
mbed_official 48:e9a2c7cb57a4 980 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 981 return __svcThreadSetPriority(thread_id, priority);
mbed_official 48:e9a2c7cb57a4 982 }
mbed_official 48:e9a2c7cb57a4 983
mbed_official 48:e9a2c7cb57a4 984 /// Get current priority of an active thread
mbed_official 48:e9a2c7cb57a4 985 osPriority osThreadGetPriority (osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 986 if (__exceptional_mode()) return osPriorityError;// Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 987 return __svcThreadGetPriority(thread_id);
mbed_official 48:e9a2c7cb57a4 988 }
mbed_official 48:e9a2c7cb57a4 989
mbed_official 48:e9a2c7cb57a4 990 /// INTERNAL - Not Public
mbed_official 48:e9a2c7cb57a4 991 /// Auto Terminate Thread on exit (used implicitly when thread exists)
mbed_official 68:d3d0e710b443 992 __NO_RETURN void osThreadExit (void) {
c1728p9 123:58563e6cba1e 993 osThreadId id;
c1728p9 123:58563e6cba1e 994 // Thread mutex must be held when a thread is created or terminated
c1728p9 123:58563e6cba1e 995 // Note - the mutex will be released automatically by the os when
c1728p9 123:58563e6cba1e 996 // the thread is terminated
c1728p9 123:58563e6cba1e 997 osMutexWait(osMutexId_osThreadMutex, osWaitForever);
c1728p9 123:58563e6cba1e 998 id = __svcThreadGetId();
c1728p9 123:58563e6cba1e 999 sysThreadTerminate(id);
c1728p9 123:58563e6cba1e 1000 __svcThreadTerminate(id);
mbed_official 48:e9a2c7cb57a4 1001 for (;;); // Should never come here
mbed_official 48:e9a2c7cb57a4 1002 }
mbed_official 48:e9a2c7cb57a4 1003
mbed_official 48:e9a2c7cb57a4 1004 #ifdef __MBED_CMSIS_RTOS_CA9
mbed_official 48:e9a2c7cb57a4 1005 /// Get current thread state
mbed_official 48:e9a2c7cb57a4 1006 uint8_t osThreadGetState (osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 1007 P_TCB ptcb;
mbed_official 68:d3d0e710b443 1008
mbed_official 48:e9a2c7cb57a4 1009 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 68:d3d0e710b443 1010
mbed_official 48:e9a2c7cb57a4 1011 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 117:4c105b8d7cae 1012 if (ptcb == NULL) return INACTIVE;
mbed_official 68:d3d0e710b443 1013
mbed_official 48:e9a2c7cb57a4 1014 return ptcb->state;
mbed_official 48:e9a2c7cb57a4 1015 }
mbed_official 48:e9a2c7cb57a4 1016 #endif
mbed_official 48:e9a2c7cb57a4 1017
c1728p9 123:58563e6cba1e 1018 /// Get the requested info from the specified active thread
c1728p9 123:58563e6cba1e 1019 os_InRegs osEvent _osThreadGetInfo(osThreadId thread_id, osThreadInfo info) {
c1728p9 123:58563e6cba1e 1020 osEvent ret;
c1728p9 123:58563e6cba1e 1021 if (__exceptional_mode()) {
c1728p9 123:58563e6cba1e 1022 ret.status = osErrorISR;
c1728p9 123:58563e6cba1e 1023 return ret; // Not allowed in ISR
c1728p9 123:58563e6cba1e 1024 }
c1728p9 123:58563e6cba1e 1025 return __svcThreadGetInfo(thread_id, info);
c1728p9 123:58563e6cba1e 1026 }
c1728p9 123:58563e6cba1e 1027
c1728p9 123:58563e6cba1e 1028 osThreadEnumId _osThreadsEnumStart() {
c1728p9 123:58563e6cba1e 1029 static uint32_t thread_enum_index;
c1728p9 123:58563e6cba1e 1030 osMutexWait(osMutexId_osThreadMutex, osWaitForever);
c1728p9 123:58563e6cba1e 1031 thread_enum_index = 0;
c1728p9 123:58563e6cba1e 1032 return &thread_enum_index;
c1728p9 123:58563e6cba1e 1033 }
c1728p9 123:58563e6cba1e 1034
c1728p9 123:58563e6cba1e 1035 osThreadId _osThreadEnumNext(osThreadEnumId enum_id) {
c1728p9 123:58563e6cba1e 1036 uint32_t i;
c1728p9 123:58563e6cba1e 1037 osThreadId id = NULL;
c1728p9 123:58563e6cba1e 1038 uint32_t *index = (uint32_t*)enum_id;
c1728p9 123:58563e6cba1e 1039 for (i = *index; i < os_maxtaskrun; i++) {
c1728p9 123:58563e6cba1e 1040 if (os_active_TCB[i] != NULL) {
c1728p9 123:58563e6cba1e 1041 id = (osThreadId)os_active_TCB[i];
c1728p9 123:58563e6cba1e 1042 break;
c1728p9 123:58563e6cba1e 1043 }
c1728p9 123:58563e6cba1e 1044 }
c1728p9 123:58563e6cba1e 1045 if (i == os_maxtaskrun) {
c1728p9 123:58563e6cba1e 1046 // Include the idle task at the end of the enumeration
c1728p9 123:58563e6cba1e 1047 id = &os_idle_TCB;
c1728p9 123:58563e6cba1e 1048 }
c1728p9 123:58563e6cba1e 1049 *index = i + 1;
c1728p9 123:58563e6cba1e 1050 return id;
c1728p9 123:58563e6cba1e 1051 }
c1728p9 123:58563e6cba1e 1052
c1728p9 123:58563e6cba1e 1053 osStatus _osThreadEnumFree(osThreadEnumId enum_id) {
c1728p9 123:58563e6cba1e 1054 uint32_t *index = (uint32_t*)enum_id;
c1728p9 123:58563e6cba1e 1055 *index = 0;
c1728p9 123:58563e6cba1e 1056 osMutexRelease(osMutexId_osThreadMutex);
c1728p9 123:58563e6cba1e 1057 return osOK;
c1728p9 123:58563e6cba1e 1058 }
c1728p9 123:58563e6cba1e 1059
mbed_official 48:e9a2c7cb57a4 1060 // ==== Generic Wait Functions ====
mbed_official 48:e9a2c7cb57a4 1061
mbed_official 48:e9a2c7cb57a4 1062 // Generic Wait Service Calls declarations
mbed_official 48:e9a2c7cb57a4 1063 SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1064 #if osFeature_Wait != 0
mbed_official 48:e9a2c7cb57a4 1065 SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent)
mbed_official 48:e9a2c7cb57a4 1066 #endif
mbed_official 48:e9a2c7cb57a4 1067
mbed_official 48:e9a2c7cb57a4 1068 // Generic Wait Service Calls
mbed_official 48:e9a2c7cb57a4 1069
mbed_official 48:e9a2c7cb57a4 1070 /// Wait for Timeout (Time Delay)
mbed_official 48:e9a2c7cb57a4 1071 osStatus svcDelay (uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1072 if (millisec == 0) return osOK;
mbed_official 48:e9a2c7cb57a4 1073 rt_dly_wait(rt_ms2tick(millisec));
mbed_official 48:e9a2c7cb57a4 1074 return osEventTimeout;
mbed_official 48:e9a2c7cb57a4 1075 }
mbed_official 48:e9a2c7cb57a4 1076
mbed_official 48:e9a2c7cb57a4 1077 /// Wait for Signal, Message, Mail, or Timeout
mbed_official 48:e9a2c7cb57a4 1078 #if osFeature_Wait != 0
mbed_official 48:e9a2c7cb57a4 1079 os_InRegs osEvent_type svcWait (uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1080 osEvent ret;
mbed_official 48:e9a2c7cb57a4 1081
mbed_official 48:e9a2c7cb57a4 1082 if (millisec == 0) {
mbed_official 48:e9a2c7cb57a4 1083 ret.status = osOK;
mbed_official 67:63988a2238f7 1084 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 1085 osEvent_ret_status;
mbed_official 67:63988a2238f7 1086 return;
mbed_official 67:63988a2238f7 1087 #else
mbed_official 48:e9a2c7cb57a4 1088 return osEvent_ret_status;
mbed_official 67:63988a2238f7 1089 #endif
mbed_official 48:e9a2c7cb57a4 1090 }
mbed_official 48:e9a2c7cb57a4 1091
mbed_official 48:e9a2c7cb57a4 1092 /* To Do: osEventSignal, osEventMessage, osEventMail */
mbed_official 48:e9a2c7cb57a4 1093 rt_dly_wait(rt_ms2tick(millisec));
mbed_official 48:e9a2c7cb57a4 1094 ret.status = osEventTimeout;
mbed_official 48:e9a2c7cb57a4 1095
mbed_official 67:63988a2238f7 1096 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 1097 osEvent_ret_status;
mbed_official 67:63988a2238f7 1098 return;
mbed_official 67:63988a2238f7 1099 #else
mbed_official 48:e9a2c7cb57a4 1100 return osEvent_ret_status;
mbed_official 67:63988a2238f7 1101 #endif
mbed_official 48:e9a2c7cb57a4 1102 }
mbed_official 48:e9a2c7cb57a4 1103 #endif
mbed_official 48:e9a2c7cb57a4 1104
mbed_official 48:e9a2c7cb57a4 1105
mbed_official 48:e9a2c7cb57a4 1106 // Generic Wait API
mbed_official 48:e9a2c7cb57a4 1107
mbed_official 48:e9a2c7cb57a4 1108 /// Wait for Timeout (Time Delay)
mbed_official 48:e9a2c7cb57a4 1109 osStatus osDelay (uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1110 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1111 return __svcDelay(millisec);
mbed_official 48:e9a2c7cb57a4 1112 }
mbed_official 48:e9a2c7cb57a4 1113
mbed_official 48:e9a2c7cb57a4 1114 /// Wait for Signal, Message, Mail, or Timeout
mbed_official 48:e9a2c7cb57a4 1115 os_InRegs osEvent osWait (uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1116 osEvent ret;
mbed_official 48:e9a2c7cb57a4 1117
mbed_official 48:e9a2c7cb57a4 1118 #if osFeature_Wait == 0
mbed_official 48:e9a2c7cb57a4 1119 ret.status = osErrorOS;
mbed_official 48:e9a2c7cb57a4 1120 return ret;
mbed_official 48:e9a2c7cb57a4 1121 #else
mbed_official 48:e9a2c7cb57a4 1122 if (__exceptional_mode()) { // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1123 ret.status = osErrorISR;
mbed_official 48:e9a2c7cb57a4 1124 return ret;
mbed_official 48:e9a2c7cb57a4 1125 }
mbed_official 48:e9a2c7cb57a4 1126 return __svcWait(millisec);
mbed_official 48:e9a2c7cb57a4 1127 #endif
mbed_official 48:e9a2c7cb57a4 1128 }
mbed_official 48:e9a2c7cb57a4 1129
mbed_official 48:e9a2c7cb57a4 1130
mbed_official 48:e9a2c7cb57a4 1131 // ==== Timer Management ====
mbed_official 48:e9a2c7cb57a4 1132
mbed_official 48:e9a2c7cb57a4 1133 // Timer definitions
mbed_official 48:e9a2c7cb57a4 1134 #define osTimerInvalid 0
mbed_official 48:e9a2c7cb57a4 1135 #define osTimerStopped 1
mbed_official 48:e9a2c7cb57a4 1136 #define osTimerRunning 2
mbed_official 48:e9a2c7cb57a4 1137
mbed_official 68:d3d0e710b443 1138 // Timer structures
mbed_official 48:e9a2c7cb57a4 1139
mbed_official 48:e9a2c7cb57a4 1140 typedef struct os_timer_cb_ { // Timer Control Block
mbed_official 48:e9a2c7cb57a4 1141 struct os_timer_cb_ *next; // Pointer to next active Timer
mbed_official 48:e9a2c7cb57a4 1142 uint8_t state; // Timer State
mbed_official 48:e9a2c7cb57a4 1143 uint8_t type; // Timer Type (Periodic/One-shot)
mbed_official 48:e9a2c7cb57a4 1144 uint16_t reserved; // Reserved
mbed_official 48:e9a2c7cb57a4 1145 uint16_t tcnt; // Timer Delay Count
mbed_official 68:d3d0e710b443 1146 uint16_t icnt; // Timer Initial Count
mbed_official 48:e9a2c7cb57a4 1147 void *arg; // Timer Function Argument
mbed_official 48:e9a2c7cb57a4 1148 const osTimerDef_t *timer; // Pointer to Timer definition
mbed_official 48:e9a2c7cb57a4 1149 } os_timer_cb;
mbed_official 48:e9a2c7cb57a4 1150
mbed_official 48:e9a2c7cb57a4 1151 // Timer variables
mbed_official 48:e9a2c7cb57a4 1152 os_timer_cb *os_timer_head; // Pointer to first active Timer
mbed_official 48:e9a2c7cb57a4 1153
mbed_official 48:e9a2c7cb57a4 1154
mbed_official 48:e9a2c7cb57a4 1155 // Timer Helper Functions
mbed_official 48:e9a2c7cb57a4 1156
mbed_official 48:e9a2c7cb57a4 1157 // Insert Timer into the list sorted by time
mbed_official 48:e9a2c7cb57a4 1158 static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) {
mbed_official 48:e9a2c7cb57a4 1159 os_timer_cb *p, *prev;
mbed_official 48:e9a2c7cb57a4 1160
mbed_official 48:e9a2c7cb57a4 1161 prev = NULL;
mbed_official 48:e9a2c7cb57a4 1162 p = os_timer_head;
mbed_official 48:e9a2c7cb57a4 1163 while (p != NULL) {
mbed_official 48:e9a2c7cb57a4 1164 if (tcnt < p->tcnt) break;
mbed_official 48:e9a2c7cb57a4 1165 tcnt -= p->tcnt;
mbed_official 48:e9a2c7cb57a4 1166 prev = p;
mbed_official 48:e9a2c7cb57a4 1167 p = p->next;
mbed_official 48:e9a2c7cb57a4 1168 }
mbed_official 48:e9a2c7cb57a4 1169 pt->next = p;
mbed_official 48:e9a2c7cb57a4 1170 pt->tcnt = (uint16_t)tcnt;
mbed_official 48:e9a2c7cb57a4 1171 if (p != NULL) {
mbed_official 48:e9a2c7cb57a4 1172 p->tcnt -= pt->tcnt;
mbed_official 48:e9a2c7cb57a4 1173 }
mbed_official 48:e9a2c7cb57a4 1174 if (prev != NULL) {
mbed_official 48:e9a2c7cb57a4 1175 prev->next = pt;
mbed_official 48:e9a2c7cb57a4 1176 } else {
mbed_official 48:e9a2c7cb57a4 1177 os_timer_head = pt;
mbed_official 48:e9a2c7cb57a4 1178 }
mbed_official 48:e9a2c7cb57a4 1179 }
mbed_official 48:e9a2c7cb57a4 1180
mbed_official 48:e9a2c7cb57a4 1181 // Remove Timer from the list
mbed_official 48:e9a2c7cb57a4 1182 static int rt_timer_remove (os_timer_cb *pt) {
mbed_official 48:e9a2c7cb57a4 1183 os_timer_cb *p, *prev;
mbed_official 48:e9a2c7cb57a4 1184
mbed_official 48:e9a2c7cb57a4 1185 prev = NULL;
mbed_official 48:e9a2c7cb57a4 1186 p = os_timer_head;
mbed_official 48:e9a2c7cb57a4 1187 while (p != NULL) {
mbed_official 48:e9a2c7cb57a4 1188 if (p == pt) break;
mbed_official 48:e9a2c7cb57a4 1189 prev = p;
mbed_official 48:e9a2c7cb57a4 1190 p = p->next;
mbed_official 48:e9a2c7cb57a4 1191 }
mbed_official 48:e9a2c7cb57a4 1192 if (p == NULL) return -1;
mbed_official 48:e9a2c7cb57a4 1193 if (prev != NULL) {
mbed_official 48:e9a2c7cb57a4 1194 prev->next = pt->next;
mbed_official 48:e9a2c7cb57a4 1195 } else {
mbed_official 48:e9a2c7cb57a4 1196 os_timer_head = pt->next;
mbed_official 48:e9a2c7cb57a4 1197 }
mbed_official 48:e9a2c7cb57a4 1198 if (pt->next != NULL) {
mbed_official 48:e9a2c7cb57a4 1199 pt->next->tcnt += pt->tcnt;
mbed_official 48:e9a2c7cb57a4 1200 }
mbed_official 48:e9a2c7cb57a4 1201
mbed_official 48:e9a2c7cb57a4 1202 return 0;
mbed_official 48:e9a2c7cb57a4 1203 }
mbed_official 48:e9a2c7cb57a4 1204
mbed_official 48:e9a2c7cb57a4 1205
mbed_official 48:e9a2c7cb57a4 1206 // Timer Service Calls declarations
mbed_official 48:e9a2c7cb57a4 1207 SVC_3_1(svcTimerCreate, osTimerId, const osTimerDef_t *, os_timer_type, void *, RET_pointer)
mbed_official 48:e9a2c7cb57a4 1208 SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1209 SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1210 SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1211 SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback)
mbed_official 48:e9a2c7cb57a4 1212
mbed_official 48:e9a2c7cb57a4 1213 // Timer Management Service Calls
mbed_official 48:e9a2c7cb57a4 1214
mbed_official 48:e9a2c7cb57a4 1215 /// Create timer
mbed_official 48:e9a2c7cb57a4 1216 osTimerId svcTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) {
mbed_official 48:e9a2c7cb57a4 1217 os_timer_cb *pt;
mbed_official 48:e9a2c7cb57a4 1218
mbed_official 48:e9a2c7cb57a4 1219 if ((timer_def == NULL) || (timer_def->ptimer == NULL)) {
mbed_official 48:e9a2c7cb57a4 1220 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1221 return NULL;
mbed_official 48:e9a2c7cb57a4 1222 }
mbed_official 48:e9a2c7cb57a4 1223
mbed_official 48:e9a2c7cb57a4 1224 pt = timer_def->timer;
mbed_official 48:e9a2c7cb57a4 1225 if (pt == NULL) {
mbed_official 48:e9a2c7cb57a4 1226 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1227 return NULL;
mbed_official 48:e9a2c7cb57a4 1228 }
mbed_official 48:e9a2c7cb57a4 1229
mbed_official 48:e9a2c7cb57a4 1230 if ((type != osTimerOnce) && (type != osTimerPeriodic)) {
mbed_official 48:e9a2c7cb57a4 1231 sysThreadError(osErrorValue);
mbed_official 48:e9a2c7cb57a4 1232 return NULL;
mbed_official 48:e9a2c7cb57a4 1233 }
mbed_official 48:e9a2c7cb57a4 1234
mbed_official 48:e9a2c7cb57a4 1235 if (osThreadId_osTimerThread == NULL) {
mbed_official 48:e9a2c7cb57a4 1236 sysThreadError(osErrorResource);
mbed_official 48:e9a2c7cb57a4 1237 return NULL;
mbed_official 48:e9a2c7cb57a4 1238 }
mbed_official 48:e9a2c7cb57a4 1239
mbed_official 48:e9a2c7cb57a4 1240 if (pt->state != osTimerInvalid){
mbed_official 48:e9a2c7cb57a4 1241 sysThreadError(osErrorResource);
mbed_official 48:e9a2c7cb57a4 1242 return NULL;
mbed_official 48:e9a2c7cb57a4 1243 }
mbed_official 48:e9a2c7cb57a4 1244
mbed_official 92:bc9729798a19 1245 pt->next = NULL;
mbed_official 48:e9a2c7cb57a4 1246 pt->state = osTimerStopped;
mbed_official 48:e9a2c7cb57a4 1247 pt->type = (uint8_t)type;
mbed_official 48:e9a2c7cb57a4 1248 pt->arg = argument;
mbed_official 48:e9a2c7cb57a4 1249 pt->timer = timer_def;
mbed_official 48:e9a2c7cb57a4 1250
mbed_official 48:e9a2c7cb57a4 1251 return (osTimerId)pt;
mbed_official 48:e9a2c7cb57a4 1252 }
mbed_official 48:e9a2c7cb57a4 1253
mbed_official 48:e9a2c7cb57a4 1254 /// Start or restart timer
mbed_official 48:e9a2c7cb57a4 1255 osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1256 os_timer_cb *pt;
mbed_official 48:e9a2c7cb57a4 1257 uint32_t tcnt;
mbed_official 48:e9a2c7cb57a4 1258
mbed_official 48:e9a2c7cb57a4 1259 pt = rt_id2obj(timer_id);
mbed_official 48:e9a2c7cb57a4 1260 if (pt == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1261
mbed_official 48:e9a2c7cb57a4 1262 tcnt = rt_ms2tick(millisec);
mbed_official 48:e9a2c7cb57a4 1263 if (tcnt == 0) return osErrorValue;
mbed_official 48:e9a2c7cb57a4 1264
mbed_official 48:e9a2c7cb57a4 1265 switch (pt->state) {
mbed_official 48:e9a2c7cb57a4 1266 case osTimerRunning:
mbed_official 48:e9a2c7cb57a4 1267 if (rt_timer_remove(pt) != 0) {
mbed_official 48:e9a2c7cb57a4 1268 return osErrorResource;
mbed_official 48:e9a2c7cb57a4 1269 }
mbed_official 48:e9a2c7cb57a4 1270 break;
mbed_official 48:e9a2c7cb57a4 1271 case osTimerStopped:
mbed_official 48:e9a2c7cb57a4 1272 pt->state = osTimerRunning;
mbed_official 48:e9a2c7cb57a4 1273 pt->icnt = (uint16_t)tcnt;
mbed_official 48:e9a2c7cb57a4 1274 break;
mbed_official 48:e9a2c7cb57a4 1275 default:
mbed_official 48:e9a2c7cb57a4 1276 return osErrorResource;
mbed_official 48:e9a2c7cb57a4 1277 }
mbed_official 68:d3d0e710b443 1278
mbed_official 48:e9a2c7cb57a4 1279 rt_timer_insert(pt, tcnt);
mbed_official 48:e9a2c7cb57a4 1280
mbed_official 48:e9a2c7cb57a4 1281 return osOK;
mbed_official 48:e9a2c7cb57a4 1282 }
mbed_official 48:e9a2c7cb57a4 1283
mbed_official 48:e9a2c7cb57a4 1284 /// Stop timer
mbed_official 48:e9a2c7cb57a4 1285 osStatus svcTimerStop (osTimerId timer_id) {
mbed_official 48:e9a2c7cb57a4 1286 os_timer_cb *pt;
mbed_official 48:e9a2c7cb57a4 1287
mbed_official 48:e9a2c7cb57a4 1288 pt = rt_id2obj(timer_id);
mbed_official 48:e9a2c7cb57a4 1289 if (pt == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1290
mbed_official 48:e9a2c7cb57a4 1291 if (pt->state != osTimerRunning) return osErrorResource;
mbed_official 48:e9a2c7cb57a4 1292
mbed_official 48:e9a2c7cb57a4 1293 pt->state = osTimerStopped;
mbed_official 48:e9a2c7cb57a4 1294
mbed_official 48:e9a2c7cb57a4 1295 if (rt_timer_remove(pt) != 0) {
mbed_official 48:e9a2c7cb57a4 1296 return osErrorResource;
mbed_official 48:e9a2c7cb57a4 1297 }
mbed_official 48:e9a2c7cb57a4 1298
mbed_official 48:e9a2c7cb57a4 1299 return osOK;
mbed_official 48:e9a2c7cb57a4 1300 }
mbed_official 48:e9a2c7cb57a4 1301
mbed_official 48:e9a2c7cb57a4 1302 /// Delete timer
mbed_official 48:e9a2c7cb57a4 1303 osStatus svcTimerDelete (osTimerId timer_id) {
mbed_official 48:e9a2c7cb57a4 1304 os_timer_cb *pt;
mbed_official 48:e9a2c7cb57a4 1305
mbed_official 48:e9a2c7cb57a4 1306 pt = rt_id2obj(timer_id);
mbed_official 48:e9a2c7cb57a4 1307 if (pt == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1308
mbed_official 48:e9a2c7cb57a4 1309 switch (pt->state) {
mbed_official 48:e9a2c7cb57a4 1310 case osTimerRunning:
mbed_official 48:e9a2c7cb57a4 1311 rt_timer_remove(pt);
mbed_official 48:e9a2c7cb57a4 1312 break;
mbed_official 48:e9a2c7cb57a4 1313 case osTimerStopped:
mbed_official 48:e9a2c7cb57a4 1314 break;
mbed_official 48:e9a2c7cb57a4 1315 default:
mbed_official 48:e9a2c7cb57a4 1316 return osErrorResource;
mbed_official 48:e9a2c7cb57a4 1317 }
mbed_official 48:e9a2c7cb57a4 1318
mbed_official 48:e9a2c7cb57a4 1319 pt->state = osTimerInvalid;
mbed_official 48:e9a2c7cb57a4 1320
mbed_official 48:e9a2c7cb57a4 1321 return osOK;
mbed_official 48:e9a2c7cb57a4 1322 }
mbed_official 48:e9a2c7cb57a4 1323
mbed_official 48:e9a2c7cb57a4 1324 /// Get timer callback parameters
mbed_official 48:e9a2c7cb57a4 1325 os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) {
mbed_official 48:e9a2c7cb57a4 1326 os_timer_cb *pt;
mbed_official 48:e9a2c7cb57a4 1327 osCallback ret;
mbed_official 48:e9a2c7cb57a4 1328
mbed_official 48:e9a2c7cb57a4 1329 pt = rt_id2obj(timer_id);
mbed_official 48:e9a2c7cb57a4 1330 if (pt == NULL) {
mbed_official 48:e9a2c7cb57a4 1331 ret.fp = NULL;
mbed_official 48:e9a2c7cb57a4 1332 ret.arg = NULL;
mbed_official 67:63988a2238f7 1333 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 1334 osCallback_ret;
mbed_official 67:63988a2238f7 1335 return;
mbed_official 67:63988a2238f7 1336 #else
mbed_official 48:e9a2c7cb57a4 1337 return osCallback_ret;
mbed_official 67:63988a2238f7 1338 #endif
mbed_official 48:e9a2c7cb57a4 1339 }
mbed_official 48:e9a2c7cb57a4 1340
mbed_official 48:e9a2c7cb57a4 1341 ret.fp = (void *)pt->timer->ptimer;
mbed_official 48:e9a2c7cb57a4 1342 ret.arg = pt->arg;
mbed_official 48:e9a2c7cb57a4 1343
mbed_official 67:63988a2238f7 1344 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 1345 osCallback_ret;
mbed_official 67:63988a2238f7 1346 return;
mbed_official 67:63988a2238f7 1347 #else
mbed_official 48:e9a2c7cb57a4 1348 return osCallback_ret;
mbed_official 67:63988a2238f7 1349 #endif
mbed_official 48:e9a2c7cb57a4 1350 }
mbed_official 48:e9a2c7cb57a4 1351
mbed_official 48:e9a2c7cb57a4 1352 static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
mbed_official 48:e9a2c7cb57a4 1353
mbed_official 48:e9a2c7cb57a4 1354 /// Timer Tick (called each SysTick)
mbed_official 48:e9a2c7cb57a4 1355 void sysTimerTick (void) {
mbed_official 48:e9a2c7cb57a4 1356 os_timer_cb *pt, *p;
mbed_official 48:e9a2c7cb57a4 1357
mbed_official 48:e9a2c7cb57a4 1358 p = os_timer_head;
mbed_official 48:e9a2c7cb57a4 1359 if (p == NULL) return;
mbed_official 48:e9a2c7cb57a4 1360
mbed_official 48:e9a2c7cb57a4 1361 p->tcnt--;
mbed_official 48:e9a2c7cb57a4 1362 while ((p != NULL) && (p->tcnt == 0)) {
mbed_official 48:e9a2c7cb57a4 1363 pt = p;
mbed_official 48:e9a2c7cb57a4 1364 p = p->next;
mbed_official 48:e9a2c7cb57a4 1365 os_timer_head = p;
mbed_official 48:e9a2c7cb57a4 1366 isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0);
mbed_official 48:e9a2c7cb57a4 1367 if (pt->type == osTimerPeriodic) {
mbed_official 48:e9a2c7cb57a4 1368 rt_timer_insert(pt, pt->icnt);
mbed_official 48:e9a2c7cb57a4 1369 } else {
mbed_official 48:e9a2c7cb57a4 1370 pt->state = osTimerStopped;
mbed_official 48:e9a2c7cb57a4 1371 }
mbed_official 48:e9a2c7cb57a4 1372 }
mbed_official 48:e9a2c7cb57a4 1373 }
mbed_official 48:e9a2c7cb57a4 1374
mbed_official 92:bc9729798a19 1375 /// Get user timers wake-up time
mbed_official 92:bc9729798a19 1376 uint32_t sysUserTimerWakeupTime (void) {
mbed_official 92:bc9729798a19 1377
mbed_official 92:bc9729798a19 1378 if (os_timer_head) {
mbed_official 92:bc9729798a19 1379 return os_timer_head->tcnt;
mbed_official 92:bc9729798a19 1380 }
mbed_official 92:bc9729798a19 1381 return 0xFFFF;
mbed_official 92:bc9729798a19 1382 }
mbed_official 92:bc9729798a19 1383
mbed_official 92:bc9729798a19 1384 /// Update user timers on resume
mbed_official 92:bc9729798a19 1385 void sysUserTimerUpdate (uint32_t sleep_time) {
mbed_official 92:bc9729798a19 1386
mbed_official 92:bc9729798a19 1387 while (os_timer_head && sleep_time) {
mbed_official 92:bc9729798a19 1388 if (sleep_time >= os_timer_head->tcnt) {
mbed_official 92:bc9729798a19 1389 sleep_time -= os_timer_head->tcnt;
mbed_official 92:bc9729798a19 1390 os_timer_head->tcnt = 1;
mbed_official 92:bc9729798a19 1391 sysTimerTick();
mbed_official 92:bc9729798a19 1392 } else {
mbed_official 92:bc9729798a19 1393 os_timer_head->tcnt -= sleep_time;
mbed_official 92:bc9729798a19 1394 break;
mbed_official 92:bc9729798a19 1395 }
mbed_official 92:bc9729798a19 1396 }
mbed_official 92:bc9729798a19 1397 }
mbed_official 92:bc9729798a19 1398
mbed_official 48:e9a2c7cb57a4 1399
mbed_official 48:e9a2c7cb57a4 1400 // Timer Management Public API
mbed_official 48:e9a2c7cb57a4 1401
mbed_official 48:e9a2c7cb57a4 1402 /// Create timer
mbed_official 48:e9a2c7cb57a4 1403 osTimerId osTimerCreate (const osTimerDef_t *timer_def, os_timer_type type, void *argument) {
mbed_official 48:e9a2c7cb57a4 1404 if (__exceptional_mode()) return NULL; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1405 if ((__get_mode() != MODE_USR) && (os_running == 0)) {
mbed_official 48:e9a2c7cb57a4 1406 // Privileged and not running
mbed_official 48:e9a2c7cb57a4 1407 return svcTimerCreate(timer_def, type, argument);
mbed_official 48:e9a2c7cb57a4 1408 } else {
mbed_official 48:e9a2c7cb57a4 1409 return __svcTimerCreate(timer_def, type, argument);
mbed_official 48:e9a2c7cb57a4 1410 }
mbed_official 48:e9a2c7cb57a4 1411 }
mbed_official 48:e9a2c7cb57a4 1412
mbed_official 48:e9a2c7cb57a4 1413 /// Start or restart timer
mbed_official 48:e9a2c7cb57a4 1414 osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1415 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1416 return __svcTimerStart(timer_id, millisec);
mbed_official 48:e9a2c7cb57a4 1417 }
mbed_official 48:e9a2c7cb57a4 1418
mbed_official 48:e9a2c7cb57a4 1419 /// Stop timer
mbed_official 48:e9a2c7cb57a4 1420 osStatus osTimerStop (osTimerId timer_id) {
mbed_official 48:e9a2c7cb57a4 1421 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1422 return __svcTimerStop(timer_id);
mbed_official 48:e9a2c7cb57a4 1423 }
mbed_official 48:e9a2c7cb57a4 1424
mbed_official 48:e9a2c7cb57a4 1425 /// Delete timer
mbed_official 48:e9a2c7cb57a4 1426 osStatus osTimerDelete (osTimerId timer_id) {
mbed_official 48:e9a2c7cb57a4 1427 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1428 return __svcTimerDelete(timer_id);
mbed_official 48:e9a2c7cb57a4 1429 }
mbed_official 48:e9a2c7cb57a4 1430
mbed_official 48:e9a2c7cb57a4 1431 /// INTERNAL - Not Public
mbed_official 48:e9a2c7cb57a4 1432 /// Get timer callback parameters (used by OS Timer Thread)
mbed_official 68:d3d0e710b443 1433 os_InRegs osCallback osTimerCall (osTimerId timer_id) {
mbed_official 68:d3d0e710b443 1434 return __svcTimerCall(timer_id);
mbed_official 48:e9a2c7cb57a4 1435 }
mbed_official 48:e9a2c7cb57a4 1436
mbed_official 48:e9a2c7cb57a4 1437
mbed_official 48:e9a2c7cb57a4 1438 // Timer Thread
mbed_official 48:e9a2c7cb57a4 1439 __NO_RETURN void osTimerThread (void const *argument) {
mbed_official 48:e9a2c7cb57a4 1440 osCallback cb;
mbed_official 48:e9a2c7cb57a4 1441 osEvent evt;
mbed_official 48:e9a2c7cb57a4 1442
mbed_official 48:e9a2c7cb57a4 1443 for (;;) {
mbed_official 48:e9a2c7cb57a4 1444 evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever);
mbed_official 48:e9a2c7cb57a4 1445 if (evt.status == osEventMessage) {
mbed_official 48:e9a2c7cb57a4 1446 cb = osTimerCall(evt.value.p);
mbed_official 48:e9a2c7cb57a4 1447 if (cb.fp != NULL) {
mbed_official 48:e9a2c7cb57a4 1448 (*(os_ptimer)cb.fp)(cb.arg);
mbed_official 48:e9a2c7cb57a4 1449 }
mbed_official 48:e9a2c7cb57a4 1450 }
mbed_official 48:e9a2c7cb57a4 1451 }
mbed_official 48:e9a2c7cb57a4 1452 }
mbed_official 48:e9a2c7cb57a4 1453
mbed_official 48:e9a2c7cb57a4 1454
mbed_official 48:e9a2c7cb57a4 1455 // ==== Signal Management ====
mbed_official 48:e9a2c7cb57a4 1456
mbed_official 48:e9a2c7cb57a4 1457 // Signal Service Calls declarations
mbed_official 48:e9a2c7cb57a4 1458 SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t)
mbed_official 48:e9a2c7cb57a4 1459 SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t)
mbed_official 48:e9a2c7cb57a4 1460 SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent)
mbed_official 48:e9a2c7cb57a4 1461
mbed_official 48:e9a2c7cb57a4 1462 // Signal Service Calls
mbed_official 48:e9a2c7cb57a4 1463
mbed_official 48:e9a2c7cb57a4 1464 /// Set the specified Signal Flags of an active thread
mbed_official 48:e9a2c7cb57a4 1465 int32_t svcSignalSet (osThreadId thread_id, int32_t signals) {
mbed_official 48:e9a2c7cb57a4 1466 P_TCB ptcb;
mbed_official 48:e9a2c7cb57a4 1467 int32_t sig;
mbed_official 48:e9a2c7cb57a4 1468
mbed_official 48:e9a2c7cb57a4 1469 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 48:e9a2c7cb57a4 1470 if (ptcb == NULL) return 0x80000000;
mbed_official 48:e9a2c7cb57a4 1471
mbed_official 48:e9a2c7cb57a4 1472 if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
mbed_official 48:e9a2c7cb57a4 1473
mbed_official 48:e9a2c7cb57a4 1474 sig = ptcb->events; // Previous signal flags
mbed_official 48:e9a2c7cb57a4 1475
mbed_official 48:e9a2c7cb57a4 1476 rt_evt_set(signals, ptcb->task_id); // Set event flags
mbed_official 48:e9a2c7cb57a4 1477
mbed_official 48:e9a2c7cb57a4 1478 return sig;
mbed_official 48:e9a2c7cb57a4 1479 }
mbed_official 48:e9a2c7cb57a4 1480
mbed_official 48:e9a2c7cb57a4 1481 /// Clear the specified Signal Flags of an active thread
mbed_official 48:e9a2c7cb57a4 1482 int32_t svcSignalClear (osThreadId thread_id, int32_t signals) {
mbed_official 48:e9a2c7cb57a4 1483 P_TCB ptcb;
mbed_official 48:e9a2c7cb57a4 1484 int32_t sig;
mbed_official 48:e9a2c7cb57a4 1485
mbed_official 48:e9a2c7cb57a4 1486 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 48:e9a2c7cb57a4 1487 if (ptcb == NULL) return 0x80000000;
mbed_official 48:e9a2c7cb57a4 1488
mbed_official 48:e9a2c7cb57a4 1489 if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
mbed_official 48:e9a2c7cb57a4 1490
mbed_official 48:e9a2c7cb57a4 1491 sig = ptcb->events; // Previous signal flags
mbed_official 48:e9a2c7cb57a4 1492
mbed_official 48:e9a2c7cb57a4 1493 rt_evt_clr(signals, ptcb->task_id); // Clear event flags
mbed_official 48:e9a2c7cb57a4 1494
mbed_official 48:e9a2c7cb57a4 1495 return sig;
mbed_official 48:e9a2c7cb57a4 1496 }
mbed_official 48:e9a2c7cb57a4 1497
mbed_official 48:e9a2c7cb57a4 1498 /// Wait for one or more Signal Flags to become signaled for the current RUNNING thread
mbed_official 48:e9a2c7cb57a4 1499 os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1500 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 1501 osEvent ret;
mbed_official 48:e9a2c7cb57a4 1502
mbed_official 48:e9a2c7cb57a4 1503 if (signals & (0xFFFFFFFF << osFeature_Signals)) {
mbed_official 48:e9a2c7cb57a4 1504 ret.status = osErrorValue;
mbed_official 67:63988a2238f7 1505 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 1506 osEvent_ret_status;
mbed_official 67:63988a2238f7 1507 return;
mbed_official 67:63988a2238f7 1508 #else
mbed_official 48:e9a2c7cb57a4 1509 return osEvent_ret_status;
mbed_official 67:63988a2238f7 1510 #endif
mbed_official 48:e9a2c7cb57a4 1511 }
mbed_official 48:e9a2c7cb57a4 1512
mbed_official 48:e9a2c7cb57a4 1513 if (signals != 0) { // Wait for all specified signals
mbed_official 48:e9a2c7cb57a4 1514 res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE);
mbed_official 48:e9a2c7cb57a4 1515 } else { // Wait for any signal
mbed_official 48:e9a2c7cb57a4 1516 res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE);
mbed_official 48:e9a2c7cb57a4 1517 }
mbed_official 48:e9a2c7cb57a4 1518
mbed_official 48:e9a2c7cb57a4 1519 if (res == OS_R_EVT) {
mbed_official 48:e9a2c7cb57a4 1520 ret.status = osEventSignal;
mbed_official 48:e9a2c7cb57a4 1521 ret.value.signals = signals ? signals : os_tsk.run->waits;
mbed_official 48:e9a2c7cb57a4 1522 } else {
mbed_official 48:e9a2c7cb57a4 1523 ret.status = millisec ? osEventTimeout : osOK;
mbed_official 48:e9a2c7cb57a4 1524 ret.value.signals = 0;
mbed_official 48:e9a2c7cb57a4 1525 }
mbed_official 48:e9a2c7cb57a4 1526
mbed_official 67:63988a2238f7 1527 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 1528 osEvent_ret_value;
mbed_official 67:63988a2238f7 1529 return;
mbed_official 67:63988a2238f7 1530 #else
mbed_official 48:e9a2c7cb57a4 1531 return osEvent_ret_value;
mbed_official 67:63988a2238f7 1532 #endif
mbed_official 48:e9a2c7cb57a4 1533 }
mbed_official 48:e9a2c7cb57a4 1534
mbed_official 48:e9a2c7cb57a4 1535
mbed_official 48:e9a2c7cb57a4 1536 // Signal ISR Calls
mbed_official 48:e9a2c7cb57a4 1537
mbed_official 48:e9a2c7cb57a4 1538 /// Set the specified Signal Flags of an active thread
mbed_official 48:e9a2c7cb57a4 1539 static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) {
mbed_official 48:e9a2c7cb57a4 1540 P_TCB ptcb;
mbed_official 48:e9a2c7cb57a4 1541 int32_t sig;
mbed_official 48:e9a2c7cb57a4 1542
mbed_official 48:e9a2c7cb57a4 1543 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 48:e9a2c7cb57a4 1544 if (ptcb == NULL) return 0x80000000;
mbed_official 48:e9a2c7cb57a4 1545
mbed_official 48:e9a2c7cb57a4 1546 if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
mbed_official 48:e9a2c7cb57a4 1547
mbed_official 48:e9a2c7cb57a4 1548 sig = ptcb->events; // Previous signal flags
mbed_official 48:e9a2c7cb57a4 1549
mbed_official 48:e9a2c7cb57a4 1550 isr_evt_set(signals, ptcb->task_id); // Set event flags
mbed_official 48:e9a2c7cb57a4 1551
mbed_official 48:e9a2c7cb57a4 1552 return sig;
mbed_official 48:e9a2c7cb57a4 1553 }
mbed_official 48:e9a2c7cb57a4 1554
mbed_official 48:e9a2c7cb57a4 1555
mbed_official 48:e9a2c7cb57a4 1556 // Signal Public API
mbed_official 48:e9a2c7cb57a4 1557
mbed_official 48:e9a2c7cb57a4 1558 /// Set the specified Signal Flags of an active thread
mbed_official 48:e9a2c7cb57a4 1559 int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
mbed_official 48:e9a2c7cb57a4 1560 if (__exceptional_mode()) { // in ISR
mbed_official 68:d3d0e710b443 1561 return isrSignalSet(thread_id, signals);
mbed_official 48:e9a2c7cb57a4 1562 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 1563 return __svcSignalSet(thread_id, signals);
mbed_official 48:e9a2c7cb57a4 1564 }
mbed_official 48:e9a2c7cb57a4 1565 }
mbed_official 48:e9a2c7cb57a4 1566
mbed_official 48:e9a2c7cb57a4 1567 /// Clear the specified Signal Flags of an active thread
mbed_official 48:e9a2c7cb57a4 1568 int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
mbed_official 48:e9a2c7cb57a4 1569 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1570 return __svcSignalClear(thread_id, signals);
mbed_official 48:e9a2c7cb57a4 1571 }
mbed_official 48:e9a2c7cb57a4 1572
mbed_official 48:e9a2c7cb57a4 1573 /// Wait for one or more Signal Flags to become signaled for the current RUNNING thread
mbed_official 48:e9a2c7cb57a4 1574 os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1575 osEvent ret;
mbed_official 48:e9a2c7cb57a4 1576
mbed_official 48:e9a2c7cb57a4 1577 if (__exceptional_mode()) { // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1578 ret.status = osErrorISR;
mbed_official 48:e9a2c7cb57a4 1579 return ret;
mbed_official 48:e9a2c7cb57a4 1580 }
mbed_official 48:e9a2c7cb57a4 1581 return __svcSignalWait(signals, millisec);
mbed_official 48:e9a2c7cb57a4 1582 }
mbed_official 48:e9a2c7cb57a4 1583
mbed_official 48:e9a2c7cb57a4 1584
mbed_official 48:e9a2c7cb57a4 1585 // ==== Mutex Management ====
mbed_official 48:e9a2c7cb57a4 1586
mbed_official 48:e9a2c7cb57a4 1587 // Mutex Service Calls declarations
mbed_official 48:e9a2c7cb57a4 1588 SVC_1_1(svcMutexCreate, osMutexId, const osMutexDef_t *, RET_pointer)
mbed_official 48:e9a2c7cb57a4 1589 SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1590 SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1591 SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1592
mbed_official 48:e9a2c7cb57a4 1593 // Mutex Service Calls
mbed_official 48:e9a2c7cb57a4 1594
mbed_official 48:e9a2c7cb57a4 1595 /// Create and Initialize a Mutex object
mbed_official 48:e9a2c7cb57a4 1596 osMutexId svcMutexCreate (const osMutexDef_t *mutex_def) {
mbed_official 48:e9a2c7cb57a4 1597 OS_ID mut;
mbed_official 48:e9a2c7cb57a4 1598
mbed_official 48:e9a2c7cb57a4 1599 if (mutex_def == NULL) {
mbed_official 48:e9a2c7cb57a4 1600 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1601 return NULL;
mbed_official 48:e9a2c7cb57a4 1602 }
mbed_official 48:e9a2c7cb57a4 1603
mbed_official 48:e9a2c7cb57a4 1604 mut = mutex_def->mutex;
mbed_official 48:e9a2c7cb57a4 1605 if (mut == NULL) {
mbed_official 48:e9a2c7cb57a4 1606 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1607 return NULL;
mbed_official 48:e9a2c7cb57a4 1608 }
mbed_official 48:e9a2c7cb57a4 1609
mbed_official 48:e9a2c7cb57a4 1610 if (((P_MUCB)mut)->cb_type != 0) {
mbed_official 48:e9a2c7cb57a4 1611 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1612 return NULL;
mbed_official 48:e9a2c7cb57a4 1613 }
mbed_official 48:e9a2c7cb57a4 1614
mbed_official 48:e9a2c7cb57a4 1615 rt_mut_init(mut); // Initialize Mutex
mbed_official 48:e9a2c7cb57a4 1616
mbed_official 48:e9a2c7cb57a4 1617 return mut;
mbed_official 48:e9a2c7cb57a4 1618 }
mbed_official 48:e9a2c7cb57a4 1619
mbed_official 48:e9a2c7cb57a4 1620 /// Wait until a Mutex becomes available
mbed_official 48:e9a2c7cb57a4 1621 osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1622 OS_ID mut;
mbed_official 48:e9a2c7cb57a4 1623 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 1624
mbed_official 48:e9a2c7cb57a4 1625 mut = rt_id2obj(mutex_id);
mbed_official 48:e9a2c7cb57a4 1626 if (mut == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1627
mbed_official 48:e9a2c7cb57a4 1628 if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1629
mbed_official 48:e9a2c7cb57a4 1630 res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex
mbed_official 48:e9a2c7cb57a4 1631
mbed_official 48:e9a2c7cb57a4 1632 if (res == OS_R_TMO) {
mbed_official 48:e9a2c7cb57a4 1633 return (millisec ? osErrorTimeoutResource : osErrorResource);
mbed_official 48:e9a2c7cb57a4 1634 }
mbed_official 48:e9a2c7cb57a4 1635
mbed_official 48:e9a2c7cb57a4 1636 return osOK;
mbed_official 48:e9a2c7cb57a4 1637 }
mbed_official 48:e9a2c7cb57a4 1638
mbed_official 48:e9a2c7cb57a4 1639 /// Release a Mutex that was obtained with osMutexWait
mbed_official 48:e9a2c7cb57a4 1640 osStatus svcMutexRelease (osMutexId mutex_id) {
mbed_official 48:e9a2c7cb57a4 1641 OS_ID mut;
mbed_official 48:e9a2c7cb57a4 1642 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 1643
mbed_official 48:e9a2c7cb57a4 1644 mut = rt_id2obj(mutex_id);
mbed_official 48:e9a2c7cb57a4 1645 if (mut == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1646
mbed_official 48:e9a2c7cb57a4 1647 if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1648
mbed_official 48:e9a2c7cb57a4 1649 res = rt_mut_release(mut); // Release Mutex
mbed_official 48:e9a2c7cb57a4 1650
mbed_official 48:e9a2c7cb57a4 1651 if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter
mbed_official 48:e9a2c7cb57a4 1652
mbed_official 48:e9a2c7cb57a4 1653 return osOK;
mbed_official 48:e9a2c7cb57a4 1654 }
mbed_official 48:e9a2c7cb57a4 1655
mbed_official 48:e9a2c7cb57a4 1656 /// Delete a Mutex that was created by osMutexCreate
mbed_official 48:e9a2c7cb57a4 1657 osStatus svcMutexDelete (osMutexId mutex_id) {
mbed_official 48:e9a2c7cb57a4 1658 OS_ID mut;
mbed_official 48:e9a2c7cb57a4 1659
mbed_official 48:e9a2c7cb57a4 1660 mut = rt_id2obj(mutex_id);
mbed_official 48:e9a2c7cb57a4 1661 if (mut == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1662
mbed_official 48:e9a2c7cb57a4 1663 if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1664
mbed_official 48:e9a2c7cb57a4 1665 rt_mut_delete(mut); // Release Mutex
mbed_official 48:e9a2c7cb57a4 1666
mbed_official 48:e9a2c7cb57a4 1667 return osOK;
mbed_official 48:e9a2c7cb57a4 1668 }
mbed_official 48:e9a2c7cb57a4 1669
mbed_official 48:e9a2c7cb57a4 1670
mbed_official 48:e9a2c7cb57a4 1671 // Mutex Public API
mbed_official 48:e9a2c7cb57a4 1672
mbed_official 48:e9a2c7cb57a4 1673 /// Create and Initialize a Mutex object
mbed_official 48:e9a2c7cb57a4 1674 osMutexId osMutexCreate (const osMutexDef_t *mutex_def) {
mbed_official 48:e9a2c7cb57a4 1675 if (__exceptional_mode()) return NULL; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1676 if ((__get_mode() != MODE_USR) && (os_running == 0)) {
mbed_official 48:e9a2c7cb57a4 1677 // Privileged and not running
mbed_official 48:e9a2c7cb57a4 1678 return svcMutexCreate(mutex_def);
mbed_official 48:e9a2c7cb57a4 1679 } else {
mbed_official 48:e9a2c7cb57a4 1680 return __svcMutexCreate(mutex_def);
mbed_official 48:e9a2c7cb57a4 1681 }
mbed_official 48:e9a2c7cb57a4 1682 }
mbed_official 48:e9a2c7cb57a4 1683
mbed_official 48:e9a2c7cb57a4 1684 /// Wait until a Mutex becomes available
mbed_official 48:e9a2c7cb57a4 1685 osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1686 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1687 return __svcMutexWait(mutex_id, millisec);
mbed_official 48:e9a2c7cb57a4 1688 }
mbed_official 48:e9a2c7cb57a4 1689
mbed_official 48:e9a2c7cb57a4 1690 /// Release a Mutex that was obtained with osMutexWait
mbed_official 48:e9a2c7cb57a4 1691 osStatus osMutexRelease (osMutexId mutex_id) {
mbed_official 48:e9a2c7cb57a4 1692 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1693 return __svcMutexRelease(mutex_id);
mbed_official 48:e9a2c7cb57a4 1694 }
mbed_official 48:e9a2c7cb57a4 1695
mbed_official 48:e9a2c7cb57a4 1696 /// Delete a Mutex that was created by osMutexCreate
mbed_official 48:e9a2c7cb57a4 1697 osStatus osMutexDelete (osMutexId mutex_id) {
mbed_official 48:e9a2c7cb57a4 1698 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1699 return __svcMutexDelete(mutex_id);
mbed_official 48:e9a2c7cb57a4 1700 }
mbed_official 48:e9a2c7cb57a4 1701
mbed_official 48:e9a2c7cb57a4 1702
mbed_official 48:e9a2c7cb57a4 1703 // ==== Semaphore Management ====
mbed_official 48:e9a2c7cb57a4 1704
mbed_official 48:e9a2c7cb57a4 1705 // Semaphore Service Calls declarations
mbed_official 48:e9a2c7cb57a4 1706 SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer)
mbed_official 48:e9a2c7cb57a4 1707 SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t)
mbed_official 48:e9a2c7cb57a4 1708 SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1709 SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1710
mbed_official 48:e9a2c7cb57a4 1711 // Semaphore Service Calls
mbed_official 48:e9a2c7cb57a4 1712
mbed_official 48:e9a2c7cb57a4 1713 /// Create and Initialize a Semaphore object
mbed_official 48:e9a2c7cb57a4 1714 osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
mbed_official 48:e9a2c7cb57a4 1715 OS_ID sem;
mbed_official 48:e9a2c7cb57a4 1716
mbed_official 48:e9a2c7cb57a4 1717 if (semaphore_def == NULL) {
mbed_official 48:e9a2c7cb57a4 1718 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1719 return NULL;
mbed_official 48:e9a2c7cb57a4 1720 }
mbed_official 48:e9a2c7cb57a4 1721
mbed_official 48:e9a2c7cb57a4 1722 sem = semaphore_def->semaphore;
mbed_official 48:e9a2c7cb57a4 1723 if (sem == NULL) {
mbed_official 48:e9a2c7cb57a4 1724 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1725 return NULL;
mbed_official 48:e9a2c7cb57a4 1726 }
mbed_official 48:e9a2c7cb57a4 1727
mbed_official 48:e9a2c7cb57a4 1728 if (((P_SCB)sem)->cb_type != 0) {
mbed_official 48:e9a2c7cb57a4 1729 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1730 return NULL;
mbed_official 48:e9a2c7cb57a4 1731 }
mbed_official 48:e9a2c7cb57a4 1732
mbed_official 48:e9a2c7cb57a4 1733 if (count > osFeature_Semaphore) {
mbed_official 48:e9a2c7cb57a4 1734 sysThreadError(osErrorValue);
mbed_official 48:e9a2c7cb57a4 1735 return NULL;
mbed_official 48:e9a2c7cb57a4 1736 }
mbed_official 48:e9a2c7cb57a4 1737
mbed_official 48:e9a2c7cb57a4 1738 rt_sem_init(sem, count); // Initialize Semaphore
mbed_official 68:d3d0e710b443 1739
mbed_official 48:e9a2c7cb57a4 1740 return sem;
mbed_official 48:e9a2c7cb57a4 1741 }
mbed_official 48:e9a2c7cb57a4 1742
mbed_official 48:e9a2c7cb57a4 1743 /// Wait until a Semaphore becomes available
mbed_official 48:e9a2c7cb57a4 1744 int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1745 OS_ID sem;
mbed_official 48:e9a2c7cb57a4 1746 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 1747
mbed_official 48:e9a2c7cb57a4 1748 sem = rt_id2obj(semaphore_id);
mbed_official 48:e9a2c7cb57a4 1749 if (sem == NULL) return -1;
mbed_official 48:e9a2c7cb57a4 1750
mbed_official 48:e9a2c7cb57a4 1751 if (((P_SCB)sem)->cb_type != SCB) return -1;
mbed_official 48:e9a2c7cb57a4 1752
mbed_official 48:e9a2c7cb57a4 1753 res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore
mbed_official 48:e9a2c7cb57a4 1754
mbed_official 48:e9a2c7cb57a4 1755 if (res == OS_R_TMO) return 0; // Timeout
mbed_official 48:e9a2c7cb57a4 1756
mbed_official 48:e9a2c7cb57a4 1757 return (((P_SCB)sem)->tokens + 1);
mbed_official 48:e9a2c7cb57a4 1758 }
mbed_official 48:e9a2c7cb57a4 1759
mbed_official 48:e9a2c7cb57a4 1760 /// Release a Semaphore
mbed_official 48:e9a2c7cb57a4 1761 osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) {
mbed_official 48:e9a2c7cb57a4 1762 OS_ID sem;
mbed_official 48:e9a2c7cb57a4 1763
mbed_official 48:e9a2c7cb57a4 1764 sem = rt_id2obj(semaphore_id);
mbed_official 48:e9a2c7cb57a4 1765 if (sem == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1766
mbed_official 48:e9a2c7cb57a4 1767 if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1768
mbed_official 48:e9a2c7cb57a4 1769 if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource;
mbed_official 68:d3d0e710b443 1770
mbed_official 48:e9a2c7cb57a4 1771 rt_sem_send(sem); // Release Semaphore
mbed_official 48:e9a2c7cb57a4 1772
mbed_official 48:e9a2c7cb57a4 1773 return osOK;
mbed_official 48:e9a2c7cb57a4 1774 }
mbed_official 48:e9a2c7cb57a4 1775
mbed_official 48:e9a2c7cb57a4 1776 /// Delete a Semaphore that was created by osSemaphoreCreate
mbed_official 48:e9a2c7cb57a4 1777 osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) {
mbed_official 48:e9a2c7cb57a4 1778 OS_ID sem;
mbed_official 48:e9a2c7cb57a4 1779
mbed_official 48:e9a2c7cb57a4 1780 sem = rt_id2obj(semaphore_id);
mbed_official 48:e9a2c7cb57a4 1781 if (sem == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1782
mbed_official 48:e9a2c7cb57a4 1783 if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1784
mbed_official 48:e9a2c7cb57a4 1785 rt_sem_delete(sem); // Delete Semaphore
mbed_official 48:e9a2c7cb57a4 1786
mbed_official 48:e9a2c7cb57a4 1787 return osOK;
mbed_official 48:e9a2c7cb57a4 1788 }
mbed_official 48:e9a2c7cb57a4 1789
mbed_official 48:e9a2c7cb57a4 1790
mbed_official 48:e9a2c7cb57a4 1791 // Semaphore ISR Calls
mbed_official 48:e9a2c7cb57a4 1792
mbed_official 48:e9a2c7cb57a4 1793 /// Release a Semaphore
mbed_official 48:e9a2c7cb57a4 1794 static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) {
mbed_official 48:e9a2c7cb57a4 1795 OS_ID sem;
mbed_official 48:e9a2c7cb57a4 1796
mbed_official 48:e9a2c7cb57a4 1797 sem = rt_id2obj(semaphore_id);
mbed_official 48:e9a2c7cb57a4 1798 if (sem == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1799
mbed_official 48:e9a2c7cb57a4 1800 if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1801
mbed_official 48:e9a2c7cb57a4 1802 if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource;
mbed_official 48:e9a2c7cb57a4 1803
mbed_official 48:e9a2c7cb57a4 1804 isr_sem_send(sem); // Release Semaphore
mbed_official 48:e9a2c7cb57a4 1805
mbed_official 48:e9a2c7cb57a4 1806 return osOK;
mbed_official 48:e9a2c7cb57a4 1807 }
mbed_official 48:e9a2c7cb57a4 1808
mbed_official 48:e9a2c7cb57a4 1809
mbed_official 48:e9a2c7cb57a4 1810 // Semaphore Public API
mbed_official 48:e9a2c7cb57a4 1811
mbed_official 48:e9a2c7cb57a4 1812 /// Create and Initialize a Semaphore object
mbed_official 48:e9a2c7cb57a4 1813 osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
mbed_official 48:e9a2c7cb57a4 1814 if (__exceptional_mode()) return NULL; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1815 if ((__get_mode() != MODE_USR) && (os_running == 0)) {
mbed_official 48:e9a2c7cb57a4 1816 // Privileged and not running
mbed_official 48:e9a2c7cb57a4 1817 return svcSemaphoreCreate(semaphore_def, count);
mbed_official 48:e9a2c7cb57a4 1818 } else {
mbed_official 48:e9a2c7cb57a4 1819 return __svcSemaphoreCreate(semaphore_def, count);
mbed_official 48:e9a2c7cb57a4 1820 }
mbed_official 48:e9a2c7cb57a4 1821 }
mbed_official 48:e9a2c7cb57a4 1822
mbed_official 48:e9a2c7cb57a4 1823 /// Wait until a Semaphore becomes available
mbed_official 48:e9a2c7cb57a4 1824 int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1825 if (__exceptional_mode()) return -1; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1826 return __svcSemaphoreWait(semaphore_id, millisec);
mbed_official 48:e9a2c7cb57a4 1827 }
mbed_official 48:e9a2c7cb57a4 1828
mbed_official 48:e9a2c7cb57a4 1829 /// Release a Semaphore
mbed_official 48:e9a2c7cb57a4 1830 osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) {
mbed_official 48:e9a2c7cb57a4 1831 if (__exceptional_mode()) { // in ISR
mbed_official 48:e9a2c7cb57a4 1832 return isrSemaphoreRelease(semaphore_id);
mbed_official 48:e9a2c7cb57a4 1833 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 1834 return __svcSemaphoreRelease(semaphore_id);
mbed_official 48:e9a2c7cb57a4 1835 }
mbed_official 48:e9a2c7cb57a4 1836 }
mbed_official 48:e9a2c7cb57a4 1837
mbed_official 48:e9a2c7cb57a4 1838 /// Delete a Semaphore that was created by osSemaphoreCreate
mbed_official 48:e9a2c7cb57a4 1839 osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) {
mbed_official 48:e9a2c7cb57a4 1840 if (__exceptional_mode()) return osErrorISR; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1841 return __svcSemaphoreDelete(semaphore_id);
mbed_official 48:e9a2c7cb57a4 1842 }
mbed_official 48:e9a2c7cb57a4 1843
mbed_official 48:e9a2c7cb57a4 1844
mbed_official 48:e9a2c7cb57a4 1845 // ==== Memory Management Functions ====
mbed_official 48:e9a2c7cb57a4 1846
mbed_official 48:e9a2c7cb57a4 1847 // Memory Management Helper Functions
mbed_official 48:e9a2c7cb57a4 1848
mbed_official 48:e9a2c7cb57a4 1849 // Clear Memory Box (Zero init)
mbed_official 48:e9a2c7cb57a4 1850 static void rt_clr_box (void *box_mem, void *box) {
mbed_official 48:e9a2c7cb57a4 1851 uint32_t *p, n;
mbed_official 48:e9a2c7cb57a4 1852
mbed_official 48:e9a2c7cb57a4 1853 if (box) {
mbed_official 48:e9a2c7cb57a4 1854 p = box;
mbed_official 48:e9a2c7cb57a4 1855 for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) {
mbed_official 48:e9a2c7cb57a4 1856 *p++ = 0;
mbed_official 48:e9a2c7cb57a4 1857 }
mbed_official 48:e9a2c7cb57a4 1858 }
mbed_official 48:e9a2c7cb57a4 1859 }
mbed_official 48:e9a2c7cb57a4 1860
mbed_official 48:e9a2c7cb57a4 1861 // Memory Management Service Calls declarations
mbed_official 48:e9a2c7cb57a4 1862 SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer)
mbed_official 48:e9a2c7cb57a4 1863 SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer)
mbed_official 48:e9a2c7cb57a4 1864 SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1865
mbed_official 48:e9a2c7cb57a4 1866 // Memory Management Service & ISR Calls
mbed_official 48:e9a2c7cb57a4 1867
mbed_official 48:e9a2c7cb57a4 1868 /// Create and Initialize memory pool
mbed_official 48:e9a2c7cb57a4 1869 osPoolId svcPoolCreate (const osPoolDef_t *pool_def) {
mbed_official 48:e9a2c7cb57a4 1870 uint32_t blk_sz;
mbed_official 48:e9a2c7cb57a4 1871
mbed_official 48:e9a2c7cb57a4 1872 if ((pool_def == NULL) ||
mbed_official 48:e9a2c7cb57a4 1873 (pool_def->pool_sz == 0) ||
mbed_official 48:e9a2c7cb57a4 1874 (pool_def->item_sz == 0) ||
mbed_official 48:e9a2c7cb57a4 1875 (pool_def->pool == NULL)) {
mbed_official 48:e9a2c7cb57a4 1876 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1877 return NULL;
mbed_official 48:e9a2c7cb57a4 1878 }
mbed_official 48:e9a2c7cb57a4 1879
mbed_official 48:e9a2c7cb57a4 1880 blk_sz = (pool_def->item_sz + 3) & ~3;
mbed_official 48:e9a2c7cb57a4 1881
mbed_official 48:e9a2c7cb57a4 1882 _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz);
mbed_official 48:e9a2c7cb57a4 1883
mbed_official 48:e9a2c7cb57a4 1884 return pool_def->pool;
mbed_official 48:e9a2c7cb57a4 1885 }
mbed_official 48:e9a2c7cb57a4 1886
mbed_official 48:e9a2c7cb57a4 1887 /// Allocate a memory block from a memory pool
mbed_official 48:e9a2c7cb57a4 1888 void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) {
mbed_official 48:e9a2c7cb57a4 1889 void *ptr;
mbed_official 48:e9a2c7cb57a4 1890
mbed_official 48:e9a2c7cb57a4 1891 if (pool_id == NULL) return NULL;
mbed_official 48:e9a2c7cb57a4 1892
mbed_official 48:e9a2c7cb57a4 1893 ptr = rt_alloc_box(pool_id);
mbed_official 48:e9a2c7cb57a4 1894 if (clr) {
mbed_official 48:e9a2c7cb57a4 1895 rt_clr_box(pool_id, ptr);
mbed_official 48:e9a2c7cb57a4 1896 }
mbed_official 48:e9a2c7cb57a4 1897
mbed_official 48:e9a2c7cb57a4 1898 return ptr;
mbed_official 48:e9a2c7cb57a4 1899 }
mbed_official 48:e9a2c7cb57a4 1900
mbed_official 48:e9a2c7cb57a4 1901 /// Return an allocated memory block back to a specific memory pool
mbed_official 48:e9a2c7cb57a4 1902 osStatus sysPoolFree (osPoolId pool_id, void *block) {
mbed_official 48:e9a2c7cb57a4 1903 int32_t res;
mbed_official 68:d3d0e710b443 1904
mbed_official 48:e9a2c7cb57a4 1905 if (pool_id == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1906
mbed_official 48:e9a2c7cb57a4 1907 res = rt_free_box(pool_id, block);
mbed_official 48:e9a2c7cb57a4 1908 if (res != 0) return osErrorValue;
mbed_official 48:e9a2c7cb57a4 1909
mbed_official 48:e9a2c7cb57a4 1910 return osOK;
mbed_official 48:e9a2c7cb57a4 1911 }
mbed_official 48:e9a2c7cb57a4 1912
mbed_official 48:e9a2c7cb57a4 1913
mbed_official 48:e9a2c7cb57a4 1914 // Memory Management Public API
mbed_official 48:e9a2c7cb57a4 1915
mbed_official 48:e9a2c7cb57a4 1916 /// Create and Initialize memory pool
mbed_official 48:e9a2c7cb57a4 1917 osPoolId osPoolCreate (const osPoolDef_t *pool_def) {
mbed_official 48:e9a2c7cb57a4 1918 if (__exceptional_mode()) return NULL; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 1919 if ((__get_mode() != MODE_USR) && (os_running == 0)) {
mbed_official 48:e9a2c7cb57a4 1920 // Privileged and not running
mbed_official 48:e9a2c7cb57a4 1921 return svcPoolCreate(pool_def);
mbed_official 48:e9a2c7cb57a4 1922 } else {
mbed_official 48:e9a2c7cb57a4 1923 return __svcPoolCreate(pool_def);
mbed_official 48:e9a2c7cb57a4 1924 }
mbed_official 48:e9a2c7cb57a4 1925 }
mbed_official 48:e9a2c7cb57a4 1926
mbed_official 48:e9a2c7cb57a4 1927 /// Allocate a memory block from a memory pool
mbed_official 48:e9a2c7cb57a4 1928 void *osPoolAlloc (osPoolId pool_id) {
mbed_official 48:e9a2c7cb57a4 1929 if (__get_mode() != MODE_USR) { // in ISR or Privileged
mbed_official 48:e9a2c7cb57a4 1930 return sysPoolAlloc(pool_id, 0);
mbed_official 48:e9a2c7cb57a4 1931 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 1932 return __sysPoolAlloc(pool_id, 0);
mbed_official 48:e9a2c7cb57a4 1933 }
mbed_official 48:e9a2c7cb57a4 1934 }
mbed_official 48:e9a2c7cb57a4 1935
mbed_official 48:e9a2c7cb57a4 1936 /// Allocate a memory block from a memory pool and set memory block to zero
mbed_official 48:e9a2c7cb57a4 1937 void *osPoolCAlloc (osPoolId pool_id) {
mbed_official 48:e9a2c7cb57a4 1938 if (__get_mode() != MODE_USR) { // in ISR or Privileged
mbed_official 48:e9a2c7cb57a4 1939 return sysPoolAlloc(pool_id, 1);
mbed_official 48:e9a2c7cb57a4 1940 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 1941 return __sysPoolAlloc(pool_id, 1);
mbed_official 48:e9a2c7cb57a4 1942 }
mbed_official 48:e9a2c7cb57a4 1943 }
mbed_official 48:e9a2c7cb57a4 1944
mbed_official 48:e9a2c7cb57a4 1945 /// Return an allocated memory block back to a specific memory pool
mbed_official 48:e9a2c7cb57a4 1946 osStatus osPoolFree (osPoolId pool_id, void *block) {
mbed_official 48:e9a2c7cb57a4 1947 if (__get_mode() != MODE_USR) { // in ISR or Privileged
mbed_official 48:e9a2c7cb57a4 1948 return sysPoolFree(pool_id, block);
mbed_official 48:e9a2c7cb57a4 1949 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 1950 return __sysPoolFree(pool_id, block);
mbed_official 48:e9a2c7cb57a4 1951 }
mbed_official 48:e9a2c7cb57a4 1952 }
mbed_official 48:e9a2c7cb57a4 1953
mbed_official 48:e9a2c7cb57a4 1954
mbed_official 48:e9a2c7cb57a4 1955 // ==== Message Queue Management Functions ====
mbed_official 48:e9a2c7cb57a4 1956
mbed_official 48:e9a2c7cb57a4 1957 // Message Queue Management Service Calls declarations
mbed_official 48:e9a2c7cb57a4 1958 SVC_2_1(svcMessageCreate, osMessageQId, const osMessageQDef_t *, osThreadId, RET_pointer)
mbed_official 48:e9a2c7cb57a4 1959 SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 1960 SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent)
mbed_official 48:e9a2c7cb57a4 1961
mbed_official 48:e9a2c7cb57a4 1962 // Message Queue Service Calls
mbed_official 48:e9a2c7cb57a4 1963
mbed_official 48:e9a2c7cb57a4 1964 /// Create and Initialize Message Queue
mbed_official 48:e9a2c7cb57a4 1965 osMessageQId svcMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 1966
mbed_official 48:e9a2c7cb57a4 1967 if ((queue_def == NULL) ||
mbed_official 48:e9a2c7cb57a4 1968 (queue_def->queue_sz == 0) ||
mbed_official 48:e9a2c7cb57a4 1969 (queue_def->pool == NULL)) {
mbed_official 48:e9a2c7cb57a4 1970 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1971 return NULL;
mbed_official 48:e9a2c7cb57a4 1972 }
mbed_official 68:d3d0e710b443 1973
mbed_official 48:e9a2c7cb57a4 1974 if (((P_MCB)queue_def->pool)->cb_type != 0) {
mbed_official 48:e9a2c7cb57a4 1975 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 1976 return NULL;
mbed_official 48:e9a2c7cb57a4 1977 }
mbed_official 48:e9a2c7cb57a4 1978
mbed_official 48:e9a2c7cb57a4 1979 rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4));
mbed_official 48:e9a2c7cb57a4 1980
mbed_official 48:e9a2c7cb57a4 1981 return queue_def->pool;
mbed_official 48:e9a2c7cb57a4 1982 }
mbed_official 48:e9a2c7cb57a4 1983
mbed_official 48:e9a2c7cb57a4 1984 /// Put a Message to a Queue
mbed_official 48:e9a2c7cb57a4 1985 osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 1986 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 1987
mbed_official 48:e9a2c7cb57a4 1988 if (queue_id == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1989
mbed_official 48:e9a2c7cb57a4 1990 if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 1991
mbed_official 48:e9a2c7cb57a4 1992 res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec));
mbed_official 48:e9a2c7cb57a4 1993
mbed_official 48:e9a2c7cb57a4 1994 if (res == OS_R_TMO) {
mbed_official 48:e9a2c7cb57a4 1995 return (millisec ? osErrorTimeoutResource : osErrorResource);
mbed_official 48:e9a2c7cb57a4 1996 }
mbed_official 48:e9a2c7cb57a4 1997
mbed_official 48:e9a2c7cb57a4 1998 return osOK;
mbed_official 48:e9a2c7cb57a4 1999 }
mbed_official 48:e9a2c7cb57a4 2000
mbed_official 48:e9a2c7cb57a4 2001 /// Get a Message or Wait for a Message from a Queue
mbed_official 48:e9a2c7cb57a4 2002 os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 2003 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 2004 osEvent ret;
mbed_official 48:e9a2c7cb57a4 2005
mbed_official 48:e9a2c7cb57a4 2006 if (queue_id == NULL) {
mbed_official 48:e9a2c7cb57a4 2007 ret.status = osErrorParameter;
mbed_official 67:63988a2238f7 2008 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 2009 osEvent_ret_status;
mbed_official 67:63988a2238f7 2010 return;
mbed_official 67:63988a2238f7 2011 #else
mbed_official 48:e9a2c7cb57a4 2012 return osEvent_ret_status;
mbed_official 67:63988a2238f7 2013 #endif
mbed_official 48:e9a2c7cb57a4 2014 }
mbed_official 48:e9a2c7cb57a4 2015
mbed_official 48:e9a2c7cb57a4 2016 if (((P_MCB)queue_id)->cb_type != MCB) {
mbed_official 48:e9a2c7cb57a4 2017 ret.status = osErrorParameter;
mbed_official 67:63988a2238f7 2018 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 2019 osEvent_ret_status;
mbed_official 67:63988a2238f7 2020 return;
mbed_official 67:63988a2238f7 2021 #else
mbed_official 48:e9a2c7cb57a4 2022 return osEvent_ret_status;
mbed_official 67:63988a2238f7 2023 #endif
mbed_official 48:e9a2c7cb57a4 2024 }
mbed_official 48:e9a2c7cb57a4 2025
mbed_official 48:e9a2c7cb57a4 2026 res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec));
mbed_official 68:d3d0e710b443 2027
mbed_official 48:e9a2c7cb57a4 2028 if (res == OS_R_TMO) {
mbed_official 48:e9a2c7cb57a4 2029 ret.status = millisec ? osEventTimeout : osOK;
mbed_official 67:63988a2238f7 2030 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 2031 osEvent_ret_value;
mbed_official 67:63988a2238f7 2032 return;
mbed_official 67:63988a2238f7 2033 #else
mbed_official 48:e9a2c7cb57a4 2034 return osEvent_ret_value;
mbed_official 67:63988a2238f7 2035 #endif
mbed_official 48:e9a2c7cb57a4 2036 }
mbed_official 48:e9a2c7cb57a4 2037
mbed_official 48:e9a2c7cb57a4 2038 ret.status = osEventMessage;
mbed_official 48:e9a2c7cb57a4 2039
mbed_official 67:63988a2238f7 2040 #if defined (__GNUC__) && defined (__ARM_PCS_VFP)
mbed_official 67:63988a2238f7 2041 osEvent_ret_value;
mbed_official 67:63988a2238f7 2042 return;
mbed_official 67:63988a2238f7 2043 #else
mbed_official 48:e9a2c7cb57a4 2044 return osEvent_ret_value;
mbed_official 67:63988a2238f7 2045 #endif
mbed_official 48:e9a2c7cb57a4 2046 }
mbed_official 48:e9a2c7cb57a4 2047
mbed_official 48:e9a2c7cb57a4 2048
mbed_official 48:e9a2c7cb57a4 2049 // Message Queue ISR Calls
mbed_official 48:e9a2c7cb57a4 2050
mbed_official 48:e9a2c7cb57a4 2051 /// Put a Message to a Queue
mbed_official 48:e9a2c7cb57a4 2052 static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 2053
mbed_official 48:e9a2c7cb57a4 2054 if ((queue_id == NULL) || (millisec != 0)) {
mbed_official 48:e9a2c7cb57a4 2055 return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 2056 }
mbed_official 48:e9a2c7cb57a4 2057
mbed_official 48:e9a2c7cb57a4 2058 if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 2059
mbed_official 48:e9a2c7cb57a4 2060 if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full
mbed_official 48:e9a2c7cb57a4 2061 return osErrorResource;
mbed_official 48:e9a2c7cb57a4 2062 }
mbed_official 48:e9a2c7cb57a4 2063
mbed_official 48:e9a2c7cb57a4 2064 isr_mbx_send(queue_id, (void *)info);
mbed_official 48:e9a2c7cb57a4 2065
mbed_official 48:e9a2c7cb57a4 2066 return osOK;
mbed_official 48:e9a2c7cb57a4 2067 }
mbed_official 48:e9a2c7cb57a4 2068
mbed_official 48:e9a2c7cb57a4 2069 /// Get a Message or Wait for a Message from a Queue
mbed_official 48:e9a2c7cb57a4 2070 static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 2071 OS_RESULT res;
mbed_official 48:e9a2c7cb57a4 2072 osEvent ret;
mbed_official 48:e9a2c7cb57a4 2073
mbed_official 48:e9a2c7cb57a4 2074 if ((queue_id == NULL) || (millisec != 0)) {
mbed_official 48:e9a2c7cb57a4 2075 ret.status = osErrorParameter;
mbed_official 48:e9a2c7cb57a4 2076 return ret;
mbed_official 48:e9a2c7cb57a4 2077 }
mbed_official 48:e9a2c7cb57a4 2078
mbed_official 48:e9a2c7cb57a4 2079 if (((P_MCB)queue_id)->cb_type != MCB) {
mbed_official 48:e9a2c7cb57a4 2080 ret.status = osErrorParameter;
mbed_official 48:e9a2c7cb57a4 2081 return ret;
mbed_official 48:e9a2c7cb57a4 2082 }
mbed_official 48:e9a2c7cb57a4 2083
mbed_official 48:e9a2c7cb57a4 2084 res = isr_mbx_receive(queue_id, &ret.value.p);
mbed_official 68:d3d0e710b443 2085
mbed_official 48:e9a2c7cb57a4 2086 if (res != OS_R_MBX) {
mbed_official 48:e9a2c7cb57a4 2087 ret.status = osOK;
mbed_official 48:e9a2c7cb57a4 2088 return ret;
mbed_official 48:e9a2c7cb57a4 2089 }
mbed_official 48:e9a2c7cb57a4 2090
mbed_official 68:d3d0e710b443 2091 ret.status = osEventMessage;
mbed_official 48:e9a2c7cb57a4 2092
mbed_official 48:e9a2c7cb57a4 2093 return ret;
mbed_official 48:e9a2c7cb57a4 2094 }
mbed_official 48:e9a2c7cb57a4 2095
mbed_official 48:e9a2c7cb57a4 2096
mbed_official 48:e9a2c7cb57a4 2097 // Message Queue Management Public API
mbed_official 48:e9a2c7cb57a4 2098
mbed_official 48:e9a2c7cb57a4 2099 /// Create and Initialize Message Queue
mbed_official 48:e9a2c7cb57a4 2100 osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 2101 if (__exceptional_mode()) return NULL; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 2102 if ((__get_mode() != MODE_USR) && (os_running == 0)) {
mbed_official 48:e9a2c7cb57a4 2103 // Privileged and not running
mbed_official 48:e9a2c7cb57a4 2104 return svcMessageCreate(queue_def, thread_id);
mbed_official 48:e9a2c7cb57a4 2105 } else {
mbed_official 48:e9a2c7cb57a4 2106 return __svcMessageCreate(queue_def, thread_id);
mbed_official 48:e9a2c7cb57a4 2107 }
mbed_official 48:e9a2c7cb57a4 2108 }
mbed_official 48:e9a2c7cb57a4 2109
mbed_official 48:e9a2c7cb57a4 2110 /// Put a Message to a Queue
mbed_official 48:e9a2c7cb57a4 2111 osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 2112 if (__exceptional_mode()) { // in ISR
mbed_official 48:e9a2c7cb57a4 2113 return isrMessagePut(queue_id, info, millisec);
mbed_official 48:e9a2c7cb57a4 2114 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 2115 return __svcMessagePut(queue_id, info, millisec);
mbed_official 48:e9a2c7cb57a4 2116 }
mbed_official 48:e9a2c7cb57a4 2117 }
mbed_official 48:e9a2c7cb57a4 2118
mbed_official 48:e9a2c7cb57a4 2119 /// Get a Message or Wait for a Message from a Queue
mbed_official 48:e9a2c7cb57a4 2120 os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 2121 if (__exceptional_mode()) { // in ISR
mbed_official 48:e9a2c7cb57a4 2122 return isrMessageGet(queue_id, millisec);
mbed_official 48:e9a2c7cb57a4 2123 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 2124 return __svcMessageGet(queue_id, millisec);
mbed_official 48:e9a2c7cb57a4 2125 }
mbed_official 48:e9a2c7cb57a4 2126 }
mbed_official 48:e9a2c7cb57a4 2127
mbed_official 48:e9a2c7cb57a4 2128
mbed_official 48:e9a2c7cb57a4 2129 // ==== Mail Queue Management Functions ====
mbed_official 48:e9a2c7cb57a4 2130
mbed_official 48:e9a2c7cb57a4 2131 // Mail Queue Management Service Calls declarations
mbed_official 48:e9a2c7cb57a4 2132 SVC_2_1(svcMailCreate, osMailQId, const osMailQDef_t *, osThreadId, RET_pointer)
mbed_official 48:e9a2c7cb57a4 2133 SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer)
mbed_official 48:e9a2c7cb57a4 2134 SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus)
mbed_official 48:e9a2c7cb57a4 2135
mbed_official 48:e9a2c7cb57a4 2136 // Mail Queue Management Service & ISR Calls
mbed_official 48:e9a2c7cb57a4 2137
mbed_official 48:e9a2c7cb57a4 2138 /// Create and Initialize mail queue
mbed_official 48:e9a2c7cb57a4 2139 osMailQId svcMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 2140 uint32_t blk_sz;
mbed_official 48:e9a2c7cb57a4 2141 P_MCB pmcb;
mbed_official 48:e9a2c7cb57a4 2142 void *pool;
mbed_official 48:e9a2c7cb57a4 2143
mbed_official 48:e9a2c7cb57a4 2144 if ((queue_def == NULL) ||
mbed_official 48:e9a2c7cb57a4 2145 (queue_def->queue_sz == 0) ||
mbed_official 48:e9a2c7cb57a4 2146 (queue_def->item_sz == 0) ||
mbed_official 48:e9a2c7cb57a4 2147 (queue_def->pool == NULL)) {
mbed_official 48:e9a2c7cb57a4 2148 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 2149 return NULL;
mbed_official 48:e9a2c7cb57a4 2150 }
mbed_official 48:e9a2c7cb57a4 2151
mbed_official 48:e9a2c7cb57a4 2152 pmcb = *(((void **)queue_def->pool) + 0);
mbed_official 48:e9a2c7cb57a4 2153 pool = *(((void **)queue_def->pool) + 1);
mbed_official 48:e9a2c7cb57a4 2154
mbed_official 48:e9a2c7cb57a4 2155 if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) {
mbed_official 48:e9a2c7cb57a4 2156 sysThreadError(osErrorParameter);
mbed_official 48:e9a2c7cb57a4 2157 return NULL;
mbed_official 48:e9a2c7cb57a4 2158 }
mbed_official 48:e9a2c7cb57a4 2159
mbed_official 48:e9a2c7cb57a4 2160 blk_sz = (queue_def->item_sz + 3) & ~3;
mbed_official 48:e9a2c7cb57a4 2161
mbed_official 48:e9a2c7cb57a4 2162 _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz);
mbed_official 48:e9a2c7cb57a4 2163
mbed_official 48:e9a2c7cb57a4 2164 rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4));
mbed_official 48:e9a2c7cb57a4 2165
mbed_official 48:e9a2c7cb57a4 2166 return queue_def->pool;
mbed_official 48:e9a2c7cb57a4 2167 }
mbed_official 48:e9a2c7cb57a4 2168
mbed_official 48:e9a2c7cb57a4 2169 /// Allocate a memory block from a mail
mbed_official 48:e9a2c7cb57a4 2170 void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) {
mbed_official 48:e9a2c7cb57a4 2171 P_MCB pmcb;
mbed_official 48:e9a2c7cb57a4 2172 void *pool;
mbed_official 48:e9a2c7cb57a4 2173 void *mem;
mbed_official 48:e9a2c7cb57a4 2174
mbed_official 48:e9a2c7cb57a4 2175 if (queue_id == NULL) return NULL;
mbed_official 48:e9a2c7cb57a4 2176
mbed_official 48:e9a2c7cb57a4 2177 pmcb = *(((void **)queue_id) + 0);
mbed_official 48:e9a2c7cb57a4 2178 pool = *(((void **)queue_id) + 1);
mbed_official 48:e9a2c7cb57a4 2179
mbed_official 48:e9a2c7cb57a4 2180 if ((pool == NULL) || (pmcb == NULL)) return NULL;
mbed_official 48:e9a2c7cb57a4 2181
mbed_official 48:e9a2c7cb57a4 2182 if (isr && (millisec != 0)) return NULL;
mbed_official 48:e9a2c7cb57a4 2183
mbed_official 48:e9a2c7cb57a4 2184 mem = rt_alloc_box(pool);
mbed_official 48:e9a2c7cb57a4 2185 if (clr) {
mbed_official 48:e9a2c7cb57a4 2186 rt_clr_box(pool, mem);
mbed_official 48:e9a2c7cb57a4 2187 }
mbed_official 48:e9a2c7cb57a4 2188
mbed_official 48:e9a2c7cb57a4 2189 if ((mem == NULL) && (millisec != 0)) {
mbed_official 48:e9a2c7cb57a4 2190 // Put Task to sleep when Memory not available
mbed_official 48:e9a2c7cb57a4 2191 if (pmcb->p_lnk != NULL) {
mbed_official 48:e9a2c7cb57a4 2192 rt_put_prio((P_XCB)pmcb, os_tsk.run);
mbed_official 48:e9a2c7cb57a4 2193 } else {
mbed_official 48:e9a2c7cb57a4 2194 pmcb->p_lnk = os_tsk.run;
mbed_official 48:e9a2c7cb57a4 2195 os_tsk.run->p_lnk = NULL;
mbed_official 48:e9a2c7cb57a4 2196 os_tsk.run->p_rlnk = (P_TCB)pmcb;
mbed_official 48:e9a2c7cb57a4 2197 // Task is waiting to allocate a message
mbed_official 48:e9a2c7cb57a4 2198 pmcb->state = 3;
mbed_official 48:e9a2c7cb57a4 2199 }
mbed_official 48:e9a2c7cb57a4 2200 rt_block(rt_ms2tick(millisec), WAIT_MBX);
mbed_official 48:e9a2c7cb57a4 2201 }
mbed_official 48:e9a2c7cb57a4 2202
mbed_official 68:d3d0e710b443 2203 return mem;
mbed_official 48:e9a2c7cb57a4 2204 }
mbed_official 48:e9a2c7cb57a4 2205
mbed_official 48:e9a2c7cb57a4 2206 /// Free a memory block from a mail
mbed_official 48:e9a2c7cb57a4 2207 osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) {
mbed_official 48:e9a2c7cb57a4 2208 P_MCB pmcb;
mbed_official 48:e9a2c7cb57a4 2209 P_TCB ptcb;
mbed_official 48:e9a2c7cb57a4 2210 void *pool;
mbed_official 48:e9a2c7cb57a4 2211 void *mem;
mbed_official 48:e9a2c7cb57a4 2212 int32_t res;
mbed_official 48:e9a2c7cb57a4 2213
mbed_official 48:e9a2c7cb57a4 2214 if (queue_id == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 2215
mbed_official 48:e9a2c7cb57a4 2216 pmcb = *(((void **)queue_id) + 0);
mbed_official 48:e9a2c7cb57a4 2217 pool = *(((void **)queue_id) + 1);
mbed_official 48:e9a2c7cb57a4 2218
mbed_official 48:e9a2c7cb57a4 2219 if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 2220
mbed_official 48:e9a2c7cb57a4 2221 res = rt_free_box(pool, mail);
mbed_official 48:e9a2c7cb57a4 2222
mbed_official 48:e9a2c7cb57a4 2223 if (res != 0) return osErrorValue;
mbed_official 48:e9a2c7cb57a4 2224
mbed_official 92:bc9729798a19 2225 if ((pmcb->p_lnk != NULL) && (pmcb->state == 3)) {
mbed_official 48:e9a2c7cb57a4 2226 // Task is waiting to allocate a message
mbed_official 48:e9a2c7cb57a4 2227 if (isr) {
mbed_official 48:e9a2c7cb57a4 2228 rt_psq_enq (pmcb, (U32)pool);
mbed_official 48:e9a2c7cb57a4 2229 rt_psh_req ();
mbed_official 48:e9a2c7cb57a4 2230 } else {
mbed_official 48:e9a2c7cb57a4 2231 mem = rt_alloc_box(pool);
mbed_official 48:e9a2c7cb57a4 2232 if (mem != NULL) {
mbed_official 48:e9a2c7cb57a4 2233 ptcb = rt_get_first((P_XCB)pmcb);
mbed_official 48:e9a2c7cb57a4 2234 rt_ret_val(ptcb, (U32)mem);
mbed_official 48:e9a2c7cb57a4 2235 rt_rmv_dly(ptcb);
mbed_official 48:e9a2c7cb57a4 2236 rt_dispatch(ptcb);
mbed_official 48:e9a2c7cb57a4 2237 }
mbed_official 48:e9a2c7cb57a4 2238 }
mbed_official 48:e9a2c7cb57a4 2239 }
mbed_official 48:e9a2c7cb57a4 2240
mbed_official 48:e9a2c7cb57a4 2241 return osOK;
mbed_official 48:e9a2c7cb57a4 2242 }
mbed_official 48:e9a2c7cb57a4 2243
mbed_official 48:e9a2c7cb57a4 2244
mbed_official 48:e9a2c7cb57a4 2245 // Mail Queue Management Public API
mbed_official 48:e9a2c7cb57a4 2246
mbed_official 48:e9a2c7cb57a4 2247 /// Create and Initialize mail queue
mbed_official 48:e9a2c7cb57a4 2248 osMailQId osMailCreate (const osMailQDef_t *queue_def, osThreadId thread_id) {
mbed_official 48:e9a2c7cb57a4 2249 if (__exceptional_mode()) return NULL; // Not allowed in ISR
mbed_official 48:e9a2c7cb57a4 2250 if ((__get_mode() != MODE_USR) && (os_running == 0)) {
mbed_official 48:e9a2c7cb57a4 2251 // Privileged and not running
mbed_official 48:e9a2c7cb57a4 2252 return svcMailCreate(queue_def, thread_id);
mbed_official 48:e9a2c7cb57a4 2253 } else {
mbed_official 48:e9a2c7cb57a4 2254 return __svcMailCreate(queue_def, thread_id);
mbed_official 48:e9a2c7cb57a4 2255 }
mbed_official 48:e9a2c7cb57a4 2256 }
mbed_official 48:e9a2c7cb57a4 2257
mbed_official 48:e9a2c7cb57a4 2258 /// Allocate a memory block from a mail
mbed_official 48:e9a2c7cb57a4 2259 void *osMailAlloc (osMailQId queue_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 2260 if (__exceptional_mode()) { // in ISR
mbed_official 48:e9a2c7cb57a4 2261 return sysMailAlloc(queue_id, millisec, 1, 0);
mbed_official 48:e9a2c7cb57a4 2262 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 2263 return __sysMailAlloc(queue_id, millisec, 0, 0);
mbed_official 48:e9a2c7cb57a4 2264 }
mbed_official 48:e9a2c7cb57a4 2265 }
mbed_official 48:e9a2c7cb57a4 2266
mbed_official 48:e9a2c7cb57a4 2267 /// Allocate a memory block from a mail and set memory block to zero
mbed_official 48:e9a2c7cb57a4 2268 void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 2269 if (__exceptional_mode()) { // in ISR
mbed_official 48:e9a2c7cb57a4 2270 return sysMailAlloc(queue_id, millisec, 1, 1);
mbed_official 48:e9a2c7cb57a4 2271 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 2272 return __sysMailAlloc(queue_id, millisec, 0, 1);
mbed_official 48:e9a2c7cb57a4 2273 }
mbed_official 48:e9a2c7cb57a4 2274 }
mbed_official 48:e9a2c7cb57a4 2275
mbed_official 48:e9a2c7cb57a4 2276 /// Free a memory block from a mail
mbed_official 48:e9a2c7cb57a4 2277 osStatus osMailFree (osMailQId queue_id, void *mail) {
mbed_official 48:e9a2c7cb57a4 2278 if (__exceptional_mode()) { // in ISR
mbed_official 48:e9a2c7cb57a4 2279 return sysMailFree(queue_id, mail, 1);
mbed_official 48:e9a2c7cb57a4 2280 } else { // in Thread
mbed_official 48:e9a2c7cb57a4 2281 return __sysMailFree(queue_id, mail, 0);
mbed_official 48:e9a2c7cb57a4 2282 }
mbed_official 48:e9a2c7cb57a4 2283 }
mbed_official 48:e9a2c7cb57a4 2284
mbed_official 48:e9a2c7cb57a4 2285 /// Put a mail to a queue
mbed_official 48:e9a2c7cb57a4 2286 osStatus osMailPut (osMailQId queue_id, void *mail) {
mbed_official 48:e9a2c7cb57a4 2287 if (queue_id == NULL) return osErrorParameter;
mbed_official 48:e9a2c7cb57a4 2288 if (mail == NULL) return osErrorValue;
mbed_official 48:e9a2c7cb57a4 2289 return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0);
mbed_official 48:e9a2c7cb57a4 2290 }
mbed_official 48:e9a2c7cb57a4 2291
mbed_official 72:83895f30f8f2 2292 #ifdef __CC_ARM
mbed_official 70:3295e347fd88 2293 #pragma push
mbed_official 70:3295e347fd88 2294 #pragma Ospace
mbed_official 70:3295e347fd88 2295 #endif // __arm__
mbed_official 48:e9a2c7cb57a4 2296 /// Get a mail from a queue
mbed_official 48:e9a2c7cb57a4 2297 os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) {
mbed_official 48:e9a2c7cb57a4 2298 osEvent ret;
mbed_official 48:e9a2c7cb57a4 2299
mbed_official 48:e9a2c7cb57a4 2300 if (queue_id == NULL) {
mbed_official 48:e9a2c7cb57a4 2301 ret.status = osErrorParameter;
mbed_official 48:e9a2c7cb57a4 2302 return ret;
mbed_official 48:e9a2c7cb57a4 2303 }
mbed_official 48:e9a2c7cb57a4 2304
mbed_official 48:e9a2c7cb57a4 2305 ret = osMessageGet(*((void **)queue_id), millisec);
mbed_official 48:e9a2c7cb57a4 2306 if (ret.status == osEventMessage) ret.status = osEventMail;
mbed_official 48:e9a2c7cb57a4 2307
mbed_official 48:e9a2c7cb57a4 2308 return ret;
mbed_official 48:e9a2c7cb57a4 2309 }
mbed_official 72:83895f30f8f2 2310 #ifdef __CC_ARM
mbed_official 70:3295e347fd88 2311 #pragma pop
mbed_official 70:3295e347fd88 2312 #endif // __arm__
mbed_official 92:bc9729798a19 2313
mbed_official 92:bc9729798a19 2314
mbed_official 92:bc9729798a19 2315 // ==== RTX Extensions ====
mbed_official 92:bc9729798a19 2316
mbed_official 92:bc9729798a19 2317 // Service Calls declarations
mbed_official 92:bc9729798a19 2318 SVC_0_1(rt_suspend, uint32_t, RET_uint32_t)
mbed_official 92:bc9729798a19 2319 SVC_1_0(rt_resume, void, uint32_t)
mbed_official 92:bc9729798a19 2320
mbed_official 92:bc9729798a19 2321
mbed_official 92:bc9729798a19 2322 // Public API
mbed_official 92:bc9729798a19 2323
mbed_official 92:bc9729798a19 2324 /// Suspends the OS task scheduler
mbed_official 92:bc9729798a19 2325 uint32_t os_suspend (void) {
mbed_official 92:bc9729798a19 2326 return __rt_suspend();
mbed_official 92:bc9729798a19 2327 }
mbed_official 92:bc9729798a19 2328
mbed_official 92:bc9729798a19 2329 /// Resumes the OS task scheduler
mbed_official 92:bc9729798a19 2330 void os_resume (uint32_t sleep_time) {
mbed_official 92:bc9729798a19 2331 __rt_resume(sleep_time);
mbed_official 92:bc9729798a19 2332 }