Final 350 project

Dependencies:   uzair Camera_LS_Y201 F7_Ethernet LCD_DISCO_F746NG NetworkAPI SDFileSystem mbed

Committer:
shoaib_ahmed
Date:
Mon Jul 31 09:16:35 2017 +0000
Revision:
0:791a779d6220
final project;

Who changed what in which revision?

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