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:
80:2dab120a94c2
ok

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 80:2dab120a94c2 1 /*----------------------------------------------------------------------------
mbed_official 80:2dab120a94c2 2 * RL-ARM - RTX
mbed_official 80:2dab120a94c2 3 *----------------------------------------------------------------------------
mbed_official 80:2dab120a94c2 4 * Name: rt_CMSIS.c
mbed_official 80:2dab120a94c2 5 * Purpose: CMSIS RTOS API
mbed_official 80:2dab120a94c2 6 * Rev.: V4.60
mbed_official 80:2dab120a94c2 7 *----------------------------------------------------------------------------
mbed_official 80:2dab120a94c2 8 *
mbed_official 80:2dab120a94c2 9 * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
mbed_official 80:2dab120a94c2 10 * All rights reserved.
mbed_official 80:2dab120a94c2 11 * Redistribution and use in source and binary forms, with or without
mbed_official 80:2dab120a94c2 12 * modification, are permitted provided that the following conditions are met:
mbed_official 80:2dab120a94c2 13 * - Redistributions of source code must retain the above copyright
mbed_official 80:2dab120a94c2 14 * notice, this list of conditions and the following disclaimer.
mbed_official 80:2dab120a94c2 15 * - Redistributions in binary form must reproduce the above copyright
mbed_official 80:2dab120a94c2 16 * notice, this list of conditions and the following disclaimer in the
mbed_official 80:2dab120a94c2 17 * documentation and/or other materials provided with the distribution.
mbed_official 80:2dab120a94c2 18 * - Neither the name of ARM nor the names of its contributors may be used
mbed_official 80:2dab120a94c2 19 * to endorse or promote products derived from this software without
mbed_official 80:2dab120a94c2 20 * specific prior written permission.
mbed_official 80:2dab120a94c2 21 *
mbed_official 80:2dab120a94c2 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
mbed_official 80:2dab120a94c2 23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
mbed_official 80:2dab120a94c2 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
mbed_official 80:2dab120a94c2 25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
mbed_official 80:2dab120a94c2 26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
mbed_official 80:2dab120a94c2 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
mbed_official 80:2dab120a94c2 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
mbed_official 80:2dab120a94c2 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
mbed_official 80:2dab120a94c2 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
mbed_official 80:2dab120a94c2 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
mbed_official 80:2dab120a94c2 32 * POSSIBILITY OF SUCH DAMAGE.
mbed_official 80:2dab120a94c2 33 *---------------------------------------------------------------------------*/
mbed_official 80:2dab120a94c2 34
mbed_official 80:2dab120a94c2 35 #define __CMSIS_GENERIC
mbed_official 80:2dab120a94c2 36
mbed_official 80:2dab120a94c2 37 #include "core_arm7.h"
mbed_official 80:2dab120a94c2 38
mbed_official 80:2dab120a94c2 39 #include "rt_TypeDef.h"
mbed_official 80:2dab120a94c2 40 #include "RTX_Conf.h"
mbed_official 80:2dab120a94c2 41 #include "rt_System.h"
mbed_official 80:2dab120a94c2 42 #include "rt_Task.h"
mbed_official 80:2dab120a94c2 43 #include "rt_Event.h"
mbed_official 80:2dab120a94c2 44 #include "rt_List.h"
mbed_official 80:2dab120a94c2 45 #include "rt_Time.h"
mbed_official 80:2dab120a94c2 46 #include "rt_Mutex.h"
mbed_official 80:2dab120a94c2 47 #include "rt_Semaphore.h"
mbed_official 80:2dab120a94c2 48 #include "rt_Mailbox.h"
mbed_official 80:2dab120a94c2 49 #include "rt_MemBox.h"
mbed_official 80:2dab120a94c2 50 #include "rt_HAL_CM.h"
mbed_official 80:2dab120a94c2 51
mbed_official 80:2dab120a94c2 52 #define os_thread_cb OS_TCB
mbed_official 80:2dab120a94c2 53
mbed_official 80:2dab120a94c2 54 #include "cmsis_os.h"
mbed_official 80:2dab120a94c2 55
mbed_official 80:2dab120a94c2 56 #if (osFeature_Signals != 16)
mbed_official 80:2dab120a94c2 57 #error Invalid "osFeature_Signals" value!
mbed_official 80:2dab120a94c2 58 #endif
mbed_official 80:2dab120a94c2 59 #if (osFeature_Semaphore > 65535)
mbed_official 80:2dab120a94c2 60 #error Invalid "osFeature_Semaphore" value!
mbed_official 80:2dab120a94c2 61 #endif
mbed_official 80:2dab120a94c2 62 #if (osFeature_Wait != 0)
mbed_official 80:2dab120a94c2 63 #error osWait not supported!
mbed_official 80:2dab120a94c2 64 #endif
mbed_official 80:2dab120a94c2 65
mbed_official 80:2dab120a94c2 66
mbed_official 80:2dab120a94c2 67 // ==== Enumeration, structures, defines ====
mbed_official 80:2dab120a94c2 68
mbed_official 80:2dab120a94c2 69 // Service Calls defines
mbed_official 80:2dab120a94c2 70
mbed_official 80:2dab120a94c2 71 #if defined (__CC_ARM) /* ARM Compiler */
mbed_official 80:2dab120a94c2 72
mbed_official 80:2dab120a94c2 73 #define __NO_RETURN __declspec(noreturn)
mbed_official 80:2dab120a94c2 74
mbed_official 80:2dab120a94c2 75 #define osEvent_type osEvent
mbed_official 80:2dab120a94c2 76 #define osEvent_ret_status ret
mbed_official 80:2dab120a94c2 77 #define osEvent_ret_value ret
mbed_official 80:2dab120a94c2 78 #define osEvent_ret_msg ret
mbed_official 80:2dab120a94c2 79 #define osEvent_ret_mail ret
mbed_official 80:2dab120a94c2 80
mbed_official 80:2dab120a94c2 81 #define osCallback_type osCallback
mbed_official 80:2dab120a94c2 82 #define osCallback_ret ret
mbed_official 80:2dab120a94c2 83
mbed_official 80:2dab120a94c2 84 #define SVC_0_1(f,t,...) \
mbed_official 80:2dab120a94c2 85 __svc_indirect(0) t _##f (t(*)()); \
mbed_official 80:2dab120a94c2 86 t f (void); \
mbed_official 80:2dab120a94c2 87 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 88 static __inline t __##f (void) { \
mbed_official 80:2dab120a94c2 89 return _##f(f); \
mbed_official 80:2dab120a94c2 90 }
mbed_official 80:2dab120a94c2 91
mbed_official 80:2dab120a94c2 92 #define SVC_1_1(f,t,t1,...) \
mbed_official 80:2dab120a94c2 93 __svc_indirect(0) t _##f (t(*)(t1),t1); \
mbed_official 80:2dab120a94c2 94 t f (t1 a1); \
mbed_official 80:2dab120a94c2 95 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 96 static __inline t __##f (t1 a1) { \
mbed_official 80:2dab120a94c2 97 return _##f(f,a1); \
mbed_official 80:2dab120a94c2 98 }
mbed_official 80:2dab120a94c2 99
mbed_official 80:2dab120a94c2 100 #define SVC_2_1(f,t,t1,t2,...) \
mbed_official 80:2dab120a94c2 101 __svc_indirect(0) t _##f (t(*)(t1,t2),t1,t2); \
mbed_official 80:2dab120a94c2 102 t f (t1 a1, t2 a2); \
mbed_official 80:2dab120a94c2 103 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 104 static __inline t __##f (t1 a1, t2 a2) { \
mbed_official 80:2dab120a94c2 105 return _##f(f,a1,a2); \
mbed_official 80:2dab120a94c2 106 }
mbed_official 80:2dab120a94c2 107
mbed_official 80:2dab120a94c2 108 #define SVC_3_1(f,t,t1,t2,t3,...) \
mbed_official 80:2dab120a94c2 109 __svc_indirect(0) t _##f (t(*)(t1,t2,t3),t1,t2,t3); \
mbed_official 80:2dab120a94c2 110 t f (t1 a1, t2 a2, t3 a3); \
mbed_official 80:2dab120a94c2 111 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 112 static __inline t __##f (t1 a1, t2 a2, t3 a3) { \
mbed_official 80:2dab120a94c2 113 return _##f(f,a1,a2,a3); \
mbed_official 80:2dab120a94c2 114 }
mbed_official 80:2dab120a94c2 115
mbed_official 80:2dab120a94c2 116 #define SVC_4_1(f,t,t1,t2,t3,t4,...) \
mbed_official 80:2dab120a94c2 117 __svc_indirect(0) t _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4); \
mbed_official 80:2dab120a94c2 118 t f (t1 a1, t2 a2, t3 a3, t4 a4); \
mbed_official 80:2dab120a94c2 119 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 120 static __inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
mbed_official 80:2dab120a94c2 121 return _##f(f,a1,a2,a3,a4); \
mbed_official 80:2dab120a94c2 122 }
mbed_official 80:2dab120a94c2 123
mbed_official 80:2dab120a94c2 124 #define SVC_1_2 SVC_1_1
mbed_official 80:2dab120a94c2 125 #define SVC_1_3 SVC_1_1
mbed_official 80:2dab120a94c2 126 #define SVC_2_3 SVC_2_1
mbed_official 80:2dab120a94c2 127
mbed_official 80:2dab120a94c2 128 #elif defined (__GNUC__) /* GNU Compiler */
mbed_official 80:2dab120a94c2 129
mbed_official 80:2dab120a94c2 130 #define __NO_RETURN __attribute__((noreturn))
mbed_official 80:2dab120a94c2 131
mbed_official 80:2dab120a94c2 132 typedef uint32_t __attribute__((vector_size(8))) ret64;
mbed_official 80:2dab120a94c2 133 typedef uint32_t __attribute__((vector_size(16))) ret128;
mbed_official 80:2dab120a94c2 134
mbed_official 80:2dab120a94c2 135 #define RET_pointer __r0
mbed_official 80:2dab120a94c2 136 #define RET_int32_t __r0
mbed_official 80:2dab120a94c2 137 #define RET_osStatus __r0
mbed_official 80:2dab120a94c2 138 #define RET_osPriority __r0
mbed_official 80:2dab120a94c2 139 #define RET_osEvent {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}}
mbed_official 80:2dab120a94c2 140 #define RET_osCallback {(void *)__r0, (void *)__r1}
mbed_official 80:2dab120a94c2 141
mbed_official 80:2dab120a94c2 142 #define osEvent_type ret128
mbed_official 80:2dab120a94c2 143 #define osEvent_ret_status (ret128){ret.status}
mbed_official 80:2dab120a94c2 144 #define osEvent_ret_value (ret128){ret.status, ret.value.v}
mbed_official 80:2dab120a94c2 145 #define osEvent_ret_msg (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id}
mbed_official 80:2dab120a94c2 146 #define osEvent_ret_mail (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id}
mbed_official 80:2dab120a94c2 147
mbed_official 80:2dab120a94c2 148 #define osCallback_type ret64
mbed_official 80:2dab120a94c2 149 #define osCallback_ret (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg}
mbed_official 80:2dab120a94c2 150
mbed_official 80:2dab120a94c2 151 #define SVC_ArgN(n) \
mbed_official 80:2dab120a94c2 152 register int __r##n __asm("r"#n);
mbed_official 80:2dab120a94c2 153
mbed_official 80:2dab120a94c2 154 #define SVC_ArgR(n,t,a) \
mbed_official 80:2dab120a94c2 155 register t __r##n __asm("r"#n) = a;
mbed_official 80:2dab120a94c2 156
mbed_official 80:2dab120a94c2 157 #define SVC_Arg0() \
mbed_official 80:2dab120a94c2 158 SVC_ArgN(0) \
mbed_official 80:2dab120a94c2 159 SVC_ArgN(1) \
mbed_official 80:2dab120a94c2 160 SVC_ArgN(2) \
mbed_official 80:2dab120a94c2 161 SVC_ArgN(3)
mbed_official 80:2dab120a94c2 162
mbed_official 80:2dab120a94c2 163 #define SVC_Arg1(t1) \
mbed_official 80:2dab120a94c2 164 SVC_ArgR(0,t1,a1) \
mbed_official 80:2dab120a94c2 165 SVC_ArgN(1) \
mbed_official 80:2dab120a94c2 166 SVC_ArgN(2) \
mbed_official 80:2dab120a94c2 167 SVC_ArgN(3)
mbed_official 80:2dab120a94c2 168
mbed_official 80:2dab120a94c2 169 #define SVC_Arg2(t1,t2) \
mbed_official 80:2dab120a94c2 170 SVC_ArgR(0,t1,a1) \
mbed_official 80:2dab120a94c2 171 SVC_ArgR(1,t2,a2) \
mbed_official 80:2dab120a94c2 172 SVC_ArgN(2) \
mbed_official 80:2dab120a94c2 173 SVC_ArgN(3)
mbed_official 80:2dab120a94c2 174
mbed_official 80:2dab120a94c2 175 #define SVC_Arg3(t1,t2,t3) \
mbed_official 80:2dab120a94c2 176 SVC_ArgR(0,t1,a1) \
mbed_official 80:2dab120a94c2 177 SVC_ArgR(1,t2,a2) \
mbed_official 80:2dab120a94c2 178 SVC_ArgR(2,t3,a3) \
mbed_official 80:2dab120a94c2 179 SVC_ArgN(3)
mbed_official 80:2dab120a94c2 180
mbed_official 80:2dab120a94c2 181 #define SVC_Arg4(t1,t2,t3,t4) \
mbed_official 80:2dab120a94c2 182 SVC_ArgR(0,t1,a1) \
mbed_official 80:2dab120a94c2 183 SVC_ArgR(1,t2,a2) \
mbed_official 80:2dab120a94c2 184 SVC_ArgR(2,t3,a3) \
mbed_official 80:2dab120a94c2 185 SVC_ArgR(3,t4,a4)
mbed_official 80:2dab120a94c2 186
mbed_official 80:2dab120a94c2 187 #if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS)
mbed_official 80:2dab120a94c2 188 #define SVC_Call(f) \
mbed_official 80:2dab120a94c2 189 __asm volatile \
mbed_official 80:2dab120a94c2 190 ( \
mbed_official 80:2dab120a94c2 191 "ldr r7,="#f"\n\t" \
mbed_official 80:2dab120a94c2 192 "mov r12,r7\n\t" \
mbed_official 80:2dab120a94c2 193 "svc 0" \
mbed_official 80:2dab120a94c2 194 : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \
mbed_official 80:2dab120a94c2 195 : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \
mbed_official 80:2dab120a94c2 196 : "r7", "r12", "lr", "cc" \
mbed_official 80:2dab120a94c2 197 );
mbed_official 80:2dab120a94c2 198 #else
mbed_official 80:2dab120a94c2 199 #define SVC_Call(f) \
mbed_official 80:2dab120a94c2 200 __asm volatile \
mbed_official 80:2dab120a94c2 201 ( \
mbed_official 80:2dab120a94c2 202 "ldr r12,="#f"\n\t" \
mbed_official 80:2dab120a94c2 203 "svc 0" \
mbed_official 80:2dab120a94c2 204 : "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3) \
mbed_official 80:2dab120a94c2 205 : "r" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) \
mbed_official 80:2dab120a94c2 206 : "r12", "lr", "cc" \
mbed_official 80:2dab120a94c2 207 );
mbed_official 80:2dab120a94c2 208 #endif
mbed_official 80:2dab120a94c2 209
mbed_official 80:2dab120a94c2 210 #define SVC_0_1(f,t,rv) \
mbed_official 80:2dab120a94c2 211 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 212 static inline t __##f (void) { \
mbed_official 80:2dab120a94c2 213 SVC_Arg0(); \
mbed_official 80:2dab120a94c2 214 SVC_Call(f); \
mbed_official 80:2dab120a94c2 215 return (t) rv; \
mbed_official 80:2dab120a94c2 216 }
mbed_official 80:2dab120a94c2 217
mbed_official 80:2dab120a94c2 218 #define SVC_1_1(f,t,t1,rv) \
mbed_official 80:2dab120a94c2 219 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 220 static inline t __##f (t1 a1) { \
mbed_official 80:2dab120a94c2 221 SVC_Arg1(t1); \
mbed_official 80:2dab120a94c2 222 SVC_Call(f); \
mbed_official 80:2dab120a94c2 223 return (t) rv; \
mbed_official 80:2dab120a94c2 224 }
mbed_official 80:2dab120a94c2 225
mbed_official 80:2dab120a94c2 226 #define SVC_2_1(f,t,t1,t2,rv) \
mbed_official 80:2dab120a94c2 227 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 228 static inline t __##f (t1 a1, t2 a2) { \
mbed_official 80:2dab120a94c2 229 SVC_Arg2(t1,t2); \
mbed_official 80:2dab120a94c2 230 SVC_Call(f); \
mbed_official 80:2dab120a94c2 231 return (t) rv; \
mbed_official 80:2dab120a94c2 232 }
mbed_official 80:2dab120a94c2 233
mbed_official 80:2dab120a94c2 234 #define SVC_3_1(f,t,t1,t2,t3,rv) \
mbed_official 80:2dab120a94c2 235 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 236 static inline t __##f (t1 a1, t2 a2, t3 a3) { \
mbed_official 80:2dab120a94c2 237 SVC_Arg3(t1,t2,t3); \
mbed_official 80:2dab120a94c2 238 SVC_Call(f); \
mbed_official 80:2dab120a94c2 239 return (t) rv; \
mbed_official 80:2dab120a94c2 240 }
mbed_official 80:2dab120a94c2 241
mbed_official 80:2dab120a94c2 242 #define SVC_4_1(f,t,t1,t2,t3,t4,rv) \
mbed_official 80:2dab120a94c2 243 __attribute__((always_inline)) \
mbed_official 80:2dab120a94c2 244 static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
mbed_official 80:2dab120a94c2 245 SVC_Arg4(t1,t2,t3,t4); \
mbed_official 80:2dab120a94c2 246 SVC_Call(f); \
mbed_official 80:2dab120a94c2 247 return (t) rv; \
mbed_official 80:2dab120a94c2 248 }
mbed_official 80:2dab120a94c2 249
mbed_official 80:2dab120a94c2 250 #define SVC_1_2 SVC_1_1
mbed_official 80:2dab120a94c2 251 #define SVC_1_3 SVC_1_1
mbed_official 80:2dab120a94c2 252 #define SVC_2_3 SVC_2_1
mbed_official 80:2dab120a94c2 253
mbed_official 80:2dab120a94c2 254 #elif defined (__ICCARM__) /* IAR Compiler */
mbed_official 80:2dab120a94c2 255
mbed_official 80:2dab120a94c2 256 #define __NO_RETURN __noreturn
mbed_official 80:2dab120a94c2 257
mbed_official 80:2dab120a94c2 258 #define osEvent_type osEvent
mbed_official 80:2dab120a94c2 259 #define osEvent_ret_status ret
mbed_official 80:2dab120a94c2 260 #define osEvent_ret_value ret
mbed_official 80:2dab120a94c2 261 #define osEvent_ret_msg ret
mbed_official 80:2dab120a94c2 262 #define osEvent_ret_mail ret
mbed_official 80:2dab120a94c2 263
mbed_official 80:2dab120a94c2 264 #define osCallback_type osCallback
mbed_official 80:2dab120a94c2 265 #define osCallback_ret ret
mbed_official 80:2dab120a94c2 266
mbed_official 80:2dab120a94c2 267 #define RET_osEvent osEvent
mbed_official 80:2dab120a94c2 268 #define RET_osCallback osCallback
mbed_official 80:2dab120a94c2 269
mbed_official 80:2dab120a94c2 270 #define SVC_Setup(f) \
mbed_official 80:2dab120a94c2 271 __asm( \
mbed_official 80:2dab120a94c2 272 "mov r12,%0\n" \
mbed_official 80:2dab120a94c2 273 :: "r"(&f): "r12" \
mbed_official 80:2dab120a94c2 274 );
mbed_official 80:2dab120a94c2 275
mbed_official 80:2dab120a94c2 276
mbed_official 80:2dab120a94c2 277 #define SVC_0_1(f,t,...) \
mbed_official 80:2dab120a94c2 278 t f (void); \
mbed_official 80:2dab120a94c2 279 _Pragma("swi_number=0") __swi t _##f (void); \
mbed_official 80:2dab120a94c2 280 static inline t __##f (void) { \
mbed_official 80:2dab120a94c2 281 SVC_Setup(f); \
mbed_official 80:2dab120a94c2 282 return _##f(); \
mbed_official 80:2dab120a94c2 283 }
mbed_official 80:2dab120a94c2 284
mbed_official 80:2dab120a94c2 285 #define SVC_1_1(f,t,t1,...) \
mbed_official 80:2dab120a94c2 286 t f (t1 a1); \
mbed_official 80:2dab120a94c2 287 _Pragma("swi_number=0") __swi t _##f (t1 a1); \
mbed_official 80:2dab120a94c2 288 static inline t __##f (t1 a1) { \
mbed_official 80:2dab120a94c2 289 SVC_Setup(f); \
mbed_official 80:2dab120a94c2 290 return _##f(a1); \
mbed_official 80:2dab120a94c2 291 }
mbed_official 80:2dab120a94c2 292
mbed_official 80:2dab120a94c2 293 #define SVC_2_1(f,t,t1,t2,...) \
mbed_official 80:2dab120a94c2 294 t f (t1 a1, t2 a2); \
mbed_official 80:2dab120a94c2 295 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2); \
mbed_official 80:2dab120a94c2 296 static inline t __##f (t1 a1, t2 a2) { \
mbed_official 80:2dab120a94c2 297 SVC_Setup(f); \
mbed_official 80:2dab120a94c2 298 return _##f(a1,a2); \
mbed_official 80:2dab120a94c2 299 }
mbed_official 80:2dab120a94c2 300
mbed_official 80:2dab120a94c2 301 #define SVC_3_1(f,t,t1,t2,t3,...) \
mbed_official 80:2dab120a94c2 302 t f (t1 a1, t2 a2, t3 a3); \
mbed_official 80:2dab120a94c2 303 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3); \
mbed_official 80:2dab120a94c2 304 static inline t __##f (t1 a1, t2 a2, t3 a3) { \
mbed_official 80:2dab120a94c2 305 SVC_Setup(f); \
mbed_official 80:2dab120a94c2 306 return _##f(a1,a2,a3); \
mbed_official 80:2dab120a94c2 307 }
mbed_official 80:2dab120a94c2 308
mbed_official 80:2dab120a94c2 309 #define SVC_4_1(f,t,t1,t2,t3,t4,...) \
mbed_official 80:2dab120a94c2 310 t f (t1 a1, t2 a2, t3 a3, t4 a4); \
mbed_official 80:2dab120a94c2 311 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4); \
mbed_official 80:2dab120a94c2 312 static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
mbed_official 80:2dab120a94c2 313 SVC_Setup(f); \
mbed_official 80:2dab120a94c2 314 return _##f(a1,a2,a3,a4); \
mbed_official 80:2dab120a94c2 315 }
mbed_official 80:2dab120a94c2 316
mbed_official 80:2dab120a94c2 317 #define SVC_1_2 SVC_1_1
mbed_official 80:2dab120a94c2 318 #define SVC_1_3 SVC_1_1
mbed_official 80:2dab120a94c2 319 #define SVC_2_3 SVC_2_1
mbed_official 80:2dab120a94c2 320
mbed_official 80:2dab120a94c2 321 #endif
mbed_official 80:2dab120a94c2 322
mbed_official 80:2dab120a94c2 323
mbed_official 80:2dab120a94c2 324 // Callback structure
mbed_official 80:2dab120a94c2 325 typedef struct {
mbed_official 80:2dab120a94c2 326 void *fp; // Function pointer
mbed_official 80:2dab120a94c2 327 void *arg; // Function argument
mbed_official 80:2dab120a94c2 328 } osCallback;
mbed_official 80:2dab120a94c2 329
mbed_official 80:2dab120a94c2 330
mbed_official 80:2dab120a94c2 331 // OS Section definitions
mbed_official 80:2dab120a94c2 332 #ifdef OS_SECTIONS_LINK_INFO
mbed_official 80:2dab120a94c2 333 extern const uint32_t os_section_id$$Base;
mbed_official 80:2dab120a94c2 334 extern const uint32_t os_section_id$$Limit;
mbed_official 80:2dab120a94c2 335 #endif
mbed_official 80:2dab120a94c2 336
mbed_official 80:2dab120a94c2 337 // OS Timers external resources
mbed_official 80:2dab120a94c2 338 extern osThreadDef_t os_thread_def_osTimerThread;
mbed_official 80:2dab120a94c2 339 extern osThreadId osThreadId_osTimerThread;
mbed_official 80:2dab120a94c2 340 extern osMessageQDef_t os_messageQ_def_osTimerMessageQ;
mbed_official 80:2dab120a94c2 341 extern osMessageQId osMessageQId_osTimerMessageQ;
mbed_official 80:2dab120a94c2 342
mbed_official 80:2dab120a94c2 343
mbed_official 80:2dab120a94c2 344 // ==== Helper Functions ====
mbed_official 80:2dab120a94c2 345
mbed_official 80:2dab120a94c2 346 /// Convert timeout in millisec to system ticks
mbed_official 80:2dab120a94c2 347 static uint32_t rt_ms2tick (uint32_t millisec) {
mbed_official 80:2dab120a94c2 348 uint32_t tick;
mbed_official 80:2dab120a94c2 349
mbed_official 80:2dab120a94c2 350 if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout
mbed_official 80:2dab120a94c2 351 if (millisec > 4000000) return 0xFFFE; // Max ticks supported
mbed_official 80:2dab120a94c2 352
mbed_official 80:2dab120a94c2 353 tick = ((1000 * millisec) + os_clockrate - 1) / os_clockrate;
mbed_official 80:2dab120a94c2 354 if (tick > 0xFFFE) return 0xFFFE;
mbed_official 80:2dab120a94c2 355
mbed_official 80:2dab120a94c2 356 return tick;
mbed_official 80:2dab120a94c2 357 }
mbed_official 80:2dab120a94c2 358
mbed_official 80:2dab120a94c2 359 /// Convert Thread ID to TCB pointer
mbed_official 80:2dab120a94c2 360 static P_TCB rt_tid2ptcb (osThreadId thread_id) {
mbed_official 80:2dab120a94c2 361 P_TCB ptcb;
mbed_official 80:2dab120a94c2 362
mbed_official 80:2dab120a94c2 363 if (thread_id == NULL) return NULL;
mbed_official 80:2dab120a94c2 364
mbed_official 80:2dab120a94c2 365 if ((uint32_t)thread_id & 3) return NULL;
mbed_official 80:2dab120a94c2 366
mbed_official 80:2dab120a94c2 367 #ifdef OS_SECTIONS_LINK_INFO
mbed_official 80:2dab120a94c2 368 if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) {
mbed_official 80:2dab120a94c2 369 if (thread_id < (osThreadId)os_section_id$$Base) return NULL;
mbed_official 80:2dab120a94c2 370 if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL;
mbed_official 80:2dab120a94c2 371 }
mbed_official 80:2dab120a94c2 372 #endif
mbed_official 80:2dab120a94c2 373
mbed_official 80:2dab120a94c2 374 ptcb = thread_id;
mbed_official 80:2dab120a94c2 375
mbed_official 80:2dab120a94c2 376 if (ptcb->cb_type != TCB) return NULL;
mbed_official 80:2dab120a94c2 377
mbed_official 80:2dab120a94c2 378 return ptcb;
mbed_official 80:2dab120a94c2 379 }
mbed_official 80:2dab120a94c2 380
mbed_official 80:2dab120a94c2 381 /// Convert ID pointer to Object pointer
mbed_official 80:2dab120a94c2 382 static void *rt_id2obj (void *id) {
mbed_official 80:2dab120a94c2 383
mbed_official 80:2dab120a94c2 384 if ((uint32_t)id & 3) return NULL;
mbed_official 80:2dab120a94c2 385
mbed_official 80:2dab120a94c2 386 #ifdef OS_SECTIONS_LINK_INFO
mbed_official 80:2dab120a94c2 387 if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) {
mbed_official 80:2dab120a94c2 388 if (id < (void *)os_section_id$$Base) return NULL;
mbed_official 80:2dab120a94c2 389 if (id >= (void *)os_section_id$$Limit) return NULL;
mbed_official 80:2dab120a94c2 390 }
mbed_official 80:2dab120a94c2 391 #endif
mbed_official 80:2dab120a94c2 392
mbed_official 80:2dab120a94c2 393 return id;
mbed_official 80:2dab120a94c2 394 }
mbed_official 80:2dab120a94c2 395
mbed_official 80:2dab120a94c2 396
mbed_official 80:2dab120a94c2 397 // ==== Kernel Control ====
mbed_official 80:2dab120a94c2 398
mbed_official 80:2dab120a94c2 399 uint8_t os_initialized; // Kernel Initialized flag
mbed_official 80:2dab120a94c2 400 uint8_t os_running; // Kernel Running flag
mbed_official 80:2dab120a94c2 401
mbed_official 80:2dab120a94c2 402 // Kernel Control Service Calls declarations
mbed_official 80:2dab120a94c2 403 SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus)
mbed_official 80:2dab120a94c2 404 SVC_0_1(svcKernelStart, osStatus, RET_osStatus)
mbed_official 80:2dab120a94c2 405 SVC_0_1(svcKernelRunning, int32_t, RET_int32_t)
mbed_official 80:2dab120a94c2 406
mbed_official 80:2dab120a94c2 407 extern void sysThreadError (osStatus status);
mbed_official 80:2dab120a94c2 408 osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument);
mbed_official 80:2dab120a94c2 409 osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id);
mbed_official 80:2dab120a94c2 410
mbed_official 80:2dab120a94c2 411 // Kernel Control Service Calls
mbed_official 80:2dab120a94c2 412
mbed_official 80:2dab120a94c2 413 /// Initialize the RTOS Kernel for creating objects
mbed_official 80:2dab120a94c2 414 osStatus svcKernelInitialize (void) {
mbed_official 80:2dab120a94c2 415 if (os_initialized) return osOK;
mbed_official 80:2dab120a94c2 416
mbed_official 80:2dab120a94c2 417 rt_sys_init(); // RTX System Initialization
mbed_official 80:2dab120a94c2 418 os_tsk.run->prio = 255; // Highest priority
mbed_official 80:2dab120a94c2 419
mbed_official 80:2dab120a94c2 420 sysThreadError(osOK);
mbed_official 80:2dab120a94c2 421
mbed_official 80:2dab120a94c2 422 os_initialized = 1;
mbed_official 80:2dab120a94c2 423
mbed_official 80:2dab120a94c2 424 return osOK;
mbed_official 80:2dab120a94c2 425 }
mbed_official 80:2dab120a94c2 426
mbed_official 80:2dab120a94c2 427 /// Start the RTOS Kernel
mbed_official 80:2dab120a94c2 428 osStatus svcKernelStart (void) {
mbed_official 80:2dab120a94c2 429
mbed_official 80:2dab120a94c2 430 if (os_running) return osOK;
mbed_official 80:2dab120a94c2 431
mbed_official 80:2dab120a94c2 432 // Create OS Timers resources (Message Queue & Thread)
mbed_official 80:2dab120a94c2 433 osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL);
mbed_official 80:2dab120a94c2 434 osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL);
mbed_official 80:2dab120a94c2 435
mbed_official 80:2dab120a94c2 436 rt_tsk_prio(0, 0); // Lowest priority
mbed_official 80:2dab120a94c2 437 // __set_SP(os_tsk.run->tsk_stack + 8*4); // New context
mbed_official 80:2dab120a94c2 438 os_tsk.run = NULL; // Force context switch
mbed_official 80:2dab120a94c2 439
mbed_official 80:2dab120a94c2 440 rt_sys_start();
mbed_official 80:2dab120a94c2 441
mbed_official 80:2dab120a94c2 442 os_running = 1;
mbed_official 80:2dab120a94c2 443
mbed_official 80:2dab120a94c2 444 return osOK;
mbed_official 80:2dab120a94c2 445 }
mbed_official 80:2dab120a94c2 446
mbed_official 80:2dab120a94c2 447 /// Check if the RTOS kernel is already started
mbed_official 80:2dab120a94c2 448 int32_t svcKernelRunning(void) {
mbed_official 80:2dab120a94c2 449 return os_running;
mbed_official 80:2dab120a94c2 450 }
mbed_official 80:2dab120a94c2 451
mbed_official 80:2dab120a94c2 452 // Kernel Control Public API
mbed_official 80:2dab120a94c2 453
mbed_official 80:2dab120a94c2 454 /// Initialize the RTOS Kernel for creating objects
mbed_official 80:2dab120a94c2 455 osStatus osKernelInitialize (void) {
mbed_official 80:2dab120a94c2 456 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 457 if (__get_CONTROL() == MODE_SUPERVISOR) { // Privileged mode
mbed_official 80:2dab120a94c2 458 return svcKernelInitialize();
mbed_official 80:2dab120a94c2 459 } else {
mbed_official 80:2dab120a94c2 460 return __svcKernelInitialize();
mbed_official 80:2dab120a94c2 461 }
mbed_official 80:2dab120a94c2 462 }
mbed_official 80:2dab120a94c2 463
mbed_official 80:2dab120a94c2 464 /// Start the RTOS Kernel
mbed_official 80:2dab120a94c2 465 osStatus osKernelStart (void) {
mbed_official 80:2dab120a94c2 466
mbed_official 80:2dab120a94c2 467 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 468 switch (__get_CONTROL()) {
mbed_official 80:2dab120a94c2 469 case MODE_SUPERVISOR: // Privileged mode
mbed_official 80:2dab120a94c2 470 break;
mbed_official 80:2dab120a94c2 471 case MODE_USER:
mbed_official 80:2dab120a94c2 472 case MODE_SYSTEM: // Unprivileged mode
mbed_official 80:2dab120a94c2 473 return osErrorOS;
mbed_official 80:2dab120a94c2 474 default: // Other invalid modes
mbed_official 80:2dab120a94c2 475 return osErrorOS;
mbed_official 80:2dab120a94c2 476 break;
mbed_official 80:2dab120a94c2 477 }
mbed_official 80:2dab120a94c2 478 return svcKernelStart();
mbed_official 80:2dab120a94c2 479 }
mbed_official 80:2dab120a94c2 480
mbed_official 80:2dab120a94c2 481 /// Check if the RTOS kernel is already started
mbed_official 80:2dab120a94c2 482 int32_t osKernelRunning(void) {
mbed_official 80:2dab120a94c2 483 if ((__get_CONTROL() == MODE_IRQ) || (__get_CONTROL() == MODE_SUPERVISOR)) {
mbed_official 80:2dab120a94c2 484 // in ISR or Privileged
mbed_official 80:2dab120a94c2 485 return os_running;
mbed_official 80:2dab120a94c2 486 } else {
mbed_official 80:2dab120a94c2 487 return __svcKernelRunning();
mbed_official 80:2dab120a94c2 488 }
mbed_official 80:2dab120a94c2 489 }
mbed_official 80:2dab120a94c2 490
mbed_official 80:2dab120a94c2 491
mbed_official 80:2dab120a94c2 492 // ==== Thread Management ====
mbed_official 80:2dab120a94c2 493
mbed_official 80:2dab120a94c2 494 __NO_RETURN void osThreadExit (void);
mbed_official 80:2dab120a94c2 495
mbed_official 80:2dab120a94c2 496 // Thread Service Calls declarations
mbed_official 80:2dab120a94c2 497 SVC_2_1(svcThreadCreate, osThreadId, osThreadDef_t *, void *, RET_pointer)
mbed_official 80:2dab120a94c2 498 SVC_0_1(svcThreadGetId, osThreadId, RET_pointer)
mbed_official 80:2dab120a94c2 499 SVC_1_1(svcThreadTerminate, osStatus, osThreadId, RET_osStatus)
mbed_official 80:2dab120a94c2 500 SVC_0_1(svcThreadYield, osStatus, RET_osStatus)
mbed_official 80:2dab120a94c2 501 SVC_2_1(svcThreadSetPriority, osStatus, osThreadId, osPriority, RET_osStatus)
mbed_official 80:2dab120a94c2 502 SVC_1_1(svcThreadGetPriority, osPriority, osThreadId, RET_osPriority)
mbed_official 80:2dab120a94c2 503
mbed_official 80:2dab120a94c2 504 // Thread Service Calls
mbed_official 80:2dab120a94c2 505 extern OS_TID rt_get_TID (void);
mbed_official 80:2dab120a94c2 506 extern void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body);
mbed_official 80:2dab120a94c2 507
mbed_official 80:2dab120a94c2 508 /// Create a thread and add it to Active Threads and set it to state READY
mbed_official 80:2dab120a94c2 509 osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument) {
mbed_official 80:2dab120a94c2 510 P_TCB ptcb;
mbed_official 80:2dab120a94c2 511
mbed_official 80:2dab120a94c2 512 if ((thread_def == NULL) ||
mbed_official 80:2dab120a94c2 513 (thread_def->pthread == NULL) ||
mbed_official 80:2dab120a94c2 514 (thread_def->tpriority < osPriorityIdle) ||
mbed_official 80:2dab120a94c2 515 (thread_def->tpriority > osPriorityRealtime) ||
mbed_official 80:2dab120a94c2 516 (thread_def->stacksize == 0) ||
mbed_official 80:2dab120a94c2 517 (thread_def->stack_pointer == NULL) ) {
mbed_official 80:2dab120a94c2 518 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 519 return NULL;
mbed_official 80:2dab120a94c2 520 }
mbed_official 80:2dab120a94c2 521
mbed_official 80:2dab120a94c2 522 U8 priority = thread_def->tpriority - osPriorityIdle + 1;
mbed_official 80:2dab120a94c2 523 P_TCB task_context = &thread_def->tcb;
mbed_official 80:2dab120a94c2 524
mbed_official 80:2dab120a94c2 525 /* Utilize the user provided stack. */
mbed_official 80:2dab120a94c2 526 task_context->stack = (U32*)thread_def->stack_pointer;
mbed_official 80:2dab120a94c2 527 task_context->priv_stack = thread_def->stacksize;
mbed_official 80:2dab120a94c2 528 /* Find a free entry in 'os_active_TCB' table. */
mbed_official 80:2dab120a94c2 529 OS_TID tsk = rt_get_TID ();
mbed_official 80:2dab120a94c2 530 os_active_TCB[tsk-1] = task_context;
mbed_official 80:2dab120a94c2 531 task_context->task_id = tsk;
mbed_official 80:2dab120a94c2 532 /* Pass parameter 'argv' to 'rt_init_context' */
mbed_official 80:2dab120a94c2 533 task_context->msg = argument;
mbed_official 80:2dab120a94c2 534 /* For 'size == 0' system allocates the user stack from the memory pool. */
mbed_official 80:2dab120a94c2 535 rt_init_context (task_context, priority, (FUNCP)thread_def->pthread);
mbed_official 80:2dab120a94c2 536
mbed_official 80:2dab120a94c2 537 /* Dispatch this task to the scheduler for execution. */
mbed_official 80:2dab120a94c2 538 DBG_TASK_NOTIFY(task_context, __TRUE);
mbed_official 80:2dab120a94c2 539 rt_dispatch (task_context);
mbed_official 80:2dab120a94c2 540
mbed_official 80:2dab120a94c2 541 ptcb = (P_TCB)os_active_TCB[tsk - 1]; // TCB pointer
mbed_official 80:2dab120a94c2 542
mbed_official 80:2dab120a94c2 543 *((uint32_t *)ptcb->tsk_stack + TCB_STACK_LR_OFFSET_DWORDS) = (uint32_t)osThreadExit; /* LR = osThreadExit */
mbed_official 80:2dab120a94c2 544
mbed_official 80:2dab120a94c2 545 return ptcb;
mbed_official 80:2dab120a94c2 546 }
mbed_official 80:2dab120a94c2 547
mbed_official 80:2dab120a94c2 548 /// Return the thread ID of the current running thread
mbed_official 80:2dab120a94c2 549 osThreadId svcThreadGetId (void) {
mbed_official 80:2dab120a94c2 550 OS_TID tsk;
mbed_official 80:2dab120a94c2 551
mbed_official 80:2dab120a94c2 552 tsk = rt_tsk_self();
mbed_official 80:2dab120a94c2 553 if (tsk == 0) return NULL;
mbed_official 80:2dab120a94c2 554 return (P_TCB)os_active_TCB[tsk - 1];
mbed_official 80:2dab120a94c2 555 }
mbed_official 80:2dab120a94c2 556
mbed_official 80:2dab120a94c2 557 /// Terminate execution of a thread and remove it from ActiveThreads
mbed_official 80:2dab120a94c2 558 osStatus svcThreadTerminate (osThreadId thread_id) {
mbed_official 80:2dab120a94c2 559 OS_RESULT res;
mbed_official 80:2dab120a94c2 560 P_TCB ptcb;
mbed_official 80:2dab120a94c2 561
mbed_official 80:2dab120a94c2 562 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 80:2dab120a94c2 563 if (ptcb == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 564
mbed_official 80:2dab120a94c2 565 res = rt_tsk_delete(ptcb->task_id); // Delete task
mbed_official 80:2dab120a94c2 566
mbed_official 80:2dab120a94c2 567 if (res == OS_R_NOK) return osErrorResource; // Delete task failed
mbed_official 80:2dab120a94c2 568
mbed_official 80:2dab120a94c2 569 return osOK;
mbed_official 80:2dab120a94c2 570 }
mbed_official 80:2dab120a94c2 571
mbed_official 80:2dab120a94c2 572 /// Pass control to next thread that is in state READY
mbed_official 80:2dab120a94c2 573 osStatus svcThreadYield (void) {
mbed_official 80:2dab120a94c2 574 rt_tsk_pass(); // Pass control to next task
mbed_official 80:2dab120a94c2 575 return osOK;
mbed_official 80:2dab120a94c2 576 }
mbed_official 80:2dab120a94c2 577
mbed_official 80:2dab120a94c2 578 /// Change priority of an active thread
mbed_official 80:2dab120a94c2 579 osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) {
mbed_official 80:2dab120a94c2 580 OS_RESULT res;
mbed_official 80:2dab120a94c2 581 P_TCB ptcb;
mbed_official 80:2dab120a94c2 582
mbed_official 80:2dab120a94c2 583 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 80:2dab120a94c2 584 if (ptcb == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 585
mbed_official 80:2dab120a94c2 586 if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) {
mbed_official 80:2dab120a94c2 587 return osErrorValue;
mbed_official 80:2dab120a94c2 588 }
mbed_official 80:2dab120a94c2 589
mbed_official 80:2dab120a94c2 590 res = rt_tsk_prio( // Change task priority
mbed_official 80:2dab120a94c2 591 ptcb->task_id, // Task ID
mbed_official 80:2dab120a94c2 592 priority - osPriorityIdle + 1 // New task priority
mbed_official 80:2dab120a94c2 593 );
mbed_official 80:2dab120a94c2 594
mbed_official 80:2dab120a94c2 595 if (res == OS_R_NOK) return osErrorResource; // Change task priority failed
mbed_official 80:2dab120a94c2 596
mbed_official 80:2dab120a94c2 597 return osOK;
mbed_official 80:2dab120a94c2 598 }
mbed_official 80:2dab120a94c2 599
mbed_official 80:2dab120a94c2 600 /// Get current priority of an active thread
mbed_official 80:2dab120a94c2 601 osPriority svcThreadGetPriority (osThreadId thread_id) {
mbed_official 80:2dab120a94c2 602 P_TCB ptcb;
mbed_official 80:2dab120a94c2 603
mbed_official 80:2dab120a94c2 604 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 80:2dab120a94c2 605 if (ptcb == NULL) return osPriorityError;
mbed_official 80:2dab120a94c2 606
mbed_official 80:2dab120a94c2 607 return (osPriority)(ptcb->prio - 1 + osPriorityIdle);
mbed_official 80:2dab120a94c2 608 }
mbed_official 80:2dab120a94c2 609
mbed_official 80:2dab120a94c2 610
mbed_official 80:2dab120a94c2 611 // Thread Public API
mbed_official 80:2dab120a94c2 612
mbed_official 80:2dab120a94c2 613 /// Create a thread and add it to Active Threads and set it to state READY
mbed_official 80:2dab120a94c2 614 osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) {
mbed_official 80:2dab120a94c2 615 if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR
mbed_official 80:2dab120a94c2 616 if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) {
mbed_official 80:2dab120a94c2 617 // Privileged and not running
mbed_official 80:2dab120a94c2 618 return svcThreadCreate(thread_def, argument);
mbed_official 80:2dab120a94c2 619 } else {
mbed_official 80:2dab120a94c2 620 return __svcThreadCreate(thread_def, argument);
mbed_official 80:2dab120a94c2 621 }
mbed_official 80:2dab120a94c2 622 }
mbed_official 80:2dab120a94c2 623
mbed_official 80:2dab120a94c2 624 /// Return the thread ID of the current running thread
mbed_official 80:2dab120a94c2 625 osThreadId osThreadGetId (void) {
mbed_official 80:2dab120a94c2 626 if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR
mbed_official 80:2dab120a94c2 627 return __svcThreadGetId();
mbed_official 80:2dab120a94c2 628 }
mbed_official 80:2dab120a94c2 629
mbed_official 80:2dab120a94c2 630 /// Terminate execution of a thread and remove it from ActiveThreads
mbed_official 80:2dab120a94c2 631 osStatus osThreadTerminate (osThreadId thread_id) {
mbed_official 80:2dab120a94c2 632 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 633 return __svcThreadTerminate(thread_id);
mbed_official 80:2dab120a94c2 634 }
mbed_official 80:2dab120a94c2 635
mbed_official 80:2dab120a94c2 636 /// Pass control to next thread that is in state READY
mbed_official 80:2dab120a94c2 637 osStatus osThreadYield (void) {
mbed_official 80:2dab120a94c2 638 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 639 return __svcThreadYield();
mbed_official 80:2dab120a94c2 640 }
mbed_official 80:2dab120a94c2 641
mbed_official 80:2dab120a94c2 642 /// Change priority of an active thread
mbed_official 80:2dab120a94c2 643 osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) {
mbed_official 80:2dab120a94c2 644 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 645 return __svcThreadSetPriority(thread_id, priority);
mbed_official 80:2dab120a94c2 646 }
mbed_official 80:2dab120a94c2 647
mbed_official 80:2dab120a94c2 648 /// Get current priority of an active thread
mbed_official 80:2dab120a94c2 649 osPriority osThreadGetPriority (osThreadId thread_id) {
mbed_official 80:2dab120a94c2 650 if (__get_CONTROL() == MODE_IRQ) return osPriorityError;// Not allowed in ISR
mbed_official 80:2dab120a94c2 651 return __svcThreadGetPriority(thread_id);
mbed_official 80:2dab120a94c2 652 }
mbed_official 80:2dab120a94c2 653
mbed_official 80:2dab120a94c2 654 /// INTERNAL - Not Public
mbed_official 80:2dab120a94c2 655 /// Auto Terminate Thread on exit (used implicitly when thread exists)
mbed_official 80:2dab120a94c2 656 __NO_RETURN void osThreadExit (void) {
mbed_official 80:2dab120a94c2 657 __svcThreadTerminate(__svcThreadGetId());
mbed_official 80:2dab120a94c2 658 for (;;); // Should never come here
mbed_official 80:2dab120a94c2 659 }
mbed_official 80:2dab120a94c2 660
mbed_official 80:2dab120a94c2 661
mbed_official 80:2dab120a94c2 662 // ==== Generic Wait Functions ====
mbed_official 80:2dab120a94c2 663
mbed_official 80:2dab120a94c2 664 // Generic Wait Service Calls declarations
mbed_official 80:2dab120a94c2 665 SVC_1_1(svcDelay, osStatus, uint32_t, RET_osStatus)
mbed_official 80:2dab120a94c2 666 #if osFeature_Wait != 0
mbed_official 80:2dab120a94c2 667 SVC_1_3(svcWait, os_InRegs osEvent, uint32_t, RET_osEvent)
mbed_official 80:2dab120a94c2 668 #endif
mbed_official 80:2dab120a94c2 669
mbed_official 80:2dab120a94c2 670 // Generic Wait Service Calls
mbed_official 80:2dab120a94c2 671
mbed_official 80:2dab120a94c2 672 /// Wait for Timeout (Time Delay)
mbed_official 80:2dab120a94c2 673 osStatus svcDelay (uint32_t millisec) {
mbed_official 80:2dab120a94c2 674 if (millisec == 0) return osOK;
mbed_official 80:2dab120a94c2 675 rt_dly_wait(rt_ms2tick(millisec));
mbed_official 80:2dab120a94c2 676 return osEventTimeout;
mbed_official 80:2dab120a94c2 677 }
mbed_official 80:2dab120a94c2 678
mbed_official 80:2dab120a94c2 679 /// Wait for Signal, Message, Mail, or Timeout
mbed_official 80:2dab120a94c2 680 #if osFeature_Wait != 0
mbed_official 80:2dab120a94c2 681 os_InRegs osEvent_type svcWait (uint32_t millisec) {
mbed_official 80:2dab120a94c2 682 osEvent ret;
mbed_official 80:2dab120a94c2 683
mbed_official 80:2dab120a94c2 684 if (millisec == 0) {
mbed_official 80:2dab120a94c2 685 ret.status = osOK;
mbed_official 80:2dab120a94c2 686 return osEvent_ret_status;
mbed_official 80:2dab120a94c2 687 }
mbed_official 80:2dab120a94c2 688
mbed_official 80:2dab120a94c2 689 /* To Do: osEventSignal, osEventMessage, osEventMail */
mbed_official 80:2dab120a94c2 690 rt_dly_wait(rt_ms2tick(millisec));
mbed_official 80:2dab120a94c2 691 ret.status = osEventTimeout;
mbed_official 80:2dab120a94c2 692
mbed_official 80:2dab120a94c2 693 return osEvent_ret_status;
mbed_official 80:2dab120a94c2 694 }
mbed_official 80:2dab120a94c2 695 #endif
mbed_official 80:2dab120a94c2 696
mbed_official 80:2dab120a94c2 697
mbed_official 80:2dab120a94c2 698 // Generic Wait API
mbed_official 80:2dab120a94c2 699
mbed_official 80:2dab120a94c2 700 /// Wait for Timeout (Time Delay)
mbed_official 80:2dab120a94c2 701 osStatus osDelay (uint32_t millisec) {
mbed_official 80:2dab120a94c2 702 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 703 return __svcDelay(millisec);
mbed_official 80:2dab120a94c2 704 }
mbed_official 80:2dab120a94c2 705
mbed_official 80:2dab120a94c2 706 /// Wait for Signal, Message, Mail, or Timeout
mbed_official 80:2dab120a94c2 707 os_InRegs osEvent osWait (uint32_t millisec) {
mbed_official 80:2dab120a94c2 708 osEvent ret;
mbed_official 80:2dab120a94c2 709
mbed_official 80:2dab120a94c2 710 #if osFeature_Wait == 0
mbed_official 80:2dab120a94c2 711 ret.status = osErrorOS;
mbed_official 80:2dab120a94c2 712 return ret;
mbed_official 80:2dab120a94c2 713 #else
mbed_official 80:2dab120a94c2 714 if (__get_CONTROL() == MODE_IRQ) { // Not allowed in ISR
mbed_official 80:2dab120a94c2 715 ret.status = osErrorISR;
mbed_official 80:2dab120a94c2 716 return ret;
mbed_official 80:2dab120a94c2 717 }
mbed_official 80:2dab120a94c2 718 return __svcWait(millisec);
mbed_official 80:2dab120a94c2 719 #endif
mbed_official 80:2dab120a94c2 720 }
mbed_official 80:2dab120a94c2 721
mbed_official 80:2dab120a94c2 722
mbed_official 80:2dab120a94c2 723 // ==== Timer Management ====
mbed_official 80:2dab120a94c2 724
mbed_official 80:2dab120a94c2 725 // Timer definitions
mbed_official 80:2dab120a94c2 726 #define osTimerInvalid 0
mbed_official 80:2dab120a94c2 727 #define osTimerStopped 1
mbed_official 80:2dab120a94c2 728 #define osTimerRunning 2
mbed_official 80:2dab120a94c2 729
mbed_official 80:2dab120a94c2 730 // Timer structures
mbed_official 80:2dab120a94c2 731
mbed_official 80:2dab120a94c2 732 typedef struct os_timer_cb_ { // Timer Control Block
mbed_official 80:2dab120a94c2 733 struct os_timer_cb_ *next; // Pointer to next active Timer
mbed_official 80:2dab120a94c2 734 uint8_t state; // Timer State
mbed_official 80:2dab120a94c2 735 uint8_t type; // Timer Type (Periodic/One-shot)
mbed_official 80:2dab120a94c2 736 uint16_t reserved; // Reserved
mbed_official 80:2dab120a94c2 737 uint16_t tcnt; // Timer Delay Count
mbed_official 80:2dab120a94c2 738 uint16_t icnt; // Timer Initial Count
mbed_official 80:2dab120a94c2 739 void *arg; // Timer Function Argument
mbed_official 80:2dab120a94c2 740 osTimerDef_t *timer; // Pointer to Timer definition
mbed_official 80:2dab120a94c2 741 } os_timer_cb;
mbed_official 80:2dab120a94c2 742
mbed_official 80:2dab120a94c2 743 // Timer variables
mbed_official 80:2dab120a94c2 744 os_timer_cb *os_timer_head; // Pointer to first active Timer
mbed_official 80:2dab120a94c2 745
mbed_official 80:2dab120a94c2 746
mbed_official 80:2dab120a94c2 747 // Timer Helper Functions
mbed_official 80:2dab120a94c2 748
mbed_official 80:2dab120a94c2 749 // Insert Timer into the list sorted by time
mbed_official 80:2dab120a94c2 750 static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) {
mbed_official 80:2dab120a94c2 751 os_timer_cb *p, *prev;
mbed_official 80:2dab120a94c2 752
mbed_official 80:2dab120a94c2 753 prev = NULL;
mbed_official 80:2dab120a94c2 754 p = os_timer_head;
mbed_official 80:2dab120a94c2 755 while (p != NULL) {
mbed_official 80:2dab120a94c2 756 if (tcnt < p->tcnt) break;
mbed_official 80:2dab120a94c2 757 tcnt -= p->tcnt;
mbed_official 80:2dab120a94c2 758 prev = p;
mbed_official 80:2dab120a94c2 759 p = p->next;
mbed_official 80:2dab120a94c2 760 }
mbed_official 80:2dab120a94c2 761 pt->next = p;
mbed_official 80:2dab120a94c2 762 pt->tcnt = (uint16_t)tcnt;
mbed_official 80:2dab120a94c2 763 if (p != NULL) {
mbed_official 80:2dab120a94c2 764 p->tcnt -= pt->tcnt;
mbed_official 80:2dab120a94c2 765 }
mbed_official 80:2dab120a94c2 766 if (prev != NULL) {
mbed_official 80:2dab120a94c2 767 prev->next = pt;
mbed_official 80:2dab120a94c2 768 } else {
mbed_official 80:2dab120a94c2 769 os_timer_head = pt;
mbed_official 80:2dab120a94c2 770 }
mbed_official 80:2dab120a94c2 771 }
mbed_official 80:2dab120a94c2 772
mbed_official 80:2dab120a94c2 773 // Remove Timer from the list
mbed_official 80:2dab120a94c2 774 static int rt_timer_remove (os_timer_cb *pt) {
mbed_official 80:2dab120a94c2 775 os_timer_cb *p, *prev;
mbed_official 80:2dab120a94c2 776
mbed_official 80:2dab120a94c2 777 prev = NULL;
mbed_official 80:2dab120a94c2 778 p = os_timer_head;
mbed_official 80:2dab120a94c2 779 while (p != NULL) {
mbed_official 80:2dab120a94c2 780 if (p == pt) break;
mbed_official 80:2dab120a94c2 781 prev = p;
mbed_official 80:2dab120a94c2 782 p = p->next;
mbed_official 80:2dab120a94c2 783 }
mbed_official 80:2dab120a94c2 784 if (p == NULL) return -1;
mbed_official 80:2dab120a94c2 785 if (prev != NULL) {
mbed_official 80:2dab120a94c2 786 prev->next = pt->next;
mbed_official 80:2dab120a94c2 787 } else {
mbed_official 80:2dab120a94c2 788 os_timer_head = pt->next;
mbed_official 80:2dab120a94c2 789 }
mbed_official 80:2dab120a94c2 790 if (pt->next != NULL) {
mbed_official 80:2dab120a94c2 791 pt->next->tcnt += pt->tcnt;
mbed_official 80:2dab120a94c2 792 }
mbed_official 80:2dab120a94c2 793
mbed_official 80:2dab120a94c2 794 return 0;
mbed_official 80:2dab120a94c2 795 }
mbed_official 80:2dab120a94c2 796
mbed_official 80:2dab120a94c2 797
mbed_official 80:2dab120a94c2 798 // Timer Service Calls declarations
mbed_official 80:2dab120a94c2 799 SVC_3_1(svcTimerCreate, osTimerId, osTimerDef_t *, os_timer_type, void *, RET_pointer)
mbed_official 80:2dab120a94c2 800 SVC_2_1(svcTimerStart, osStatus, osTimerId, uint32_t, RET_osStatus)
mbed_official 80:2dab120a94c2 801 SVC_1_1(svcTimerStop, osStatus, osTimerId, RET_osStatus)
mbed_official 80:2dab120a94c2 802 SVC_1_1(svcTimerDelete, osStatus, osTimerId, RET_osStatus)
mbed_official 80:2dab120a94c2 803 SVC_1_2(svcTimerCall, os_InRegs osCallback, osTimerId, RET_osCallback)
mbed_official 80:2dab120a94c2 804
mbed_official 80:2dab120a94c2 805 // Timer Management Service Calls
mbed_official 80:2dab120a94c2 806
mbed_official 80:2dab120a94c2 807 /// Create timer
mbed_official 80:2dab120a94c2 808 osTimerId svcTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) {
mbed_official 80:2dab120a94c2 809 os_timer_cb *pt;
mbed_official 80:2dab120a94c2 810
mbed_official 80:2dab120a94c2 811 if ((timer_def == NULL) || (timer_def->ptimer == NULL)) {
mbed_official 80:2dab120a94c2 812 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 813 return NULL;
mbed_official 80:2dab120a94c2 814 }
mbed_official 80:2dab120a94c2 815
mbed_official 80:2dab120a94c2 816 pt = timer_def->timer;
mbed_official 80:2dab120a94c2 817 if (pt == NULL) {
mbed_official 80:2dab120a94c2 818 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 819 return NULL;
mbed_official 80:2dab120a94c2 820 }
mbed_official 80:2dab120a94c2 821
mbed_official 80:2dab120a94c2 822 if ((type != osTimerOnce) && (type != osTimerPeriodic)) {
mbed_official 80:2dab120a94c2 823 sysThreadError(osErrorValue);
mbed_official 80:2dab120a94c2 824 return NULL;
mbed_official 80:2dab120a94c2 825 }
mbed_official 80:2dab120a94c2 826
mbed_official 80:2dab120a94c2 827 if (osThreadId_osTimerThread == NULL) {
mbed_official 80:2dab120a94c2 828 sysThreadError(osErrorResource);
mbed_official 80:2dab120a94c2 829 return NULL;
mbed_official 80:2dab120a94c2 830 }
mbed_official 80:2dab120a94c2 831
mbed_official 80:2dab120a94c2 832 if (pt->state != osTimerInvalid){
mbed_official 80:2dab120a94c2 833 sysThreadError(osErrorResource);
mbed_official 80:2dab120a94c2 834 return NULL;
mbed_official 80:2dab120a94c2 835 }
mbed_official 80:2dab120a94c2 836
mbed_official 80:2dab120a94c2 837 pt->state = osTimerStopped;
mbed_official 80:2dab120a94c2 838 pt->type = (uint8_t)type;
mbed_official 80:2dab120a94c2 839 pt->arg = argument;
mbed_official 80:2dab120a94c2 840 pt->timer = timer_def;
mbed_official 80:2dab120a94c2 841
mbed_official 80:2dab120a94c2 842 return (osTimerId)pt;
mbed_official 80:2dab120a94c2 843 }
mbed_official 80:2dab120a94c2 844
mbed_official 80:2dab120a94c2 845 /// Start or restart timer
mbed_official 80:2dab120a94c2 846 osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 847 os_timer_cb *pt;
mbed_official 80:2dab120a94c2 848 uint32_t tcnt;
mbed_official 80:2dab120a94c2 849
mbed_official 80:2dab120a94c2 850 pt = rt_id2obj(timer_id);
mbed_official 80:2dab120a94c2 851 if (pt == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 852
mbed_official 80:2dab120a94c2 853 tcnt = rt_ms2tick(millisec);
mbed_official 80:2dab120a94c2 854 if (tcnt == 0) return osErrorValue;
mbed_official 80:2dab120a94c2 855
mbed_official 80:2dab120a94c2 856 switch (pt->state) {
mbed_official 80:2dab120a94c2 857 case osTimerRunning:
mbed_official 80:2dab120a94c2 858 if (rt_timer_remove(pt) != 0) {
mbed_official 80:2dab120a94c2 859 return osErrorResource;
mbed_official 80:2dab120a94c2 860 }
mbed_official 80:2dab120a94c2 861 break;
mbed_official 80:2dab120a94c2 862 case osTimerStopped:
mbed_official 80:2dab120a94c2 863 pt->state = osTimerRunning;
mbed_official 80:2dab120a94c2 864 pt->icnt = (uint16_t)tcnt;
mbed_official 80:2dab120a94c2 865 break;
mbed_official 80:2dab120a94c2 866 default:
mbed_official 80:2dab120a94c2 867 return osErrorResource;
mbed_official 80:2dab120a94c2 868 }
mbed_official 80:2dab120a94c2 869
mbed_official 80:2dab120a94c2 870 rt_timer_insert(pt, tcnt);
mbed_official 80:2dab120a94c2 871
mbed_official 80:2dab120a94c2 872 return osOK;
mbed_official 80:2dab120a94c2 873 }
mbed_official 80:2dab120a94c2 874
mbed_official 80:2dab120a94c2 875 /// Stop timer
mbed_official 80:2dab120a94c2 876 osStatus svcTimerStop (osTimerId timer_id) {
mbed_official 80:2dab120a94c2 877 os_timer_cb *pt;
mbed_official 80:2dab120a94c2 878
mbed_official 80:2dab120a94c2 879 pt = rt_id2obj(timer_id);
mbed_official 80:2dab120a94c2 880 if (pt == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 881
mbed_official 80:2dab120a94c2 882 if (pt->state != osTimerRunning) return osErrorResource;
mbed_official 80:2dab120a94c2 883
mbed_official 80:2dab120a94c2 884 pt->state = osTimerStopped;
mbed_official 80:2dab120a94c2 885
mbed_official 80:2dab120a94c2 886 if (rt_timer_remove(pt) != 0) {
mbed_official 80:2dab120a94c2 887 return osErrorResource;
mbed_official 80:2dab120a94c2 888 }
mbed_official 80:2dab120a94c2 889
mbed_official 80:2dab120a94c2 890 return osOK;
mbed_official 80:2dab120a94c2 891 }
mbed_official 80:2dab120a94c2 892
mbed_official 80:2dab120a94c2 893 /// Delete timer
mbed_official 80:2dab120a94c2 894 osStatus svcTimerDelete (osTimerId timer_id) {
mbed_official 80:2dab120a94c2 895 os_timer_cb *pt;
mbed_official 80:2dab120a94c2 896
mbed_official 80:2dab120a94c2 897 pt = rt_id2obj(timer_id);
mbed_official 80:2dab120a94c2 898 if (pt == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 899
mbed_official 80:2dab120a94c2 900 switch (pt->state) {
mbed_official 80:2dab120a94c2 901 case osTimerRunning:
mbed_official 80:2dab120a94c2 902 rt_timer_remove(pt);
mbed_official 80:2dab120a94c2 903 break;
mbed_official 80:2dab120a94c2 904 case osTimerStopped:
mbed_official 80:2dab120a94c2 905 break;
mbed_official 80:2dab120a94c2 906 default:
mbed_official 80:2dab120a94c2 907 return osErrorResource;
mbed_official 80:2dab120a94c2 908 }
mbed_official 80:2dab120a94c2 909
mbed_official 80:2dab120a94c2 910 pt->state = osTimerInvalid;
mbed_official 80:2dab120a94c2 911
mbed_official 80:2dab120a94c2 912 return osOK;
mbed_official 80:2dab120a94c2 913 }
mbed_official 80:2dab120a94c2 914
mbed_official 80:2dab120a94c2 915 /// Get timer callback parameters
mbed_official 80:2dab120a94c2 916 os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) {
mbed_official 80:2dab120a94c2 917 os_timer_cb *pt;
mbed_official 80:2dab120a94c2 918 osCallback ret;
mbed_official 80:2dab120a94c2 919
mbed_official 80:2dab120a94c2 920 pt = rt_id2obj(timer_id);
mbed_official 80:2dab120a94c2 921 if (pt == NULL) {
mbed_official 80:2dab120a94c2 922 ret.fp = NULL;
mbed_official 80:2dab120a94c2 923 ret.arg = NULL;
mbed_official 80:2dab120a94c2 924 return osCallback_ret;
mbed_official 80:2dab120a94c2 925 }
mbed_official 80:2dab120a94c2 926
mbed_official 80:2dab120a94c2 927 ret.fp = (void *)pt->timer->ptimer;
mbed_official 80:2dab120a94c2 928 ret.arg = pt->arg;
mbed_official 80:2dab120a94c2 929
mbed_official 80:2dab120a94c2 930 return osCallback_ret;
mbed_official 80:2dab120a94c2 931 }
mbed_official 80:2dab120a94c2 932
mbed_official 80:2dab120a94c2 933 static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
mbed_official 80:2dab120a94c2 934
mbed_official 80:2dab120a94c2 935 /// Timer Tick (called each SysTick)
mbed_official 80:2dab120a94c2 936 void sysTimerTick (void) {
mbed_official 80:2dab120a94c2 937 os_timer_cb *pt, *p;
mbed_official 80:2dab120a94c2 938
mbed_official 80:2dab120a94c2 939 p = os_timer_head;
mbed_official 80:2dab120a94c2 940 if (p == NULL) return;
mbed_official 80:2dab120a94c2 941
mbed_official 80:2dab120a94c2 942 p->tcnt--;
mbed_official 80:2dab120a94c2 943 while ((p != NULL) && (p->tcnt == 0)) {
mbed_official 80:2dab120a94c2 944 pt = p;
mbed_official 80:2dab120a94c2 945 p = p->next;
mbed_official 80:2dab120a94c2 946 os_timer_head = p;
mbed_official 80:2dab120a94c2 947 isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0);
mbed_official 80:2dab120a94c2 948 if (pt->type == osTimerPeriodic) {
mbed_official 80:2dab120a94c2 949 rt_timer_insert(pt, pt->icnt);
mbed_official 80:2dab120a94c2 950 } else {
mbed_official 80:2dab120a94c2 951 pt->state = osTimerStopped;
mbed_official 80:2dab120a94c2 952 }
mbed_official 80:2dab120a94c2 953 }
mbed_official 80:2dab120a94c2 954 }
mbed_official 80:2dab120a94c2 955
mbed_official 80:2dab120a94c2 956
mbed_official 80:2dab120a94c2 957 // Timer Management Public API
mbed_official 80:2dab120a94c2 958
mbed_official 80:2dab120a94c2 959 /// Create timer
mbed_official 80:2dab120a94c2 960 osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) {
mbed_official 80:2dab120a94c2 961 if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR
mbed_official 80:2dab120a94c2 962 if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) {
mbed_official 80:2dab120a94c2 963 // Privileged and not running
mbed_official 80:2dab120a94c2 964 return svcTimerCreate(timer_def, type, argument);
mbed_official 80:2dab120a94c2 965 } else {
mbed_official 80:2dab120a94c2 966 return __svcTimerCreate(timer_def, type, argument);
mbed_official 80:2dab120a94c2 967 }
mbed_official 80:2dab120a94c2 968 }
mbed_official 80:2dab120a94c2 969
mbed_official 80:2dab120a94c2 970 /// Start or restart timer
mbed_official 80:2dab120a94c2 971 osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 972 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 973 return __svcTimerStart(timer_id, millisec);
mbed_official 80:2dab120a94c2 974 }
mbed_official 80:2dab120a94c2 975
mbed_official 80:2dab120a94c2 976 /// Stop timer
mbed_official 80:2dab120a94c2 977 osStatus osTimerStop (osTimerId timer_id) {
mbed_official 80:2dab120a94c2 978 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 979 return __svcTimerStop(timer_id);
mbed_official 80:2dab120a94c2 980 }
mbed_official 80:2dab120a94c2 981
mbed_official 80:2dab120a94c2 982 /// Delete timer
mbed_official 80:2dab120a94c2 983 osStatus osTimerDelete (osTimerId timer_id) {
mbed_official 80:2dab120a94c2 984 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 985 return __svcTimerDelete(timer_id);
mbed_official 80:2dab120a94c2 986 }
mbed_official 80:2dab120a94c2 987
mbed_official 80:2dab120a94c2 988 /// INTERNAL - Not Public
mbed_official 80:2dab120a94c2 989 /// Get timer callback parameters (used by OS Timer Thread)
mbed_official 80:2dab120a94c2 990 os_InRegs osCallback osTimerCall (osTimerId timer_id) {
mbed_official 80:2dab120a94c2 991 return __svcTimerCall(timer_id);
mbed_official 80:2dab120a94c2 992 }
mbed_official 80:2dab120a94c2 993
mbed_official 80:2dab120a94c2 994
mbed_official 80:2dab120a94c2 995 // Timer Thread
mbed_official 80:2dab120a94c2 996 __NO_RETURN void osTimerThread (void const *argument) {
mbed_official 80:2dab120a94c2 997 osCallback cb;
mbed_official 80:2dab120a94c2 998 osEvent evt;
mbed_official 80:2dab120a94c2 999
mbed_official 80:2dab120a94c2 1000 for (;;) {
mbed_official 80:2dab120a94c2 1001 evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever);
mbed_official 80:2dab120a94c2 1002 if (evt.status == osEventMessage) {
mbed_official 80:2dab120a94c2 1003 cb = osTimerCall(evt.value.p);
mbed_official 80:2dab120a94c2 1004 if (cb.fp != NULL) {
mbed_official 80:2dab120a94c2 1005 (*(os_ptimer)cb.fp)(cb.arg);
mbed_official 80:2dab120a94c2 1006 }
mbed_official 80:2dab120a94c2 1007 }
mbed_official 80:2dab120a94c2 1008 }
mbed_official 80:2dab120a94c2 1009 }
mbed_official 80:2dab120a94c2 1010
mbed_official 80:2dab120a94c2 1011
mbed_official 80:2dab120a94c2 1012 // ==== Signal Management ====
mbed_official 80:2dab120a94c2 1013
mbed_official 80:2dab120a94c2 1014 // Signal Service Calls declarations
mbed_official 80:2dab120a94c2 1015 SVC_2_1(svcSignalSet, int32_t, osThreadId, int32_t, RET_int32_t)
mbed_official 80:2dab120a94c2 1016 SVC_2_1(svcSignalClear, int32_t, osThreadId, int32_t, RET_int32_t)
mbed_official 80:2dab120a94c2 1017 SVC_1_1(svcSignalGet, int32_t, osThreadId, RET_int32_t)
mbed_official 80:2dab120a94c2 1018 SVC_2_3(svcSignalWait, os_InRegs osEvent, int32_t, uint32_t, RET_osEvent)
mbed_official 80:2dab120a94c2 1019
mbed_official 80:2dab120a94c2 1020 // Signal Service Calls
mbed_official 80:2dab120a94c2 1021
mbed_official 80:2dab120a94c2 1022 /// Set the specified Signal Flags of an active thread
mbed_official 80:2dab120a94c2 1023 int32_t svcSignalSet (osThreadId thread_id, int32_t signals) {
mbed_official 80:2dab120a94c2 1024 P_TCB ptcb;
mbed_official 80:2dab120a94c2 1025 int32_t sig;
mbed_official 80:2dab120a94c2 1026
mbed_official 80:2dab120a94c2 1027 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 80:2dab120a94c2 1028 if (ptcb == NULL) return 0x80000000;
mbed_official 80:2dab120a94c2 1029
mbed_official 80:2dab120a94c2 1030 if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
mbed_official 80:2dab120a94c2 1031
mbed_official 80:2dab120a94c2 1032 sig = ptcb->events; // Previous signal flags
mbed_official 80:2dab120a94c2 1033
mbed_official 80:2dab120a94c2 1034 rt_evt_set(signals, ptcb->task_id); // Set event flags
mbed_official 80:2dab120a94c2 1035
mbed_official 80:2dab120a94c2 1036 return sig;
mbed_official 80:2dab120a94c2 1037 }
mbed_official 80:2dab120a94c2 1038
mbed_official 80:2dab120a94c2 1039 /// Clear the specified Signal Flags of an active thread
mbed_official 80:2dab120a94c2 1040 int32_t svcSignalClear (osThreadId thread_id, int32_t signals) {
mbed_official 80:2dab120a94c2 1041 P_TCB ptcb;
mbed_official 80:2dab120a94c2 1042 int32_t sig;
mbed_official 80:2dab120a94c2 1043
mbed_official 80:2dab120a94c2 1044 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 80:2dab120a94c2 1045 if (ptcb == NULL) return 0x80000000;
mbed_official 80:2dab120a94c2 1046
mbed_official 80:2dab120a94c2 1047 if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
mbed_official 80:2dab120a94c2 1048
mbed_official 80:2dab120a94c2 1049 sig = ptcb->events; // Previous signal flags
mbed_official 80:2dab120a94c2 1050
mbed_official 80:2dab120a94c2 1051 rt_evt_clr(signals, ptcb->task_id); // Clear event flags
mbed_official 80:2dab120a94c2 1052
mbed_official 80:2dab120a94c2 1053 return sig;
mbed_official 80:2dab120a94c2 1054 }
mbed_official 80:2dab120a94c2 1055
mbed_official 80:2dab120a94c2 1056 /// Get Signal Flags status of an active thread
mbed_official 80:2dab120a94c2 1057 int32_t svcSignalGet (osThreadId thread_id) {
mbed_official 80:2dab120a94c2 1058 P_TCB ptcb;
mbed_official 80:2dab120a94c2 1059
mbed_official 80:2dab120a94c2 1060 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 80:2dab120a94c2 1061 if (ptcb == NULL) return 0x80000000;
mbed_official 80:2dab120a94c2 1062
mbed_official 80:2dab120a94c2 1063 return ptcb->events; // Return event flags
mbed_official 80:2dab120a94c2 1064 }
mbed_official 80:2dab120a94c2 1065
mbed_official 80:2dab120a94c2 1066 /// Wait for one or more Signal Flags to become signaled for the current RUNNING thread
mbed_official 80:2dab120a94c2 1067 os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1068 OS_RESULT res;
mbed_official 80:2dab120a94c2 1069 osEvent ret;
mbed_official 80:2dab120a94c2 1070
mbed_official 80:2dab120a94c2 1071 if (signals & (0xFFFFFFFF << osFeature_Signals)) {
mbed_official 80:2dab120a94c2 1072 ret.status = osErrorValue;
mbed_official 80:2dab120a94c2 1073 return osEvent_ret_status;
mbed_official 80:2dab120a94c2 1074 }
mbed_official 80:2dab120a94c2 1075
mbed_official 80:2dab120a94c2 1076 if (signals != 0) { // Wait for all specified signals
mbed_official 80:2dab120a94c2 1077 res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE);
mbed_official 80:2dab120a94c2 1078 } else { // Wait for any signal
mbed_official 80:2dab120a94c2 1079 res = rt_evt_wait(0xFFFF, rt_ms2tick(millisec), __FALSE);
mbed_official 80:2dab120a94c2 1080 }
mbed_official 80:2dab120a94c2 1081
mbed_official 80:2dab120a94c2 1082 if (res == OS_R_EVT) {
mbed_official 80:2dab120a94c2 1083 ret.status = osEventSignal;
mbed_official 80:2dab120a94c2 1084 ret.value.signals = signals ? signals : os_tsk.run->waits;
mbed_official 80:2dab120a94c2 1085 } else {
mbed_official 80:2dab120a94c2 1086 ret.status = millisec ? osEventTimeout : osOK;
mbed_official 80:2dab120a94c2 1087 ret.value.signals = 0;
mbed_official 80:2dab120a94c2 1088 }
mbed_official 80:2dab120a94c2 1089
mbed_official 80:2dab120a94c2 1090 return osEvent_ret_value;
mbed_official 80:2dab120a94c2 1091 }
mbed_official 80:2dab120a94c2 1092
mbed_official 80:2dab120a94c2 1093
mbed_official 80:2dab120a94c2 1094 // Signal ISR Calls
mbed_official 80:2dab120a94c2 1095
mbed_official 80:2dab120a94c2 1096 /// Set the specified Signal Flags of an active thread
mbed_official 80:2dab120a94c2 1097 static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) {
mbed_official 80:2dab120a94c2 1098 P_TCB ptcb;
mbed_official 80:2dab120a94c2 1099 int32_t sig;
mbed_official 80:2dab120a94c2 1100
mbed_official 80:2dab120a94c2 1101 ptcb = rt_tid2ptcb(thread_id); // Get TCB pointer
mbed_official 80:2dab120a94c2 1102 if (ptcb == NULL) return 0x80000000;
mbed_official 80:2dab120a94c2 1103
mbed_official 80:2dab120a94c2 1104 if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
mbed_official 80:2dab120a94c2 1105
mbed_official 80:2dab120a94c2 1106 sig = ptcb->events; // Previous signal flags
mbed_official 80:2dab120a94c2 1107
mbed_official 80:2dab120a94c2 1108 isr_evt_set(signals, ptcb->task_id); // Set event flags
mbed_official 80:2dab120a94c2 1109
mbed_official 80:2dab120a94c2 1110 return sig;
mbed_official 80:2dab120a94c2 1111 }
mbed_official 80:2dab120a94c2 1112
mbed_official 80:2dab120a94c2 1113
mbed_official 80:2dab120a94c2 1114 // Signal Public API
mbed_official 80:2dab120a94c2 1115
mbed_official 80:2dab120a94c2 1116 /// Set the specified Signal Flags of an active thread
mbed_official 80:2dab120a94c2 1117 int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
mbed_official 80:2dab120a94c2 1118 if (__get_CONTROL() == MODE_IRQ) { // in ISR
mbed_official 80:2dab120a94c2 1119 return isrSignalSet(thread_id, signals);
mbed_official 80:2dab120a94c2 1120 } else { // in Thread
mbed_official 80:2dab120a94c2 1121 return __svcSignalSet(thread_id, signals);
mbed_official 80:2dab120a94c2 1122 }
mbed_official 80:2dab120a94c2 1123 }
mbed_official 80:2dab120a94c2 1124
mbed_official 80:2dab120a94c2 1125 /// Clear the specified Signal Flags of an active thread
mbed_official 80:2dab120a94c2 1126 int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
mbed_official 80:2dab120a94c2 1127 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1128 return __svcSignalClear(thread_id, signals);
mbed_official 80:2dab120a94c2 1129 }
mbed_official 80:2dab120a94c2 1130
mbed_official 80:2dab120a94c2 1131 /// Get Signal Flags status of an active thread
mbed_official 80:2dab120a94c2 1132 int32_t osSignalGet (osThreadId thread_id) {
mbed_official 80:2dab120a94c2 1133 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1134 return __svcSignalGet(thread_id);
mbed_official 80:2dab120a94c2 1135 }
mbed_official 80:2dab120a94c2 1136
mbed_official 80:2dab120a94c2 1137 /// Wait for one or more Signal Flags to become signaled for the current RUNNING thread
mbed_official 80:2dab120a94c2 1138 os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1139 osEvent ret;
mbed_official 80:2dab120a94c2 1140
mbed_official 80:2dab120a94c2 1141 if (__get_CONTROL() == MODE_IRQ) { // Not allowed in ISR
mbed_official 80:2dab120a94c2 1142 ret.status = osErrorISR;
mbed_official 80:2dab120a94c2 1143 return ret;
mbed_official 80:2dab120a94c2 1144 }
mbed_official 80:2dab120a94c2 1145 return __svcSignalWait(signals, millisec);
mbed_official 80:2dab120a94c2 1146 }
mbed_official 80:2dab120a94c2 1147
mbed_official 80:2dab120a94c2 1148
mbed_official 80:2dab120a94c2 1149 // ==== Mutex Management ====
mbed_official 80:2dab120a94c2 1150
mbed_official 80:2dab120a94c2 1151 // Mutex Service Calls declarations
mbed_official 80:2dab120a94c2 1152 SVC_1_1(svcMutexCreate, osMutexId, osMutexDef_t *, RET_pointer)
mbed_official 80:2dab120a94c2 1153 SVC_2_1(svcMutexWait, osStatus, osMutexId, uint32_t, RET_osStatus)
mbed_official 80:2dab120a94c2 1154 SVC_1_1(svcMutexRelease, osStatus, osMutexId, RET_osStatus)
mbed_official 80:2dab120a94c2 1155 SVC_1_1(svcMutexDelete, osStatus, osMutexId, RET_osStatus)
mbed_official 80:2dab120a94c2 1156
mbed_official 80:2dab120a94c2 1157 // Mutex Service Calls
mbed_official 80:2dab120a94c2 1158
mbed_official 80:2dab120a94c2 1159 /// Create and Initialize a Mutex object
mbed_official 80:2dab120a94c2 1160 osMutexId svcMutexCreate (osMutexDef_t *mutex_def) {
mbed_official 80:2dab120a94c2 1161 OS_ID mut;
mbed_official 80:2dab120a94c2 1162
mbed_official 80:2dab120a94c2 1163 if (mutex_def == NULL) {
mbed_official 80:2dab120a94c2 1164 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1165 return NULL;
mbed_official 80:2dab120a94c2 1166 }
mbed_official 80:2dab120a94c2 1167
mbed_official 80:2dab120a94c2 1168 mut = mutex_def->mutex;
mbed_official 80:2dab120a94c2 1169 if (mut == NULL) {
mbed_official 80:2dab120a94c2 1170 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1171 return NULL;
mbed_official 80:2dab120a94c2 1172 }
mbed_official 80:2dab120a94c2 1173
mbed_official 80:2dab120a94c2 1174 if (((P_MUCB)mut)->cb_type != 0) {
mbed_official 80:2dab120a94c2 1175 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1176 return NULL;
mbed_official 80:2dab120a94c2 1177 }
mbed_official 80:2dab120a94c2 1178
mbed_official 80:2dab120a94c2 1179 rt_mut_init(mut); // Initialize Mutex
mbed_official 80:2dab120a94c2 1180
mbed_official 80:2dab120a94c2 1181 return mut;
mbed_official 80:2dab120a94c2 1182 }
mbed_official 80:2dab120a94c2 1183
mbed_official 80:2dab120a94c2 1184 /// Wait until a Mutex becomes available
mbed_official 80:2dab120a94c2 1185 osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1186 OS_ID mut;
mbed_official 80:2dab120a94c2 1187 OS_RESULT res;
mbed_official 80:2dab120a94c2 1188
mbed_official 80:2dab120a94c2 1189 mut = rt_id2obj(mutex_id);
mbed_official 80:2dab120a94c2 1190 if (mut == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1191
mbed_official 80:2dab120a94c2 1192 if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
mbed_official 80:2dab120a94c2 1193
mbed_official 80:2dab120a94c2 1194 res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex
mbed_official 80:2dab120a94c2 1195
mbed_official 80:2dab120a94c2 1196 if (res == OS_R_TMO) {
mbed_official 80:2dab120a94c2 1197 return (millisec ? osErrorTimeoutResource : osErrorResource);
mbed_official 80:2dab120a94c2 1198 }
mbed_official 80:2dab120a94c2 1199
mbed_official 80:2dab120a94c2 1200 return osOK;
mbed_official 80:2dab120a94c2 1201 }
mbed_official 80:2dab120a94c2 1202
mbed_official 80:2dab120a94c2 1203 /// Release a Mutex that was obtained with osMutexWait
mbed_official 80:2dab120a94c2 1204 osStatus svcMutexRelease (osMutexId mutex_id) {
mbed_official 80:2dab120a94c2 1205 OS_ID mut;
mbed_official 80:2dab120a94c2 1206 OS_RESULT res;
mbed_official 80:2dab120a94c2 1207
mbed_official 80:2dab120a94c2 1208 mut = rt_id2obj(mutex_id);
mbed_official 80:2dab120a94c2 1209 if (mut == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1210
mbed_official 80:2dab120a94c2 1211 if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
mbed_official 80:2dab120a94c2 1212
mbed_official 80:2dab120a94c2 1213 res = rt_mut_release(mut); // Release Mutex
mbed_official 80:2dab120a94c2 1214
mbed_official 80:2dab120a94c2 1215 if (res == OS_R_NOK) return osErrorResource; // Thread not owner or Zero Counter
mbed_official 80:2dab120a94c2 1216
mbed_official 80:2dab120a94c2 1217 return osOK;
mbed_official 80:2dab120a94c2 1218 }
mbed_official 80:2dab120a94c2 1219
mbed_official 80:2dab120a94c2 1220 /// Delete a Mutex that was created by osMutexCreate
mbed_official 80:2dab120a94c2 1221 osStatus svcMutexDelete (osMutexId mutex_id) {
mbed_official 80:2dab120a94c2 1222 OS_ID mut;
mbed_official 80:2dab120a94c2 1223
mbed_official 80:2dab120a94c2 1224 mut = rt_id2obj(mutex_id);
mbed_official 80:2dab120a94c2 1225 if (mut == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1226
mbed_official 80:2dab120a94c2 1227 if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
mbed_official 80:2dab120a94c2 1228
mbed_official 80:2dab120a94c2 1229 rt_mut_delete(mut); // Release Mutex
mbed_official 80:2dab120a94c2 1230
mbed_official 80:2dab120a94c2 1231 return osOK;
mbed_official 80:2dab120a94c2 1232 }
mbed_official 80:2dab120a94c2 1233
mbed_official 80:2dab120a94c2 1234
mbed_official 80:2dab120a94c2 1235 // Mutex Public API
mbed_official 80:2dab120a94c2 1236
mbed_official 80:2dab120a94c2 1237 /// Create and Initialize a Mutex object
mbed_official 80:2dab120a94c2 1238 osMutexId osMutexCreate (osMutexDef_t *mutex_def) {
mbed_official 80:2dab120a94c2 1239 if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1240 if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) {
mbed_official 80:2dab120a94c2 1241 // Privileged and not running
mbed_official 80:2dab120a94c2 1242 return svcMutexCreate(mutex_def);
mbed_official 80:2dab120a94c2 1243 } else {
mbed_official 80:2dab120a94c2 1244 return __svcMutexCreate(mutex_def);
mbed_official 80:2dab120a94c2 1245 }
mbed_official 80:2dab120a94c2 1246 }
mbed_official 80:2dab120a94c2 1247
mbed_official 80:2dab120a94c2 1248 /// Wait until a Mutex becomes available
mbed_official 80:2dab120a94c2 1249 osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1250 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1251 return __svcMutexWait(mutex_id, millisec);
mbed_official 80:2dab120a94c2 1252 }
mbed_official 80:2dab120a94c2 1253
mbed_official 80:2dab120a94c2 1254 /// Release a Mutex that was obtained with osMutexWait
mbed_official 80:2dab120a94c2 1255 osStatus osMutexRelease (osMutexId mutex_id) {
mbed_official 80:2dab120a94c2 1256 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1257 return __svcMutexRelease(mutex_id);
mbed_official 80:2dab120a94c2 1258 }
mbed_official 80:2dab120a94c2 1259
mbed_official 80:2dab120a94c2 1260 /// Delete a Mutex that was created by osMutexCreate
mbed_official 80:2dab120a94c2 1261 osStatus osMutexDelete (osMutexId mutex_id) {
mbed_official 80:2dab120a94c2 1262 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1263 return __svcMutexDelete(mutex_id);
mbed_official 80:2dab120a94c2 1264 }
mbed_official 80:2dab120a94c2 1265
mbed_official 80:2dab120a94c2 1266
mbed_official 80:2dab120a94c2 1267 // ==== Semaphore Management ====
mbed_official 80:2dab120a94c2 1268
mbed_official 80:2dab120a94c2 1269 // Semaphore Service Calls declarations
mbed_official 80:2dab120a94c2 1270 SVC_2_1(svcSemaphoreCreate, osSemaphoreId, const osSemaphoreDef_t *, int32_t, RET_pointer)
mbed_official 80:2dab120a94c2 1271 SVC_2_1(svcSemaphoreWait, int32_t, osSemaphoreId, uint32_t, RET_int32_t)
mbed_official 80:2dab120a94c2 1272 SVC_1_1(svcSemaphoreRelease, osStatus, osSemaphoreId, RET_osStatus)
mbed_official 80:2dab120a94c2 1273 SVC_1_1(svcSemaphoreDelete, osStatus, osSemaphoreId, RET_osStatus)
mbed_official 80:2dab120a94c2 1274
mbed_official 80:2dab120a94c2 1275 // Semaphore Service Calls
mbed_official 80:2dab120a94c2 1276
mbed_official 80:2dab120a94c2 1277 /// Create and Initialize a Semaphore object
mbed_official 80:2dab120a94c2 1278 osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
mbed_official 80:2dab120a94c2 1279 OS_ID sem;
mbed_official 80:2dab120a94c2 1280
mbed_official 80:2dab120a94c2 1281 if (semaphore_def == NULL) {
mbed_official 80:2dab120a94c2 1282 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1283 return NULL;
mbed_official 80:2dab120a94c2 1284 }
mbed_official 80:2dab120a94c2 1285
mbed_official 80:2dab120a94c2 1286 sem = semaphore_def->semaphore;
mbed_official 80:2dab120a94c2 1287 if (sem == NULL) {
mbed_official 80:2dab120a94c2 1288 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1289 return NULL;
mbed_official 80:2dab120a94c2 1290 }
mbed_official 80:2dab120a94c2 1291
mbed_official 80:2dab120a94c2 1292 if (((P_SCB)sem)->cb_type != 0) {
mbed_official 80:2dab120a94c2 1293 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1294 return NULL;
mbed_official 80:2dab120a94c2 1295 }
mbed_official 80:2dab120a94c2 1296
mbed_official 80:2dab120a94c2 1297 if (count > osFeature_Semaphore) {
mbed_official 80:2dab120a94c2 1298 sysThreadError(osErrorValue);
mbed_official 80:2dab120a94c2 1299 return NULL;
mbed_official 80:2dab120a94c2 1300 }
mbed_official 80:2dab120a94c2 1301
mbed_official 80:2dab120a94c2 1302 rt_sem_init(sem, count); // Initialize Semaphore
mbed_official 80:2dab120a94c2 1303
mbed_official 80:2dab120a94c2 1304 return sem;
mbed_official 80:2dab120a94c2 1305 }
mbed_official 80:2dab120a94c2 1306
mbed_official 80:2dab120a94c2 1307 /// Wait until a Semaphore becomes available
mbed_official 80:2dab120a94c2 1308 int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1309 OS_ID sem;
mbed_official 80:2dab120a94c2 1310 OS_RESULT res;
mbed_official 80:2dab120a94c2 1311
mbed_official 80:2dab120a94c2 1312 sem = rt_id2obj(semaphore_id);
mbed_official 80:2dab120a94c2 1313 if (sem == NULL) return -1;
mbed_official 80:2dab120a94c2 1314
mbed_official 80:2dab120a94c2 1315 if (((P_SCB)sem)->cb_type != SCB) return -1;
mbed_official 80:2dab120a94c2 1316
mbed_official 80:2dab120a94c2 1317 res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore
mbed_official 80:2dab120a94c2 1318
mbed_official 80:2dab120a94c2 1319 if (res == OS_R_TMO) return 0; // Timeout
mbed_official 80:2dab120a94c2 1320
mbed_official 80:2dab120a94c2 1321 return (((P_SCB)sem)->tokens + 1);
mbed_official 80:2dab120a94c2 1322 }
mbed_official 80:2dab120a94c2 1323
mbed_official 80:2dab120a94c2 1324 /// Release a Semaphore
mbed_official 80:2dab120a94c2 1325 osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) {
mbed_official 80:2dab120a94c2 1326 OS_ID sem;
mbed_official 80:2dab120a94c2 1327
mbed_official 80:2dab120a94c2 1328 sem = rt_id2obj(semaphore_id);
mbed_official 80:2dab120a94c2 1329 if (sem == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1330
mbed_official 80:2dab120a94c2 1331 if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
mbed_official 80:2dab120a94c2 1332
mbed_official 80:2dab120a94c2 1333 if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource;
mbed_official 80:2dab120a94c2 1334
mbed_official 80:2dab120a94c2 1335 rt_sem_send(sem); // Release Semaphore
mbed_official 80:2dab120a94c2 1336
mbed_official 80:2dab120a94c2 1337 return osOK;
mbed_official 80:2dab120a94c2 1338 }
mbed_official 80:2dab120a94c2 1339
mbed_official 80:2dab120a94c2 1340 /// Delete a Semaphore that was created by osSemaphoreCreate
mbed_official 80:2dab120a94c2 1341 osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) {
mbed_official 80:2dab120a94c2 1342 OS_ID sem;
mbed_official 80:2dab120a94c2 1343
mbed_official 80:2dab120a94c2 1344 sem = rt_id2obj(semaphore_id);
mbed_official 80:2dab120a94c2 1345 if (sem == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1346
mbed_official 80:2dab120a94c2 1347 if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
mbed_official 80:2dab120a94c2 1348
mbed_official 80:2dab120a94c2 1349 rt_sem_delete(sem); // Delete Semaphore
mbed_official 80:2dab120a94c2 1350
mbed_official 80:2dab120a94c2 1351 return osOK;
mbed_official 80:2dab120a94c2 1352 }
mbed_official 80:2dab120a94c2 1353
mbed_official 80:2dab120a94c2 1354
mbed_official 80:2dab120a94c2 1355 // Semaphore ISR Calls
mbed_official 80:2dab120a94c2 1356
mbed_official 80:2dab120a94c2 1357 /// Release a Semaphore
mbed_official 80:2dab120a94c2 1358 static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) {
mbed_official 80:2dab120a94c2 1359 OS_ID sem;
mbed_official 80:2dab120a94c2 1360
mbed_official 80:2dab120a94c2 1361 sem = rt_id2obj(semaphore_id);
mbed_official 80:2dab120a94c2 1362 if (sem == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1363
mbed_official 80:2dab120a94c2 1364 if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
mbed_official 80:2dab120a94c2 1365
mbed_official 80:2dab120a94c2 1366 if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource;
mbed_official 80:2dab120a94c2 1367
mbed_official 80:2dab120a94c2 1368 isr_sem_send(sem); // Release Semaphore
mbed_official 80:2dab120a94c2 1369
mbed_official 80:2dab120a94c2 1370 return osOK;
mbed_official 80:2dab120a94c2 1371 }
mbed_official 80:2dab120a94c2 1372
mbed_official 80:2dab120a94c2 1373
mbed_official 80:2dab120a94c2 1374 // Semaphore Public API
mbed_official 80:2dab120a94c2 1375
mbed_official 80:2dab120a94c2 1376 /// Create and Initialize a Semaphore object
mbed_official 80:2dab120a94c2 1377 osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count) {
mbed_official 80:2dab120a94c2 1378 if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1379 if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) {
mbed_official 80:2dab120a94c2 1380 // Privileged and not running
mbed_official 80:2dab120a94c2 1381 return svcSemaphoreCreate(semaphore_def, count);
mbed_official 80:2dab120a94c2 1382 } else {
mbed_official 80:2dab120a94c2 1383 return __svcSemaphoreCreate(semaphore_def, count);
mbed_official 80:2dab120a94c2 1384 }
mbed_official 80:2dab120a94c2 1385 }
mbed_official 80:2dab120a94c2 1386
mbed_official 80:2dab120a94c2 1387 /// Wait until a Semaphore becomes available
mbed_official 80:2dab120a94c2 1388 int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1389 if (__get_CONTROL() == MODE_IRQ) return -1; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1390 return __svcSemaphoreWait(semaphore_id, millisec);
mbed_official 80:2dab120a94c2 1391 }
mbed_official 80:2dab120a94c2 1392
mbed_official 80:2dab120a94c2 1393 /// Release a Semaphore
mbed_official 80:2dab120a94c2 1394 osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) {
mbed_official 80:2dab120a94c2 1395 if (__get_CONTROL() == MODE_IRQ) { // in ISR
mbed_official 80:2dab120a94c2 1396 return isrSemaphoreRelease(semaphore_id);
mbed_official 80:2dab120a94c2 1397 } else { // in Thread
mbed_official 80:2dab120a94c2 1398 return __svcSemaphoreRelease(semaphore_id);
mbed_official 80:2dab120a94c2 1399 }
mbed_official 80:2dab120a94c2 1400 }
mbed_official 80:2dab120a94c2 1401
mbed_official 80:2dab120a94c2 1402 /// Delete a Semaphore that was created by osSemaphoreCreate
mbed_official 80:2dab120a94c2 1403 osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) {
mbed_official 80:2dab120a94c2 1404 if (__get_CONTROL() == MODE_IRQ) return osErrorISR; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1405 return __svcSemaphoreDelete(semaphore_id);
mbed_official 80:2dab120a94c2 1406 }
mbed_official 80:2dab120a94c2 1407
mbed_official 80:2dab120a94c2 1408
mbed_official 80:2dab120a94c2 1409 // ==== Memory Management Functions ====
mbed_official 80:2dab120a94c2 1410
mbed_official 80:2dab120a94c2 1411 // Memory Management Helper Functions
mbed_official 80:2dab120a94c2 1412
mbed_official 80:2dab120a94c2 1413 // Clear Memory Box (Zero init)
mbed_official 80:2dab120a94c2 1414 static void rt_clr_box (void *box_mem, void *box) {
mbed_official 80:2dab120a94c2 1415 uint32_t *p, n;
mbed_official 80:2dab120a94c2 1416
mbed_official 80:2dab120a94c2 1417 if (box) {
mbed_official 80:2dab120a94c2 1418 p = box;
mbed_official 80:2dab120a94c2 1419 for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) {
mbed_official 80:2dab120a94c2 1420 *p++ = 0;
mbed_official 80:2dab120a94c2 1421 }
mbed_official 80:2dab120a94c2 1422 }
mbed_official 80:2dab120a94c2 1423 }
mbed_official 80:2dab120a94c2 1424
mbed_official 80:2dab120a94c2 1425 // Memory Management Service Calls declarations
mbed_official 80:2dab120a94c2 1426 SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *, RET_pointer)
mbed_official 80:2dab120a94c2 1427 SVC_2_1(sysPoolAlloc, void *, osPoolId, uint32_t, RET_pointer)
mbed_official 80:2dab120a94c2 1428 SVC_2_1(sysPoolFree, osStatus, osPoolId, void *, RET_osStatus)
mbed_official 80:2dab120a94c2 1429
mbed_official 80:2dab120a94c2 1430 // Memory Management Service & ISR Calls
mbed_official 80:2dab120a94c2 1431
mbed_official 80:2dab120a94c2 1432 /// Create and Initialize memory pool
mbed_official 80:2dab120a94c2 1433 osPoolId svcPoolCreate (const osPoolDef_t *pool_def) {
mbed_official 80:2dab120a94c2 1434 uint32_t blk_sz;
mbed_official 80:2dab120a94c2 1435
mbed_official 80:2dab120a94c2 1436 if ((pool_def == NULL) ||
mbed_official 80:2dab120a94c2 1437 (pool_def->pool_sz == 0) ||
mbed_official 80:2dab120a94c2 1438 (pool_def->item_sz == 0) ||
mbed_official 80:2dab120a94c2 1439 (pool_def->pool == NULL)) {
mbed_official 80:2dab120a94c2 1440 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1441 return NULL;
mbed_official 80:2dab120a94c2 1442 }
mbed_official 80:2dab120a94c2 1443
mbed_official 80:2dab120a94c2 1444 blk_sz = (pool_def->item_sz + 3) & ~3;
mbed_official 80:2dab120a94c2 1445
mbed_official 80:2dab120a94c2 1446 _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz);
mbed_official 80:2dab120a94c2 1447
mbed_official 80:2dab120a94c2 1448 return pool_def->pool;
mbed_official 80:2dab120a94c2 1449 }
mbed_official 80:2dab120a94c2 1450
mbed_official 80:2dab120a94c2 1451 /// Allocate a memory block from a memory pool
mbed_official 80:2dab120a94c2 1452 void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) {
mbed_official 80:2dab120a94c2 1453 void *ptr;
mbed_official 80:2dab120a94c2 1454
mbed_official 80:2dab120a94c2 1455 if (pool_id == NULL) return NULL;
mbed_official 80:2dab120a94c2 1456
mbed_official 80:2dab120a94c2 1457 ptr = rt_alloc_box(pool_id);
mbed_official 80:2dab120a94c2 1458 if (clr) {
mbed_official 80:2dab120a94c2 1459 rt_clr_box(pool_id, ptr);
mbed_official 80:2dab120a94c2 1460 }
mbed_official 80:2dab120a94c2 1461
mbed_official 80:2dab120a94c2 1462 return ptr;
mbed_official 80:2dab120a94c2 1463 }
mbed_official 80:2dab120a94c2 1464
mbed_official 80:2dab120a94c2 1465 /// Return an allocated memory block back to a specific memory pool
mbed_official 80:2dab120a94c2 1466 osStatus sysPoolFree (osPoolId pool_id, void *block) {
mbed_official 80:2dab120a94c2 1467 int32_t res;
mbed_official 80:2dab120a94c2 1468
mbed_official 80:2dab120a94c2 1469 if (pool_id == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1470
mbed_official 80:2dab120a94c2 1471 res = rt_free_box(pool_id, block);
mbed_official 80:2dab120a94c2 1472 if (res != 0) return osErrorValue;
mbed_official 80:2dab120a94c2 1473
mbed_official 80:2dab120a94c2 1474 return osOK;
mbed_official 80:2dab120a94c2 1475 }
mbed_official 80:2dab120a94c2 1476
mbed_official 80:2dab120a94c2 1477
mbed_official 80:2dab120a94c2 1478 // Memory Management Public API
mbed_official 80:2dab120a94c2 1479
mbed_official 80:2dab120a94c2 1480 /// Create and Initialize memory pool
mbed_official 80:2dab120a94c2 1481 osPoolId osPoolCreate (osPoolDef_t *pool_def) {
mbed_official 80:2dab120a94c2 1482 if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1483 if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) {
mbed_official 80:2dab120a94c2 1484 // Privileged and not running
mbed_official 80:2dab120a94c2 1485 return svcPoolCreate(pool_def);
mbed_official 80:2dab120a94c2 1486 } else {
mbed_official 80:2dab120a94c2 1487 return __svcPoolCreate(pool_def);
mbed_official 80:2dab120a94c2 1488 }
mbed_official 80:2dab120a94c2 1489 }
mbed_official 80:2dab120a94c2 1490
mbed_official 80:2dab120a94c2 1491 /// Allocate a memory block from a memory pool
mbed_official 80:2dab120a94c2 1492 void *osPoolAlloc (osPoolId pool_id) {
mbed_official 80:2dab120a94c2 1493 if ((__get_CONTROL() == MODE_IRQ) || (__get_CONTROL() == MODE_SUPERVISOR)) { // in ISR or Privileged
mbed_official 80:2dab120a94c2 1494 return sysPoolAlloc(pool_id, 0);
mbed_official 80:2dab120a94c2 1495 } else { // in Thread
mbed_official 80:2dab120a94c2 1496 return __sysPoolAlloc(pool_id, 0);
mbed_official 80:2dab120a94c2 1497 }
mbed_official 80:2dab120a94c2 1498 }
mbed_official 80:2dab120a94c2 1499
mbed_official 80:2dab120a94c2 1500 /// Allocate a memory block from a memory pool and set memory block to zero
mbed_official 80:2dab120a94c2 1501 void *osPoolCAlloc (osPoolId pool_id) {
mbed_official 80:2dab120a94c2 1502 if ((__get_CONTROL() == MODE_IRQ) || (__get_CONTROL() == MODE_SUPERVISOR)) { // in ISR or Privileged
mbed_official 80:2dab120a94c2 1503 return sysPoolAlloc(pool_id, 1);
mbed_official 80:2dab120a94c2 1504 } else { // in Thread
mbed_official 80:2dab120a94c2 1505 return __sysPoolAlloc(pool_id, 1);
mbed_official 80:2dab120a94c2 1506 }
mbed_official 80:2dab120a94c2 1507 }
mbed_official 80:2dab120a94c2 1508
mbed_official 80:2dab120a94c2 1509 /// Return an allocated memory block back to a specific memory pool
mbed_official 80:2dab120a94c2 1510 osStatus osPoolFree (osPoolId pool_id, void *block) {
mbed_official 80:2dab120a94c2 1511 if ((__get_CONTROL() == MODE_IRQ) || (__get_CONTROL() == MODE_SUPERVISOR)) { // in ISR or Privileged
mbed_official 80:2dab120a94c2 1512 return sysPoolFree(pool_id, block);
mbed_official 80:2dab120a94c2 1513 } else { // in Thread
mbed_official 80:2dab120a94c2 1514 return __sysPoolFree(pool_id, block);
mbed_official 80:2dab120a94c2 1515 }
mbed_official 80:2dab120a94c2 1516 }
mbed_official 80:2dab120a94c2 1517
mbed_official 80:2dab120a94c2 1518
mbed_official 80:2dab120a94c2 1519 // ==== Message Queue Management Functions ====
mbed_official 80:2dab120a94c2 1520
mbed_official 80:2dab120a94c2 1521 // Message Queue Management Service Calls declarations
mbed_official 80:2dab120a94c2 1522 SVC_2_1(svcMessageCreate, osMessageQId, osMessageQDef_t *, osThreadId, RET_pointer)
mbed_official 80:2dab120a94c2 1523 SVC_3_1(svcMessagePut, osStatus, osMessageQId, uint32_t, uint32_t, RET_osStatus)
mbed_official 80:2dab120a94c2 1524 SVC_2_3(svcMessageGet, os_InRegs osEvent, osMessageQId, uint32_t, RET_osEvent)
mbed_official 80:2dab120a94c2 1525
mbed_official 80:2dab120a94c2 1526 // Message Queue Service Calls
mbed_official 80:2dab120a94c2 1527
mbed_official 80:2dab120a94c2 1528 /// Create and Initialize Message Queue
mbed_official 80:2dab120a94c2 1529 osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) {
mbed_official 80:2dab120a94c2 1530
mbed_official 80:2dab120a94c2 1531 if ((queue_def == NULL) ||
mbed_official 80:2dab120a94c2 1532 (queue_def->queue_sz == 0) ||
mbed_official 80:2dab120a94c2 1533 (queue_def->pool == NULL)) {
mbed_official 80:2dab120a94c2 1534 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1535 return NULL;
mbed_official 80:2dab120a94c2 1536 }
mbed_official 80:2dab120a94c2 1537
mbed_official 80:2dab120a94c2 1538 if (((P_MCB)queue_def->pool)->cb_type != 0) {
mbed_official 80:2dab120a94c2 1539 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1540 return NULL;
mbed_official 80:2dab120a94c2 1541 }
mbed_official 80:2dab120a94c2 1542
mbed_official 80:2dab120a94c2 1543 rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4));
mbed_official 80:2dab120a94c2 1544
mbed_official 80:2dab120a94c2 1545 return queue_def->pool;
mbed_official 80:2dab120a94c2 1546 }
mbed_official 80:2dab120a94c2 1547
mbed_official 80:2dab120a94c2 1548 /// Put a Message to a Queue
mbed_official 80:2dab120a94c2 1549 osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1550 OS_RESULT res;
mbed_official 80:2dab120a94c2 1551
mbed_official 80:2dab120a94c2 1552 if (queue_id == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1553
mbed_official 80:2dab120a94c2 1554 if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter;
mbed_official 80:2dab120a94c2 1555
mbed_official 80:2dab120a94c2 1556 res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec));
mbed_official 80:2dab120a94c2 1557
mbed_official 80:2dab120a94c2 1558 if (res == OS_R_TMO) {
mbed_official 80:2dab120a94c2 1559 return (millisec ? osErrorTimeoutResource : osErrorResource);
mbed_official 80:2dab120a94c2 1560 }
mbed_official 80:2dab120a94c2 1561
mbed_official 80:2dab120a94c2 1562 return osOK;
mbed_official 80:2dab120a94c2 1563 }
mbed_official 80:2dab120a94c2 1564
mbed_official 80:2dab120a94c2 1565 /// Get a Message or Wait for a Message from a Queue
mbed_official 80:2dab120a94c2 1566 os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1567 OS_RESULT res;
mbed_official 80:2dab120a94c2 1568 osEvent ret;
mbed_official 80:2dab120a94c2 1569
mbed_official 80:2dab120a94c2 1570 if (queue_id == NULL) {
mbed_official 80:2dab120a94c2 1571 ret.status = osErrorParameter;
mbed_official 80:2dab120a94c2 1572 return osEvent_ret_status;
mbed_official 80:2dab120a94c2 1573 }
mbed_official 80:2dab120a94c2 1574
mbed_official 80:2dab120a94c2 1575 if (((P_MCB)queue_id)->cb_type != MCB) {
mbed_official 80:2dab120a94c2 1576 ret.status = osErrorParameter;
mbed_official 80:2dab120a94c2 1577 return osEvent_ret_status;
mbed_official 80:2dab120a94c2 1578 }
mbed_official 80:2dab120a94c2 1579
mbed_official 80:2dab120a94c2 1580 res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec));
mbed_official 80:2dab120a94c2 1581
mbed_official 80:2dab120a94c2 1582 if (res == OS_R_TMO) {
mbed_official 80:2dab120a94c2 1583 ret.status = millisec ? osEventTimeout : osOK;
mbed_official 80:2dab120a94c2 1584 return osEvent_ret_value;
mbed_official 80:2dab120a94c2 1585 }
mbed_official 80:2dab120a94c2 1586
mbed_official 80:2dab120a94c2 1587 ret.status = osEventMessage;
mbed_official 80:2dab120a94c2 1588
mbed_official 80:2dab120a94c2 1589 return osEvent_ret_value;
mbed_official 80:2dab120a94c2 1590 }
mbed_official 80:2dab120a94c2 1591
mbed_official 80:2dab120a94c2 1592
mbed_official 80:2dab120a94c2 1593 // Message Queue ISR Calls
mbed_official 80:2dab120a94c2 1594
mbed_official 80:2dab120a94c2 1595 /// Put a Message to a Queue
mbed_official 80:2dab120a94c2 1596 static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1597
mbed_official 80:2dab120a94c2 1598 if ((queue_id == NULL) || (millisec != 0)) {
mbed_official 80:2dab120a94c2 1599 return osErrorParameter;
mbed_official 80:2dab120a94c2 1600 }
mbed_official 80:2dab120a94c2 1601
mbed_official 80:2dab120a94c2 1602 if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter;
mbed_official 80:2dab120a94c2 1603
mbed_official 80:2dab120a94c2 1604 if (rt_mbx_check(queue_id) == 0) { // Check if Queue is full
mbed_official 80:2dab120a94c2 1605 return osErrorResource;
mbed_official 80:2dab120a94c2 1606 }
mbed_official 80:2dab120a94c2 1607
mbed_official 80:2dab120a94c2 1608 isr_mbx_send(queue_id, (void *)info);
mbed_official 80:2dab120a94c2 1609
mbed_official 80:2dab120a94c2 1610 return osOK;
mbed_official 80:2dab120a94c2 1611 }
mbed_official 80:2dab120a94c2 1612
mbed_official 80:2dab120a94c2 1613 /// Get a Message or Wait for a Message from a Queue
mbed_official 80:2dab120a94c2 1614 static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1615 OS_RESULT res;
mbed_official 80:2dab120a94c2 1616 osEvent ret;
mbed_official 80:2dab120a94c2 1617
mbed_official 80:2dab120a94c2 1618 if ((queue_id == NULL) || (millisec != 0)) {
mbed_official 80:2dab120a94c2 1619 ret.status = osErrorParameter;
mbed_official 80:2dab120a94c2 1620 return ret;
mbed_official 80:2dab120a94c2 1621 }
mbed_official 80:2dab120a94c2 1622
mbed_official 80:2dab120a94c2 1623 if (((P_MCB)queue_id)->cb_type != MCB) {
mbed_official 80:2dab120a94c2 1624 ret.status = osErrorParameter;
mbed_official 80:2dab120a94c2 1625 return ret;
mbed_official 80:2dab120a94c2 1626 }
mbed_official 80:2dab120a94c2 1627
mbed_official 80:2dab120a94c2 1628 res = isr_mbx_receive(queue_id, &ret.value.p);
mbed_official 80:2dab120a94c2 1629
mbed_official 80:2dab120a94c2 1630 if (res != OS_R_MBX) {
mbed_official 80:2dab120a94c2 1631 ret.status = osOK;
mbed_official 80:2dab120a94c2 1632 return ret;
mbed_official 80:2dab120a94c2 1633 }
mbed_official 80:2dab120a94c2 1634
mbed_official 80:2dab120a94c2 1635 ret.status = osEventMessage;
mbed_official 80:2dab120a94c2 1636
mbed_official 80:2dab120a94c2 1637 return ret;
mbed_official 80:2dab120a94c2 1638 }
mbed_official 80:2dab120a94c2 1639
mbed_official 80:2dab120a94c2 1640
mbed_official 80:2dab120a94c2 1641 // Message Queue Management Public API
mbed_official 80:2dab120a94c2 1642
mbed_official 80:2dab120a94c2 1643 /// Create and Initialize Message Queue
mbed_official 80:2dab120a94c2 1644 osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) {
mbed_official 80:2dab120a94c2 1645 if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1646 if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) {
mbed_official 80:2dab120a94c2 1647 // Privileged and not running
mbed_official 80:2dab120a94c2 1648 return svcMessageCreate(queue_def, thread_id);
mbed_official 80:2dab120a94c2 1649 } else {
mbed_official 80:2dab120a94c2 1650 return __svcMessageCreate(queue_def, thread_id);
mbed_official 80:2dab120a94c2 1651 }
mbed_official 80:2dab120a94c2 1652 }
mbed_official 80:2dab120a94c2 1653
mbed_official 80:2dab120a94c2 1654 /// Put a Message to a Queue
mbed_official 80:2dab120a94c2 1655 osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1656 if (__get_CONTROL() == MODE_IRQ) { // in ISR
mbed_official 80:2dab120a94c2 1657 return isrMessagePut(queue_id, info, millisec);
mbed_official 80:2dab120a94c2 1658 } else { // in Thread
mbed_official 80:2dab120a94c2 1659 return __svcMessagePut(queue_id, info, millisec);
mbed_official 80:2dab120a94c2 1660 }
mbed_official 80:2dab120a94c2 1661 }
mbed_official 80:2dab120a94c2 1662
mbed_official 80:2dab120a94c2 1663 /// Get a Message or Wait for a Message from a Queue
mbed_official 80:2dab120a94c2 1664 os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1665 if (__get_CONTROL() == MODE_IRQ) { // in ISR
mbed_official 80:2dab120a94c2 1666 return isrMessageGet(queue_id, millisec);
mbed_official 80:2dab120a94c2 1667 } else { // in Thread
mbed_official 80:2dab120a94c2 1668 return __svcMessageGet(queue_id, millisec);
mbed_official 80:2dab120a94c2 1669 }
mbed_official 80:2dab120a94c2 1670 }
mbed_official 80:2dab120a94c2 1671
mbed_official 80:2dab120a94c2 1672
mbed_official 80:2dab120a94c2 1673 // ==== Mail Queue Management Functions ====
mbed_official 80:2dab120a94c2 1674
mbed_official 80:2dab120a94c2 1675 // Mail Queue Management Service Calls declarations
mbed_official 80:2dab120a94c2 1676 SVC_2_1(svcMailCreate, osMailQId, osMailQDef_t *, osThreadId, RET_pointer)
mbed_official 80:2dab120a94c2 1677 SVC_4_1(sysMailAlloc, void *, osMailQId, uint32_t, uint32_t, uint32_t, RET_pointer)
mbed_official 80:2dab120a94c2 1678 SVC_3_1(sysMailFree, osStatus, osMailQId, void *, uint32_t, RET_osStatus)
mbed_official 80:2dab120a94c2 1679
mbed_official 80:2dab120a94c2 1680 // Mail Queue Management Service & ISR Calls
mbed_official 80:2dab120a94c2 1681
mbed_official 80:2dab120a94c2 1682 /// Create and Initialize mail queue
mbed_official 80:2dab120a94c2 1683 osMailQId svcMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) {
mbed_official 80:2dab120a94c2 1684 uint32_t blk_sz;
mbed_official 80:2dab120a94c2 1685 P_MCB pmcb;
mbed_official 80:2dab120a94c2 1686 void *pool;
mbed_official 80:2dab120a94c2 1687
mbed_official 80:2dab120a94c2 1688 if ((queue_def == NULL) ||
mbed_official 80:2dab120a94c2 1689 (queue_def->queue_sz == 0) ||
mbed_official 80:2dab120a94c2 1690 (queue_def->item_sz == 0) ||
mbed_official 80:2dab120a94c2 1691 (queue_def->pool == NULL)) {
mbed_official 80:2dab120a94c2 1692 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1693 return NULL;
mbed_official 80:2dab120a94c2 1694 }
mbed_official 80:2dab120a94c2 1695
mbed_official 80:2dab120a94c2 1696 pmcb = *(((void **)queue_def->pool) + 0);
mbed_official 80:2dab120a94c2 1697 pool = *(((void **)queue_def->pool) + 1);
mbed_official 80:2dab120a94c2 1698
mbed_official 80:2dab120a94c2 1699 if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) {
mbed_official 80:2dab120a94c2 1700 sysThreadError(osErrorParameter);
mbed_official 80:2dab120a94c2 1701 return NULL;
mbed_official 80:2dab120a94c2 1702 }
mbed_official 80:2dab120a94c2 1703
mbed_official 80:2dab120a94c2 1704 blk_sz = (queue_def->item_sz + 3) & ~3;
mbed_official 80:2dab120a94c2 1705
mbed_official 80:2dab120a94c2 1706 _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz);
mbed_official 80:2dab120a94c2 1707
mbed_official 80:2dab120a94c2 1708 rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4));
mbed_official 80:2dab120a94c2 1709
mbed_official 80:2dab120a94c2 1710
mbed_official 80:2dab120a94c2 1711 return queue_def->pool;
mbed_official 80:2dab120a94c2 1712 }
mbed_official 80:2dab120a94c2 1713
mbed_official 80:2dab120a94c2 1714 /// Allocate a memory block from a mail
mbed_official 80:2dab120a94c2 1715 void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) {
mbed_official 80:2dab120a94c2 1716 P_MCB pmcb;
mbed_official 80:2dab120a94c2 1717 void *pool;
mbed_official 80:2dab120a94c2 1718 void *mem;
mbed_official 80:2dab120a94c2 1719
mbed_official 80:2dab120a94c2 1720 if (queue_id == NULL) return NULL;
mbed_official 80:2dab120a94c2 1721
mbed_official 80:2dab120a94c2 1722 pmcb = *(((void **)queue_id) + 0);
mbed_official 80:2dab120a94c2 1723 pool = *(((void **)queue_id) + 1);
mbed_official 80:2dab120a94c2 1724
mbed_official 80:2dab120a94c2 1725 if ((pool == NULL) || (pmcb == NULL)) return NULL;
mbed_official 80:2dab120a94c2 1726
mbed_official 80:2dab120a94c2 1727 if (isr && (millisec != 0)) return NULL;
mbed_official 80:2dab120a94c2 1728
mbed_official 80:2dab120a94c2 1729 mem = rt_alloc_box(pool);
mbed_official 80:2dab120a94c2 1730 if (clr) {
mbed_official 80:2dab120a94c2 1731 rt_clr_box(pool, mem);
mbed_official 80:2dab120a94c2 1732 }
mbed_official 80:2dab120a94c2 1733
mbed_official 80:2dab120a94c2 1734 if ((mem == NULL) && (millisec != 0)) {
mbed_official 80:2dab120a94c2 1735 // Put Task to sleep when Memory not available
mbed_official 80:2dab120a94c2 1736 if (pmcb->p_lnk != NULL) {
mbed_official 80:2dab120a94c2 1737 rt_put_prio((P_XCB)pmcb, os_tsk.run);
mbed_official 80:2dab120a94c2 1738 } else {
mbed_official 80:2dab120a94c2 1739 pmcb->p_lnk = os_tsk.run;
mbed_official 80:2dab120a94c2 1740 os_tsk.run->p_lnk = NULL;
mbed_official 80:2dab120a94c2 1741 os_tsk.run->p_rlnk = (P_TCB)pmcb;
mbed_official 80:2dab120a94c2 1742 // Task is waiting to allocate a message
mbed_official 80:2dab120a94c2 1743 pmcb->state = 3;
mbed_official 80:2dab120a94c2 1744 }
mbed_official 80:2dab120a94c2 1745 rt_block(rt_ms2tick(millisec), WAIT_MBX);
mbed_official 80:2dab120a94c2 1746 }
mbed_official 80:2dab120a94c2 1747
mbed_official 80:2dab120a94c2 1748 return mem;
mbed_official 80:2dab120a94c2 1749 }
mbed_official 80:2dab120a94c2 1750
mbed_official 80:2dab120a94c2 1751 /// Free a memory block from a mail
mbed_official 80:2dab120a94c2 1752 osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) {
mbed_official 80:2dab120a94c2 1753 P_MCB pmcb;
mbed_official 80:2dab120a94c2 1754 P_TCB ptcb;
mbed_official 80:2dab120a94c2 1755 void *pool;
mbed_official 80:2dab120a94c2 1756 void *mem;
mbed_official 80:2dab120a94c2 1757 int32_t res;
mbed_official 80:2dab120a94c2 1758
mbed_official 80:2dab120a94c2 1759 if (queue_id == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1760
mbed_official 80:2dab120a94c2 1761 pmcb = *(((void **)queue_id) + 0);
mbed_official 80:2dab120a94c2 1762 pool = *(((void **)queue_id) + 1);
mbed_official 80:2dab120a94c2 1763
mbed_official 80:2dab120a94c2 1764 if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter;
mbed_official 80:2dab120a94c2 1765
mbed_official 80:2dab120a94c2 1766 res = rt_free_box(pool, mail);
mbed_official 80:2dab120a94c2 1767
mbed_official 80:2dab120a94c2 1768 if (res != 0) return osErrorValue;
mbed_official 80:2dab120a94c2 1769
mbed_official 80:2dab120a94c2 1770 if (pmcb->state == 3) {
mbed_official 80:2dab120a94c2 1771 // Task is waiting to allocate a message
mbed_official 80:2dab120a94c2 1772 if (isr) {
mbed_official 80:2dab120a94c2 1773 rt_psq_enq (pmcb, (U32)pool);
mbed_official 80:2dab120a94c2 1774 rt_psh_req ();
mbed_official 80:2dab120a94c2 1775 } else {
mbed_official 80:2dab120a94c2 1776 mem = rt_alloc_box(pool);
mbed_official 80:2dab120a94c2 1777 if (mem != NULL) {
mbed_official 80:2dab120a94c2 1778 ptcb = rt_get_first((P_XCB)pmcb);
mbed_official 80:2dab120a94c2 1779 if (pmcb->p_lnk == NULL) {
mbed_official 80:2dab120a94c2 1780 pmcb->state = 0;
mbed_official 80:2dab120a94c2 1781 }
mbed_official 80:2dab120a94c2 1782 rt_ret_val(ptcb, (U32)mem);
mbed_official 80:2dab120a94c2 1783 rt_rmv_dly(ptcb);
mbed_official 80:2dab120a94c2 1784 rt_dispatch(ptcb);
mbed_official 80:2dab120a94c2 1785 }
mbed_official 80:2dab120a94c2 1786 }
mbed_official 80:2dab120a94c2 1787 }
mbed_official 80:2dab120a94c2 1788
mbed_official 80:2dab120a94c2 1789 return osOK;
mbed_official 80:2dab120a94c2 1790 }
mbed_official 80:2dab120a94c2 1791
mbed_official 80:2dab120a94c2 1792
mbed_official 80:2dab120a94c2 1793 // Mail Queue Management Public API
mbed_official 80:2dab120a94c2 1794
mbed_official 80:2dab120a94c2 1795 /// Create and Initialize mail queue
mbed_official 80:2dab120a94c2 1796 osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) {
mbed_official 80:2dab120a94c2 1797 if (__get_CONTROL() == MODE_IRQ) return NULL; // Not allowed in ISR
mbed_official 80:2dab120a94c2 1798 if ((__get_CONTROL() == MODE_SUPERVISOR) && (os_running == 0)) {
mbed_official 80:2dab120a94c2 1799 // Privileged and not running
mbed_official 80:2dab120a94c2 1800 return svcMailCreate(queue_def, thread_id);
mbed_official 80:2dab120a94c2 1801 } else {
mbed_official 80:2dab120a94c2 1802 return __svcMailCreate(queue_def, thread_id);
mbed_official 80:2dab120a94c2 1803 }
mbed_official 80:2dab120a94c2 1804 }
mbed_official 80:2dab120a94c2 1805
mbed_official 80:2dab120a94c2 1806 /// Allocate a memory block from a mail
mbed_official 80:2dab120a94c2 1807 void *osMailAlloc (osMailQId queue_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1808 if (__get_CONTROL() == MODE_IRQ) { // in ISR
mbed_official 80:2dab120a94c2 1809 return sysMailAlloc(queue_id, millisec, 1, 0);
mbed_official 80:2dab120a94c2 1810 } else { // in Thread
mbed_official 80:2dab120a94c2 1811 return __sysMailAlloc(queue_id, millisec, 0, 0);
mbed_official 80:2dab120a94c2 1812 }
mbed_official 80:2dab120a94c2 1813 }
mbed_official 80:2dab120a94c2 1814
mbed_official 80:2dab120a94c2 1815 /// Allocate a memory block from a mail and set memory block to zero
mbed_official 80:2dab120a94c2 1816 void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1817 if (__get_CONTROL() == MODE_IRQ) { // in ISR
mbed_official 80:2dab120a94c2 1818 return sysMailAlloc(queue_id, millisec, 1, 1);
mbed_official 80:2dab120a94c2 1819 } else { // in Thread
mbed_official 80:2dab120a94c2 1820 return __sysMailAlloc(queue_id, millisec, 0, 1);
mbed_official 80:2dab120a94c2 1821 }
mbed_official 80:2dab120a94c2 1822 }
mbed_official 80:2dab120a94c2 1823
mbed_official 80:2dab120a94c2 1824 /// Free a memory block from a mail
mbed_official 80:2dab120a94c2 1825 osStatus osMailFree (osMailQId queue_id, void *mail) {
mbed_official 80:2dab120a94c2 1826 if (__get_CONTROL() == MODE_IRQ) { // in ISR
mbed_official 80:2dab120a94c2 1827 return sysMailFree(queue_id, mail, 1);
mbed_official 80:2dab120a94c2 1828 } else { // in Thread
mbed_official 80:2dab120a94c2 1829 return __sysMailFree(queue_id, mail, 0);
mbed_official 80:2dab120a94c2 1830 }
mbed_official 80:2dab120a94c2 1831 }
mbed_official 80:2dab120a94c2 1832
mbed_official 80:2dab120a94c2 1833 /// Put a mail to a queue
mbed_official 80:2dab120a94c2 1834 osStatus osMailPut (osMailQId queue_id, void *mail) {
mbed_official 80:2dab120a94c2 1835 if (queue_id == NULL) return osErrorParameter;
mbed_official 80:2dab120a94c2 1836 if (mail == NULL) return osErrorValue;
mbed_official 80:2dab120a94c2 1837 return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0);
mbed_official 80:2dab120a94c2 1838 }
mbed_official 80:2dab120a94c2 1839
mbed_official 80:2dab120a94c2 1840 /// Get a mail from a queue
mbed_official 80:2dab120a94c2 1841 os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) {
mbed_official 80:2dab120a94c2 1842 osEvent ret;
mbed_official 80:2dab120a94c2 1843
mbed_official 80:2dab120a94c2 1844 if (queue_id == NULL) {
mbed_official 80:2dab120a94c2 1845 ret.status = osErrorParameter;
mbed_official 80:2dab120a94c2 1846 return ret;
mbed_official 80:2dab120a94c2 1847 }
mbed_official 80:2dab120a94c2 1848
mbed_official 80:2dab120a94c2 1849 ret = osMessageGet(*((void **)queue_id), millisec);
mbed_official 80:2dab120a94c2 1850 if (ret.status == osEventMessage) ret.status = osEventMail;
mbed_official 80:2dab120a94c2 1851
mbed_official 80:2dab120a94c2 1852 return ret;
mbed_official 80:2dab120a94c2 1853 }