Ethernet test for ECE 4180 and others to find your IP address and do a simple HTTP GET request over port 80.

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Committer:
mkersh3
Date:
Thu Apr 04 05:26:09 2013 +0000
Revision:
0:e7ca326e76ee
Ethernet Test for ECE4180 and others to find their IP Address and do a simple HTTP GET request over port 80.

Who changed what in which revision?

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