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