ProjetoBB

Dependencies:   F7_Ethernet WebSocketClient mbed mcp3008

Fork of Nucleo_F746ZG_Ethernet by Dieter Graef

Committer:
DieterGraef
Date:
Sat Jun 18 10:49:12 2016 +0000
Revision:
0:f9b6112278fe
Ethernet for the NUCLEO STM32F746 Board Testprogram uses DHCP and NTP to set the clock

Who changed what in which revision?

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