Counter

Dependencies:   EthernetInterface NTPClient SDFileSystem TextLCD WebSocketClient mbed-rtos mbed Socket lwip-eth lwip-sys lwip FATFileSystem

Committer:
Tuxitheone
Date:
Mon Feb 29 18:59:15 2016 +0000
Revision:
0:ecaf3e593122
TankCounter

Who changed what in which revision?

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