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