うおーるぼっとをWiiリモコンでコントロールする新しいプログラムです。 以前のものより、Wiiリモコンが早く繋がる様になりました。 It is a program which controls A with the Wii remote. ※ A Bluetooth dongle and a Wii remote control are needed.

Dependencies:   USBHost mbed FATFileSystem mbed-rtos

Committer:
jksoft
Date:
Mon Jun 10 16:01:50 2013 +0000
Revision:
0:fccb789424fc
1.0

Who changed what in which revision?

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