fork

Fork of mbed-rtos by mbed official

Committer:
mbed_official
Date:
Thu Nov 06 13:00:11 2014 +0000
Revision:
49:77c8e4604045
Parent:
rtx_ca/rt_CMSIS.c@48:e9a2c7cb57a4
Child:
67:63988a2238f7
Synchronized with git revision 7b90c2ba137baaf9769219e0e8a7b8e8d1299c4f

Full URL: https://github.com/mbedmicro/mbed/commit/7b90c2ba137baaf9769219e0e8a7b8e8d1299c4f/

This target is not yet tested, so it can't be released as part of the official
SDK build for now.

Who changed what in which revision?

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