Ethernetwebsoc

Dependencies:   C12832_lcd LM75B WebSocketClient mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Committer:
GordonSin
Date:
Fri May 31 04:09:54 2013 +0000
Revision:
0:0ed2a7c7190c
31/5/2013;

Who changed what in which revision?

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