in OS_TSK, rename run as tsk_run and new as tsk_new.

Committer:
jonathonfletcher
Date:
Sun Sep 02 03:24:20 2012 +0000
Revision:
0:5f46ebd8588e
in OS_TSK, rename run as tsk_run and new as tsk_new.

Who changed what in which revision?

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