ソースの整理中ですが、利用はできます。 大きなファイルはできないかもしれません。

Dependencies:   EthernetInterface HttpServer TextLCD expatlib mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Fork of giken9_HTMLServer_Sample by Yasushi TAUCHI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rt_CMSIS.c Source File

rt_CMSIS.c

00001 /*----------------------------------------------------------------------------
00002  *      RL-ARM - RTX
00003  *----------------------------------------------------------------------------
00004  *      Name:    rt_CMSIS.c
00005  *      Purpose: CMSIS RTOS API
00006  *      Rev.:    V4.60
00007  *----------------------------------------------------------------------------
00008  *
00009  * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
00010  * All rights reserved.
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are met:
00013  *  - Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  *  - Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  *  - Neither the name of ARM  nor the names of its contributors may be used 
00019  *    to endorse or promote products derived from this software without 
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
00026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  *---------------------------------------------------------------------------*/
00034 
00035 #define __CMSIS_GENERIC
00036 
00037 #if defined (__CORTEX_M4) || defined (__CORTEX_M4F)
00038   #include "core_cm4.h"
00039 #elif defined (__CORTEX_M3)
00040   #include "core_cm3.h"
00041 #elif defined (__CORTEX_M0)
00042   #include "core_cm0.h"
00043 #elif defined (__CORTEX_M0PLUS)
00044   #include "core_cm0plus.h"
00045 #else
00046   #error "Missing __CORTEX_Mx definition"
00047 #endif
00048 
00049 #include "rt_TypeDef.h"
00050 #include "RTX_Conf.h"
00051 #include "rt_System.h"
00052 #include "rt_Task.h"
00053 #include "rt_Event.h"
00054 #include "rt_List.h"
00055 #include "rt_Time.h"
00056 #include "rt_Mutex.h"
00057 #include "rt_Semaphore.h"
00058 #include "rt_Mailbox.h"
00059 #include "rt_MemBox.h"
00060 #include "rt_HAL_CM.h"
00061 
00062 #define os_thread_cb OS_TCB
00063 
00064 #include "cmsis_os.h"
00065 
00066 #if (osFeature_Signals != 16)
00067 #error Invalid "osFeature_Signals" value!
00068 #endif
00069 #if (osFeature_Semaphore > 65535)
00070 #error Invalid "osFeature_Semaphore" value!
00071 #endif
00072 #if (osFeature_Wait != 0)
00073 #error osWait not supported!
00074 #endif
00075 
00076 
00077 // ==== Enumeration, structures, defines ====
00078 
00079 // Service Calls defines
00080 
00081 #if defined (__CC_ARM)          /* ARM Compiler */
00082 
00083 #define __NO_RETURN __declspec(noreturn)
00084 
00085 #define osEvent_type       osEvent
00086 #define osEvent_ret_status ret
00087 #define osEvent_ret_value  ret
00088 #define osEvent_ret_msg    ret
00089 #define osEvent_ret_mail   ret
00090 
00091 #define osCallback_type    osCallback
00092 #define osCallback_ret     ret
00093 
00094 #define SVC_0_1(f,t,...)                                                       \
00095 __svc_indirect(0) t  _##f (t(*)());                                            \
00096                   t     f (void);                                              \
00097 __attribute__((always_inline))                                                 \
00098 static __inline   t __##f (void) {                                             \
00099   return _##f(f);                                                              \
00100 }
00101 
00102 #define SVC_1_1(f,t,t1,...)                                                    \
00103 __svc_indirect(0) t  _##f (t(*)(t1),t1);                                       \
00104                   t     f (t1 a1);                                             \
00105 __attribute__((always_inline))                                                 \
00106 static __inline   t __##f (t1 a1) {                                            \
00107   return _##f(f,a1);                                                           \
00108 }
00109 
00110 #define SVC_2_1(f,t,t1,t2,...)                                                 \
00111 __svc_indirect(0) t  _##f (t(*)(t1,t2),t1,t2);                                 \
00112                   t     f (t1 a1, t2 a2);                                      \
00113 __attribute__((always_inline))                                                 \
00114 static __inline   t __##f (t1 a1, t2 a2) {                                     \
00115   return _##f(f,a1,a2);                                                        \
00116 }
00117 
00118 #define SVC_3_1(f,t,t1,t2,t3,...)                                              \
00119 __svc_indirect(0) t  _##f (t(*)(t1,t2,t3),t1,t2,t3);                           \
00120                   t     f (t1 a1, t2 a2, t3 a3);                               \
00121 __attribute__((always_inline))                                                 \
00122 static __inline   t __##f (t1 a1, t2 a2, t3 a3) {                              \
00123   return _##f(f,a1,a2,a3);                                                     \
00124 }
00125 
00126 #define SVC_4_1(f,t,t1,t2,t3,t4,...)                                           \
00127 __svc_indirect(0) t  _##f (t(*)(t1,t2,t3,t4),t1,t2,t3,t4);                     \
00128                   t     f (t1 a1, t2 a2, t3 a3, t4 a4);                        \
00129 __attribute__((always_inline))                                                 \
00130 static __inline   t __##f (t1 a1, t2 a2, t3 a3, t4 a4) {                       \
00131   return _##f(f,a1,a2,a3,a4);                                                  \
00132 }
00133 
00134 #define SVC_1_2 SVC_1_1 
00135 #define SVC_1_3 SVC_1_1 
00136 #define SVC_2_3 SVC_2_1 
00137 
00138 #elif defined (__GNUC__)        /* GNU Compiler */
00139 
00140 #define __NO_RETURN __attribute__((noreturn))
00141 
00142 typedef uint32_t __attribute__((vector_size(8)))  ret64;
00143 typedef uint32_t __attribute__((vector_size(16))) ret128;
00144 
00145 #define RET_pointer    __r0
00146 #define RET_int32_t    __r0
00147 #define RET_osStatus   __r0
00148 #define RET_osPriority __r0
00149 #define RET_osEvent    {(osStatus)__r0, {(uint32_t)__r1}, {(void *)__r2}}
00150 #define RET_osCallback {(void *)__r0, (void *)__r1}
00151 
00152 #define osEvent_type        ret128
00153 #define osEvent_ret_status (ret128){ret.status}
00154 #define osEvent_ret_value  (ret128){ret.status, ret.value.v}
00155 #define osEvent_ret_msg    (ret128){ret.status, ret.value.v, (uint32_t)ret.def.message_id}
00156 #define osEvent_ret_mail   (ret128){ret.status, ret.value.v, (uint32_t)ret.def.mail_id}
00157 
00158 #define osCallback_type     ret64
00159 #define osCallback_ret     (ret64) {(uint32_t)ret.fp, (uint32_t)ret.arg}
00160 
00161 #define SVC_ArgN(n) \
00162   register int __r##n __asm("r"#n);
00163 
00164 #define SVC_ArgR(n,t,a) \
00165   register t   __r##n __asm("r"#n) = a;
00166 
00167 #define SVC_Arg0()                                                             \
00168   SVC_ArgN(0)                                                                  \
00169   SVC_ArgN(1)                                                                  \
00170   SVC_ArgN(2)                                                                  \
00171   SVC_ArgN(3)
00172 
00173 #define SVC_Arg1(t1)                                                           \
00174   SVC_ArgR(0,t1,a1)                                                            \
00175   SVC_ArgN(1)                                                                  \
00176   SVC_ArgN(2)                                                                  \
00177   SVC_ArgN(3)
00178 
00179 #define SVC_Arg2(t1,t2)                                                        \
00180   SVC_ArgR(0,t1,a1)                                                            \
00181   SVC_ArgR(1,t2,a2)                                                            \
00182   SVC_ArgN(2)                                                                  \
00183   SVC_ArgN(3)
00184 
00185 #define SVC_Arg3(t1,t2,t3)                                                     \
00186   SVC_ArgR(0,t1,a1)                                                            \
00187   SVC_ArgR(1,t2,a2)                                                            \
00188   SVC_ArgR(2,t3,a3)                                                            \
00189   SVC_ArgN(3)
00190 
00191 #define SVC_Arg4(t1,t2,t3,t4)                                                  \
00192   SVC_ArgR(0,t1,a1)                                                            \
00193   SVC_ArgR(1,t2,a2)                                                            \
00194   SVC_ArgR(2,t3,a3)                                                            \
00195   SVC_ArgR(3,t4,a4)
00196 
00197 #if (defined (__CORTEX_M0)) || defined (__CORTEX_M0PLUS)
00198 #define SVC_Call(f)                                                            \
00199   __asm volatile                                                                 \
00200   (                                                                            \
00201     "ldr r7,="#f"\n\t"                                                         \
00202     "mov r12,r7\n\t"                                                           \
00203     "svc 0"                                                                    \
00204     :               "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)         \
00205     :                "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)         \
00206     : "r7", "r12", "lr", "cc"                                                  \
00207   );
00208 #else
00209 #define SVC_Call(f)                                                            \
00210   __asm volatile                                                                 \
00211   (                                                                            \
00212     "ldr r12,="#f"\n\t"                                                        \
00213     "svc 0"                                                                    \
00214     :               "=r" (__r0), "=r" (__r1), "=r" (__r2), "=r" (__r3)         \
00215     :                "r" (__r0),  "r" (__r1),  "r" (__r2),  "r" (__r3)         \
00216     : "r12", "lr", "cc"                                                        \
00217   );
00218 #endif
00219 
00220 #define SVC_0_1(f,t,rv)                                                        \
00221 __attribute__((always_inline))                                                 \
00222 static inline  t __##f (void) {                                                \
00223   SVC_Arg0();                                                                  \
00224   SVC_Call(f);                                                                 \
00225   return (t) rv;                                                               \
00226 }
00227 
00228 #define SVC_1_1(f,t,t1,rv)                                                     \
00229 __attribute__((always_inline))                                                 \
00230 static inline  t __##f (t1 a1) {                                               \
00231   SVC_Arg1(t1);                                                                \
00232   SVC_Call(f);                                                                 \
00233   return (t) rv;                                                               \
00234 }
00235 
00236 #define SVC_2_1(f,t,t1,t2,rv)                                                  \
00237 __attribute__((always_inline))                                                 \
00238 static inline  t __##f (t1 a1, t2 a2) {                                        \
00239   SVC_Arg2(t1,t2);                                                             \
00240   SVC_Call(f);                                                                 \
00241   return (t) rv;                                                               \
00242 }
00243 
00244 #define SVC_3_1(f,t,t1,t2,t3,rv)                                               \
00245 __attribute__((always_inline))                                                 \
00246 static inline  t __##f (t1 a1, t2 a2, t3 a3) {                                 \
00247   SVC_Arg3(t1,t2,t3);                                                          \
00248   SVC_Call(f);                                                                 \
00249   return (t) rv;                                                               \
00250 }
00251 
00252 #define SVC_4_1(f,t,t1,t2,t3,t4,rv)                                            \
00253 __attribute__((always_inline))                                                 \
00254 static inline  t __##f (t1 a1, t2 a2, t3 a3, t4 a4) {                          \
00255   SVC_Arg4(t1,t2,t3,t4);                                                       \
00256   SVC_Call(f);                                                                 \
00257   return (t) rv;                                                               \
00258 }
00259 
00260 #define SVC_1_2 SVC_1_1 
00261 #define SVC_1_3 SVC_1_1 
00262 #define SVC_2_3 SVC_2_1 
00263 
00264 #elif defined (__ICCARM__)      /* IAR Compiler */
00265 
00266 #define __NO_RETURN __noreturn
00267 
00268 #define RET_osEvent        "=r"(ret.status), "=r"(ret.value), "=r"(ret.def)
00269 #define RET_osCallback     "=r"(ret.fp), "=r"(ret.arg)
00270 
00271 #define osEvent_type       osEvent
00272 #define osEvent_ret_status ret
00273 #define osEvent_ret_value  ret
00274 #define osEvent_ret_msg    ret
00275 #define osEvent_ret_mail   ret
00276 
00277 #define osCallback_type    uint64_t
00278 #define osCallback_ret     ((uint64_t)ret.fp | ((uint64_t)ret.arg)<<32)
00279 
00280 #define SVC_Setup(f)                                                           \
00281   __asm(                                                                         \
00282     "mov r12,%0\n"                                                             \
00283     :: "r"(&f): "r12"                                                          \
00284   );
00285 
00286 #define SVC_Ret3()                                                             \
00287   __asm(                                                                         \
00288     "ldr r0,[sp,#0]\n"                                                         \
00289     "ldr r1,[sp,#4]\n"                                                         \
00290     "ldr r2,[sp,#8]\n"                                                         \
00291   );
00292 
00293 #define SVC_0_1(f,t,...)                                                       \
00294 t f (void);                                                                    \
00295 _Pragma("swi_number=0") __swi t _##f (void);                                   \
00296 static inline t __##f (void) {                                                 \
00297   SVC_Setup(f);                                                                \
00298   return _##f();                                                               \
00299 }
00300 
00301 #define SVC_1_1(f,t,t1,...)                                                    \
00302 t f (t1 a1);                                                                   \
00303 _Pragma("swi_number=0") __swi t _##f (t1 a1);                                  \
00304 static inline t __##f (t1 a1) {                                                \
00305   SVC_Setup(f);                                                                \
00306   return _##f(a1);                                                             \
00307 }
00308 
00309 #define SVC_2_1(f,t,t1,t2,...)                                                 \
00310 t f (t1 a1, t2 a2);                                                            \
00311 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2);                           \
00312 static inline t __##f (t1 a1, t2 a2) {                                         \
00313   SVC_Setup(f);                                                                \
00314   return _##f(a1,a2);                                                          \
00315 }
00316 
00317 #define SVC_3_1(f,t,t1,t2,t3,...)                                              \
00318 t f (t1 a1, t2 a2, t3 a3);                                                     \
00319 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3);                    \
00320 static inline t __##f (t1 a1, t2 a2, t3 a3) {                                  \
00321   SVC_Setup(f);                                                                \
00322   return _##f(a1,a2,a3);                                                       \
00323 }
00324 
00325 #define SVC_4_1(f,t,t1,t2,t3,t4,...)                                           \
00326 t f (t1 a1, t2 a2, t3 a3, t4 a4);                                              \
00327 _Pragma("swi_number=0") __swi t _##f (t1 a1, t2 a2, t3 a3, t4 a4);             \
00328 static inline t __##f (t1 a1, t2 a2, t3 a3, t4 a4) {                           \
00329   SVC_Setup(f);                                                                \
00330   return _##f(a1,a2,a3,a4);                                                    \
00331 }
00332 
00333 #define SVC_1_2(f,t,t1,rr)                                                     \
00334 uint64_t f (t1 a1);                                                            \
00335 _Pragma("swi_number=0") __swi uint64_t _##f (t1 a1);                           \
00336 static inline t __##f (t1 a1) {                                                \
00337   t ret;                                                                       \
00338   SVC_Setup(f);                                                                \
00339   _##f(a1);                                                                    \
00340   __asm("" : rr : :);                                                            \
00341   return ret;                                                                  \
00342 }
00343 
00344 #define SVC_1_3(f,t,t1,rr)                                                     \
00345 t f (t1 a1);                                                                   \
00346 void f##_ (t1 a1) {                                                            \
00347   f(a1);                                                                       \
00348   SVC_Ret3();                                                                  \
00349 }                                                                              \
00350 _Pragma("swi_number=0") __swi void _##f (t1 a1);                               \
00351 static inline t __##f (t1 a1) {                                                \
00352   t ret;                                                                       \
00353   SVC_Setup(f##_);                                                             \
00354   _##f(a1);                                                                    \
00355   __asm("" : rr : :);                                                            \
00356   return ret;                                                                  \
00357 }
00358 
00359 #define SVC_2_3(f,t,t1,t2,rr)                                                  \
00360 t f (t1 a1, t2 a2);                                                            \
00361 void f##_ (t1 a1, t2 a2) {                                                     \
00362   f(a1,a2);                                                                    \
00363   SVC_Ret3();                                                                  \
00364 }                                                                              \
00365 _Pragma("swi_number=0") __swi void _##f (t1 a1, t2 a2);                        \
00366 static inline t __##f (t1 a1, t2 a2) {                                         \
00367   t ret;                                                                       \
00368   SVC_Setup(f##_);                                                             \
00369   _##f(a1,a2);                                                                 \
00370   __asm("" : rr : :);                                                            \
00371   return ret;                                                                  \
00372 }
00373 
00374 #endif
00375 
00376 
00377 // Callback structure
00378 typedef struct {
00379   void *fp;             // Function pointer
00380   void *arg;            // Function argument
00381 } osCallback;
00382 
00383 
00384 // OS Section definitions
00385 #ifdef OS_SECTIONS_LINK_INFO
00386 extern const uint32_t  os_section_id$$Base;
00387 extern const uint32_t  os_section_id$$Limit;
00388 #endif
00389 
00390 // OS Timers external resources
00391 extern osThreadDef_t   os_thread_def_osTimerThread;
00392 extern osThreadId      osThreadId_osTimerThread;
00393 extern osMessageQDef_t os_messageQ_def_osTimerMessageQ;
00394 extern osMessageQId    osMessageQId_osTimerMessageQ;
00395 
00396 
00397 // ==== Helper Functions ====
00398 
00399 /// Convert timeout in millisec to system ticks
00400 static uint32_t rt_ms2tick (uint32_t millisec) {
00401   uint32_t tick;
00402 
00403   if (millisec == osWaitForever) return 0xFFFF; // Indefinite timeout
00404   if (millisec > 4000000) return 0xFFFE;        // Max ticks supported
00405 
00406   tick = ((1000 * millisec) + os_clockrate - 1)  / os_clockrate;
00407   if (tick > 0xFFFE) return 0xFFFE;
00408   
00409   return tick;
00410 }
00411 
00412 /// Convert Thread ID to TCB pointer
00413 static P_TCB rt_tid2ptcb (osThreadId thread_id) {
00414   P_TCB ptcb;
00415 
00416   if (thread_id == NULL) return NULL;
00417 
00418   if ((uint32_t)thread_id & 3) return NULL;
00419 
00420 #ifdef OS_SECTIONS_LINK_INFO
00421   if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) {
00422     if (thread_id  < (osThreadId)os_section_id$$Base)  return NULL;
00423     if (thread_id >= (osThreadId)os_section_id$$Limit) return NULL;
00424   }
00425 #endif
00426 
00427   ptcb = thread_id;
00428 
00429   if (ptcb->cb_type != TCB) return NULL;
00430 
00431   return ptcb;
00432 }
00433 
00434 /// Convert ID pointer to Object pointer
00435 static void *rt_id2obj (void *id) {
00436 
00437   if ((uint32_t)id & 3) return NULL;
00438 
00439 #ifdef OS_SECTIONS_LINK_INFO
00440   if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) {
00441     if (id  < (void *)os_section_id$$Base)  return NULL;
00442     if (id >= (void *)os_section_id$$Limit) return NULL;
00443   }
00444 #endif
00445 
00446   return id;
00447 }
00448 
00449 
00450 // ==== Kernel Control ====
00451 
00452 uint8_t os_initialized;                         // Kernel Initialized flag
00453 uint8_t os_running;                             // Kernel Running flag
00454 
00455 // Kernel Control Service Calls declarations
00456 SVC_0_1(svcKernelInitialize, osStatus, RET_osStatus)
00457 SVC_0_1(svcKernelStart,      osStatus, RET_osStatus)
00458 SVC_0_1(svcKernelRunning,    int32_t,  RET_int32_t)
00459 
00460 extern void  sysThreadError   (osStatus status);
00461 osThreadId   svcThreadCreate  (osThreadDef_t *thread_def, void *argument);
00462 osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id);
00463 
00464 // Kernel Control Service Calls
00465 
00466 /// Initialize the RTOS Kernel for creating objects
00467 osStatus svcKernelInitialize (void) {
00468   if (os_initialized) return osOK;
00469 
00470   rt_sys_init();                                // RTX System Initialization
00471   os_tsk.run->prio = 255;                       // Highest priority
00472 
00473   sysThreadError(osOK);
00474 
00475   os_initialized = 1;
00476 
00477   return osOK;
00478 }
00479 
00480 /// Start the RTOS Kernel
00481 osStatus svcKernelStart (void) {
00482 
00483   if (os_running) return osOK;
00484 
00485   // Create OS Timers resources (Message Queue & Thread)
00486   osMessageQId_osTimerMessageQ = svcMessageCreate (&os_messageQ_def_osTimerMessageQ, NULL);
00487   osThreadId_osTimerThread = svcThreadCreate(&os_thread_def_osTimerThread, NULL);
00488 
00489   rt_tsk_prio(0, 0);                            // Lowest priority
00490   __set_PSP(os_tsk.run->tsk_stack + 8*4);       // New context
00491   os_tsk.run = NULL;                            // Force context switch
00492 
00493   rt_sys_start();
00494 
00495   os_running = 1;
00496 
00497   return osOK;
00498 }
00499 
00500 /// Check if the RTOS kernel is already started
00501 int32_t svcKernelRunning(void) {
00502   return os_running;
00503 }
00504 
00505 // Kernel Control Public API
00506 
00507 /// Initialize the RTOS Kernel for creating objects
00508 osStatus osKernelInitialize (void) {
00509   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
00510   if ((__get_CONTROL() & 1) == 0) {             // Privileged mode
00511     return   svcKernelInitialize();
00512   } else {
00513     return __svcKernelInitialize();
00514   }
00515 }
00516 
00517 /// Start the RTOS Kernel
00518 osStatus osKernelStart (void) {
00519   uint32_t stack[8];
00520   
00521   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
00522   switch (__get_CONTROL() & 0x03) {
00523     case 0x00:                                  // Privileged Thread mode & MSP
00524       __set_PSP((uint32_t)(stack + 8));         // Initial PSP
00525       if (os_flags & 1) {                       
00526         __set_CONTROL(0x02);                    // Set Privileged Thread mode & PSP
00527       } else {
00528         __set_CONTROL(0x03);                    // Set Unprivileged Thread mode & PSP
00529       }
00530       __DSB();
00531       __ISB();
00532       break;
00533     case 0x01:                                  // Unprivileged Thread mode & MSP
00534       return osErrorOS;
00535     case 0x02:                                  // Privileged Thread mode & PSP
00536       if ((os_flags & 1) == 0) {                // Unprivileged Thread mode requested
00537         __set_CONTROL(0x03);                    // Set Unprivileged Thread mode & PSP
00538         __DSB();
00539         __ISB();
00540       }
00541       break;
00542     case 0x03:                                  // Unprivileged Thread mode & PSP
00543       if  (os_flags & 1) return osErrorOS;      // Privileged Thread mode requested
00544       break;
00545   }
00546   return __svcKernelStart();
00547 }
00548 
00549 /// Check if the RTOS kernel is already started
00550 int32_t osKernelRunning(void) {
00551   if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) {
00552     // in ISR or Privileged
00553     return os_running;
00554   } else {
00555     return __svcKernelRunning();
00556   }
00557 }
00558 
00559 
00560 // ==== Thread Management ====
00561 
00562 __NO_RETURN void osThreadExit (void);
00563 
00564 // Thread Service Calls declarations
00565 SVC_2_1(svcThreadCreate,      osThreadId, osThreadDef_t *, void *,     RET_pointer)
00566 SVC_0_1(svcThreadGetId,       osThreadId,                              RET_pointer)
00567 SVC_1_1(svcThreadTerminate,   osStatus,   osThreadId,                  RET_osStatus)
00568 SVC_0_1(svcThreadYield,       osStatus,                                RET_osStatus)
00569 SVC_2_1(svcThreadSetPriority, osStatus,   osThreadId,      osPriority, RET_osStatus)
00570 SVC_1_1(svcThreadGetPriority, osPriority, osThreadId,                  RET_osPriority)
00571 
00572 // Thread Service Calls
00573 extern OS_TID rt_get_TID (void);
00574 extern void   rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body);
00575 
00576 /// Create a thread and add it to Active Threads and set it to state READY
00577 osThreadId svcThreadCreate (osThreadDef_t *thread_def, void *argument) {
00578   P_TCB  ptcb;
00579   
00580   if ((thread_def == NULL) ||
00581       (thread_def->pthread == NULL) ||
00582       (thread_def->tpriority < osPriorityIdle) ||
00583       (thread_def->tpriority > osPriorityRealtime) ||
00584       (thread_def->stacksize == 0) ||
00585       (thread_def->stack_pointer == NULL) ) {
00586     sysThreadError(osErrorParameter); 
00587     return NULL; 
00588   }
00589   
00590   U8 priority = thread_def->tpriority - osPriorityIdle + 1;
00591   P_TCB task_context = &thread_def->tcb;
00592   
00593   /* If "size != 0" use a private user provided stack. */
00594   task_context->stack      = (U32*)thread_def->stack_pointer;
00595   task_context->priv_stack = thread_def->stacksize;
00596   /* Pass parameter 'argv' to 'rt_init_context' */
00597   task_context->msg = argument;
00598   /* For 'size == 0' system allocates the user stack from the memory pool. */
00599   rt_init_context (task_context, priority, (FUNCP)thread_def->pthread);
00600 
00601   /* Find a free entry in 'os_active_TCB' table. */
00602   OS_TID tsk = rt_get_TID ();
00603   os_active_TCB[tsk-1] = task_context;
00604   task_context->task_id = tsk;
00605   DBG_TASK_NOTIFY(task_context, __TRUE);
00606   rt_dispatch (task_context);
00607   
00608   ptcb = (P_TCB)os_active_TCB[tsk - 1];         // TCB pointer
00609 
00610   *((uint32_t *)ptcb->tsk_stack + 13) = (uint32_t)osThreadExit;
00611 
00612   return ptcb;
00613 }
00614 
00615 /// Return the thread ID of the current running thread
00616 osThreadId svcThreadGetId (void) {
00617   OS_TID tsk;
00618 
00619   tsk = rt_tsk_self();
00620   if (tsk == 0) return NULL;
00621   return (P_TCB)os_active_TCB[tsk - 1];
00622 }
00623 
00624 /// Terminate execution of a thread and remove it from ActiveThreads
00625 osStatus svcThreadTerminate (osThreadId thread_id) {
00626   OS_RESULT res;
00627   P_TCB     ptcb;
00628   
00629   ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
00630   if (ptcb == NULL) return osErrorParameter;
00631   
00632   res = rt_tsk_delete(ptcb->task_id);           // Delete task
00633 
00634   if (res == OS_R_NOK) return osErrorResource;  // Delete task failed
00635   
00636   return osOK;
00637 }
00638 
00639 /// Pass control to next thread that is in state READY
00640 osStatus svcThreadYield (void) {
00641   rt_tsk_pass();                                // Pass control to next task
00642   return osOK;
00643 }
00644 
00645 /// Change priority of an active thread
00646 osStatus svcThreadSetPriority (osThreadId thread_id, osPriority priority) {
00647   OS_RESULT res;
00648   P_TCB     ptcb;
00649 
00650   ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
00651   if (ptcb == NULL) return osErrorParameter;
00652 
00653   if ((priority < osPriorityIdle) || (priority > osPriorityRealtime)) {
00654     return osErrorValue;
00655   }
00656 
00657   res = rt_tsk_prio(                            // Change task priority
00658     ptcb->task_id,                              // Task ID
00659     priority - osPriorityIdle + 1               // New task priority
00660   );
00661 
00662   if (res == OS_R_NOK) return osErrorResource;  // Change task priority failed
00663 
00664   return osOK;
00665 }
00666 
00667 /// Get current priority of an active thread
00668 osPriority svcThreadGetPriority (osThreadId thread_id) {
00669   P_TCB ptcb;
00670 
00671   ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
00672   if (ptcb == NULL) return osPriorityError;
00673 
00674   return (osPriority)(ptcb->prio - 1 + osPriorityIdle); 
00675 }
00676 
00677 
00678 // Thread Public API
00679 
00680 /// Create a thread and add it to Active Threads and set it to state READY
00681 osThreadId osThreadCreate (osThreadDef_t *thread_def, void *argument) {
00682   if (__get_IPSR() != 0) return NULL;           // Not allowed in ISR
00683   if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
00684     // Privileged and not running
00685     return   svcThreadCreate(thread_def, argument);
00686   } else {
00687     return __svcThreadCreate(thread_def, argument);
00688   }
00689 }
00690 
00691 /// Return the thread ID of the current running thread
00692 osThreadId osThreadGetId (void) {
00693   if (__get_IPSR() != 0) return NULL;           // Not allowed in ISR
00694   return __svcThreadGetId();
00695 }
00696 
00697 /// Terminate execution of a thread and remove it from ActiveThreads
00698 osStatus osThreadTerminate (osThreadId thread_id) {
00699   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
00700   return __svcThreadTerminate(thread_id);
00701 }
00702 
00703 /// Pass control to next thread that is in state READY
00704 osStatus osThreadYield (void) {
00705   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
00706   return __svcThreadYield();
00707 }
00708 
00709 /// Change priority of an active thread
00710 osStatus osThreadSetPriority (osThreadId thread_id, osPriority priority) {
00711   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
00712   return __svcThreadSetPriority(thread_id, priority);
00713 }
00714 
00715 /// Get current priority of an active thread
00716 osPriority osThreadGetPriority (osThreadId thread_id) {
00717   if (__get_IPSR() != 0) return osPriorityError;// Not allowed in ISR
00718   return __svcThreadGetPriority(thread_id);
00719 }
00720 
00721 /// INTERNAL - Not Public
00722 /// Auto Terminate Thread on exit (used implicitly when thread exists)
00723 __NO_RETURN void osThreadExit (void) { 
00724   __svcThreadTerminate(__svcThreadGetId()); 
00725   for (;;);                                     // Should never come here
00726 }
00727 
00728 
00729 // ==== Generic Wait Functions ====
00730 
00731 // Generic Wait Service Calls declarations
00732 SVC_1_1(svcDelay,           osStatus, uint32_t, RET_osStatus)
00733 #if osFeature_Wait != 0
00734 SVC_1_3(svcWait,  os_InRegs osEvent,  uint32_t, RET_osEvent)
00735 #endif
00736 
00737 // Generic Wait Service Calls
00738 
00739 /// Wait for Timeout (Time Delay)
00740 osStatus svcDelay (uint32_t millisec) {
00741   if (millisec == 0) return osOK;
00742   rt_dly_wait(rt_ms2tick(millisec));
00743   return osEventTimeout;
00744 }
00745 
00746 /// Wait for Signal, Message, Mail, or Timeout
00747 #if osFeature_Wait != 0
00748 os_InRegs osEvent_type svcWait (uint32_t millisec) {
00749   osEvent ret;
00750 
00751   if (millisec == 0) {
00752     ret.status = osOK;
00753     return osEvent_ret_status;
00754   }
00755 
00756   /* To Do: osEventSignal, osEventMessage, osEventMail */
00757   rt_dly_wait(rt_ms2tick(millisec));
00758   ret.status = osEventTimeout;
00759 
00760   return osEvent_ret_status;
00761 }
00762 #endif
00763 
00764 
00765 // Generic Wait API
00766 
00767 /// Wait for Timeout (Time Delay)
00768 osStatus osDelay (uint32_t millisec) {
00769   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
00770   return __svcDelay(millisec);
00771 }
00772 
00773 /// Wait for Signal, Message, Mail, or Timeout
00774 os_InRegs osEvent osWait (uint32_t millisec) {
00775   osEvent ret;
00776 
00777 #if osFeature_Wait == 0
00778   ret.status = osErrorOS;
00779   return ret;
00780 #else
00781   if (__get_IPSR() != 0) {                      // Not allowed in ISR
00782     ret.status = osErrorISR;
00783     return ret;
00784   }
00785   return __svcWait(millisec);
00786 #endif
00787 }
00788 
00789 
00790 // ==== Timer Management ====
00791 
00792 // Timer definitions
00793 #define osTimerInvalid  0
00794 #define osTimerStopped  1
00795 #define osTimerRunning  2
00796 
00797 // Timer structures 
00798 
00799 typedef struct os_timer_cb_ {                   // Timer Control Block
00800   struct os_timer_cb_ *next;                    // Pointer to next active Timer
00801   uint8_t             state;                    // Timer State
00802   uint8_t              type;                    // Timer Type (Periodic/One-shot)
00803   uint16_t         reserved;                    // Reserved
00804   uint16_t             tcnt;                    // Timer Delay Count
00805   uint16_t             icnt;                    // Timer Initial Count 
00806   void                 *arg;                    // Timer Function Argument
00807   osTimerDef_t       *timer;                    // Pointer to Timer definition
00808 } os_timer_cb;
00809 
00810 // Timer variables
00811 os_timer_cb *os_timer_head;                     // Pointer to first active Timer
00812 
00813 
00814 // Timer Helper Functions
00815 
00816 // Insert Timer into the list sorted by time
00817 static void rt_timer_insert (os_timer_cb *pt, uint32_t tcnt) {
00818   os_timer_cb *p, *prev;
00819 
00820   prev = NULL;
00821   p = os_timer_head;
00822   while (p != NULL) {
00823     if (tcnt < p->tcnt) break;
00824     tcnt -= p->tcnt;
00825     prev = p;
00826     p = p->next;
00827   }
00828   pt->next = p;
00829   pt->tcnt = (uint16_t)tcnt;
00830   if (p != NULL) {
00831     p->tcnt -= pt->tcnt;
00832   }
00833   if (prev != NULL) {
00834     prev->next = pt;
00835   } else {
00836     os_timer_head = pt;
00837   }
00838 }
00839 
00840 // Remove Timer from the list
00841 static int rt_timer_remove (os_timer_cb *pt) {
00842   os_timer_cb *p, *prev;
00843 
00844   prev = NULL;
00845   p = os_timer_head;
00846   while (p != NULL) {
00847     if (p == pt) break;
00848     prev = p;
00849     p = p->next;
00850   }
00851   if (p == NULL) return -1;
00852   if (prev != NULL) {
00853     prev->next = pt->next;
00854   } else {
00855     os_timer_head = pt->next;
00856   }
00857   if (pt->next != NULL) {
00858     pt->next->tcnt += pt->tcnt;
00859   }
00860 
00861   return 0;
00862 }
00863 
00864 
00865 // Timer Service Calls declarations
00866 SVC_3_1(svcTimerCreate,           osTimerId,  osTimerDef_t *, os_timer_type, void *, RET_pointer)
00867 SVC_2_1(svcTimerStart,            osStatus,   osTimerId,      uint32_t,              RET_osStatus)
00868 SVC_1_1(svcTimerStop,             osStatus,   osTimerId,                             RET_osStatus)
00869 SVC_1_1(svcTimerDelete,           osStatus,   osTimerId,                             RET_osStatus)
00870 SVC_1_2(svcTimerCall,   os_InRegs osCallback, osTimerId,                             RET_osCallback)
00871 
00872 // Timer Management Service Calls
00873 
00874 /// Create timer
00875 osTimerId svcTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) {
00876   os_timer_cb *pt;
00877 
00878   if ((timer_def == NULL) || (timer_def->ptimer == NULL)) {
00879     sysThreadError(osErrorParameter);
00880     return NULL;
00881   }
00882 
00883   pt = timer_def->timer;
00884   if (pt == NULL) {
00885     sysThreadError(osErrorParameter);
00886     return NULL;
00887   }
00888 
00889   if ((type != osTimerOnce) && (type != osTimerPeriodic)) {
00890     sysThreadError(osErrorValue);
00891     return NULL;
00892   }
00893 
00894   if (osThreadId_osTimerThread == NULL) {
00895     sysThreadError(osErrorResource);
00896     return NULL;
00897   }
00898 
00899   if (pt->state != osTimerInvalid){
00900     sysThreadError(osErrorResource);
00901     return NULL;
00902   }
00903 
00904   pt->state = osTimerStopped;
00905   pt->type  =  (uint8_t)type;
00906   pt->arg   = argument;
00907   pt->timer = timer_def;
00908 
00909   return (osTimerId)pt;
00910 }
00911 
00912 /// Start or restart timer
00913 osStatus svcTimerStart (osTimerId timer_id, uint32_t millisec) {
00914   os_timer_cb *pt;
00915   uint32_t     tcnt;
00916 
00917   pt = rt_id2obj(timer_id);
00918   if (pt == NULL) return osErrorParameter;
00919 
00920   tcnt = rt_ms2tick(millisec);
00921   if (tcnt == 0) return osErrorValue;
00922 
00923   switch (pt->state) {
00924     case osTimerRunning:
00925       if (rt_timer_remove(pt) != 0) {
00926         return osErrorResource;
00927       }
00928       break;
00929     case osTimerStopped:
00930       pt->state = osTimerRunning;
00931       pt->icnt  = (uint16_t)tcnt;
00932       break;
00933     default:
00934       return osErrorResource;
00935   }
00936   
00937   rt_timer_insert(pt, tcnt);
00938 
00939   return osOK;
00940 }
00941 
00942 /// Stop timer
00943 osStatus svcTimerStop (osTimerId timer_id) {
00944   os_timer_cb *pt;
00945 
00946   pt = rt_id2obj(timer_id);
00947   if (pt == NULL) return osErrorParameter;
00948 
00949   if (pt->state != osTimerRunning) return osErrorResource;
00950 
00951   pt->state = osTimerStopped;
00952 
00953   if (rt_timer_remove(pt) != 0) {
00954     return osErrorResource;
00955   }
00956 
00957   return osOK;
00958 }
00959 
00960 /// Delete timer
00961 osStatus svcTimerDelete (osTimerId timer_id) {
00962   os_timer_cb *pt;
00963 
00964   pt = rt_id2obj(timer_id);
00965   if (pt == NULL) return osErrorParameter;
00966 
00967   switch (pt->state) {
00968     case osTimerRunning:
00969       rt_timer_remove(pt);
00970       break;
00971     case osTimerStopped:
00972       break;
00973     default:
00974       return osErrorResource;
00975   }
00976 
00977   pt->state = osTimerInvalid;
00978 
00979   return osOK;
00980 }
00981 
00982 /// Get timer callback parameters
00983 os_InRegs osCallback_type svcTimerCall (osTimerId timer_id) {
00984   os_timer_cb *pt;
00985   osCallback   ret;
00986 
00987   pt = rt_id2obj(timer_id);
00988   if (pt == NULL) {
00989     ret.fp  = NULL;
00990     ret.arg = NULL;
00991     return osCallback_ret;
00992   }
00993 
00994   ret.fp  = (void *)pt->timer->ptimer;
00995   ret.arg = pt->arg;
00996 
00997   return osCallback_ret;
00998 }
00999 
01000 static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec);
01001 
01002 /// Timer Tick (called each SysTick)
01003 void sysTimerTick (void) {
01004   os_timer_cb *pt, *p;
01005 
01006   p = os_timer_head;
01007   if (p == NULL) return;
01008 
01009   p->tcnt--;
01010   while ((p != NULL) && (p->tcnt == 0)) {
01011     pt = p;
01012     p = p->next;
01013     os_timer_head = p;
01014     isrMessagePut(osMessageQId_osTimerMessageQ, (uint32_t)pt, 0);
01015     if (pt->type == osTimerPeriodic) {
01016       rt_timer_insert(pt, pt->icnt);
01017     } else {
01018       pt->state = osTimerStopped;
01019     }
01020   }
01021 }
01022 
01023 
01024 // Timer Management Public API
01025 
01026 /// Create timer
01027 osTimerId osTimerCreate (osTimerDef_t *timer_def, os_timer_type type, void *argument) {
01028   if (__get_IPSR() != 0) return NULL;           // Not allowed in ISR
01029   if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
01030     // Privileged and not running
01031     return   svcTimerCreate(timer_def, type, argument);
01032   } else {
01033     return __svcTimerCreate(timer_def, type, argument);
01034   }
01035 }
01036 
01037 /// Start or restart timer
01038 osStatus osTimerStart (osTimerId timer_id, uint32_t millisec) {
01039   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01040   return __svcTimerStart(timer_id, millisec);
01041 }
01042 
01043 /// Stop timer
01044 osStatus osTimerStop (osTimerId timer_id) {
01045   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01046   return __svcTimerStop(timer_id);
01047 }
01048 
01049 /// Delete timer
01050 osStatus osTimerDelete (osTimerId timer_id) {
01051   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01052   return __svcTimerDelete(timer_id);
01053 }
01054 
01055 /// INTERNAL - Not Public
01056 /// Get timer callback parameters (used by OS Timer Thread)
01057 os_InRegs osCallback osTimerCall (osTimerId timer_id) { 
01058   return __svcTimerCall(timer_id); 
01059 }
01060 
01061 
01062 // Timer Thread
01063 __NO_RETURN void osTimerThread (void const *argument) {
01064   osCallback cb;
01065   osEvent    evt;
01066 
01067   for (;;) {
01068     evt = osMessageGet(osMessageQId_osTimerMessageQ, osWaitForever);
01069     if (evt.status == osEventMessage) {
01070       cb = osTimerCall(evt.value.p);
01071       if (cb.fp != NULL) {
01072         (*(os_ptimer)cb.fp)(cb.arg);
01073       }
01074     }
01075   }
01076 }
01077 
01078 
01079 // ==== Signal Management ====
01080 
01081 // Signal Service Calls declarations
01082 SVC_2_1(svcSignalSet,             int32_t, osThreadId, int32_t,  RET_int32_t)
01083 SVC_2_1(svcSignalClear,           int32_t, osThreadId, int32_t,  RET_int32_t)
01084 SVC_1_1(svcSignalGet,             int32_t, osThreadId,           RET_int32_t)
01085 SVC_2_3(svcSignalWait,  os_InRegs osEvent, int32_t,    uint32_t, RET_osEvent)
01086 
01087 // Signal Service Calls
01088 
01089 /// Set the specified Signal Flags of an active thread
01090 int32_t svcSignalSet (osThreadId thread_id, int32_t signals) {
01091   P_TCB   ptcb;
01092   int32_t sig;
01093 
01094   ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
01095   if (ptcb == NULL) return 0x80000000;
01096 
01097   if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
01098 
01099   sig = ptcb->events;                           // Previous signal flags
01100 
01101   rt_evt_set(signals, ptcb->task_id);           // Set event flags
01102 
01103   return sig;
01104 }
01105 
01106 /// Clear the specified Signal Flags of an active thread
01107 int32_t svcSignalClear (osThreadId thread_id, int32_t signals) {
01108   P_TCB   ptcb;
01109   int32_t sig;
01110 
01111   ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
01112   if (ptcb == NULL) return 0x80000000;
01113 
01114   if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
01115 
01116   sig = ptcb->events;                           // Previous signal flags
01117 
01118   rt_evt_clr(signals, ptcb->task_id);           // Clear event flags
01119 
01120   return sig;
01121 }
01122 
01123 /// Get Signal Flags status of an active thread
01124 int32_t svcSignalGet (osThreadId thread_id) {
01125   P_TCB ptcb;
01126 
01127   ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
01128   if (ptcb == NULL) return 0x80000000;
01129 
01130   return ptcb->events;                          // Return event flags
01131 }
01132 
01133 /// Wait for one or more Signal Flags to become signaled for the current RUNNING thread
01134 os_InRegs osEvent_type svcSignalWait (int32_t signals, uint32_t millisec) {
01135   OS_RESULT res;
01136   osEvent   ret;
01137 
01138   if (signals & (0xFFFFFFFF << osFeature_Signals)) {
01139     ret.status = osErrorValue;
01140     return osEvent_ret_status;
01141   }
01142 
01143   if (signals != 0) {                           // Wait for all specified signals
01144     res = rt_evt_wait(signals, rt_ms2tick(millisec), __TRUE);
01145   } else {                                      // Wait for any signal
01146     res = rt_evt_wait(0xFFFF,  rt_ms2tick(millisec), __FALSE);
01147   }
01148 
01149   if (res == OS_R_EVT) {
01150     ret.status = osEventSignal;
01151     ret.value.signals = signals ? signals : os_tsk.run->waits;
01152   } else {
01153     ret.status = millisec ? osEventTimeout : osOK;
01154     ret.value.signals = 0;
01155   }
01156 
01157   return osEvent_ret_value;
01158 }
01159 
01160 
01161 // Signal ISR Calls
01162 
01163 /// Set the specified Signal Flags of an active thread
01164 static __INLINE int32_t isrSignalSet (osThreadId thread_id, int32_t signals) {
01165   P_TCB   ptcb;
01166   int32_t sig;
01167 
01168   ptcb = rt_tid2ptcb(thread_id);                // Get TCB pointer
01169   if (ptcb == NULL) return 0x80000000;
01170 
01171   if (signals & (0xFFFFFFFF << osFeature_Signals)) return 0x80000000;
01172 
01173   sig = ptcb->events;                           // Previous signal flags
01174 
01175   isr_evt_set(signals, ptcb->task_id);          // Set event flags
01176 
01177   return sig;
01178 }
01179 
01180 
01181 // Signal Public API
01182 
01183 /// Set the specified Signal Flags of an active thread
01184 int32_t osSignalSet (osThreadId thread_id, int32_t signals) {
01185   if (__get_IPSR() != 0) {                      // in ISR
01186     return   isrSignalSet(thread_id, signals); 
01187   } else {                                      // in Thread
01188     return __svcSignalSet(thread_id, signals);
01189   }
01190 }
01191 
01192 /// Clear the specified Signal Flags of an active thread
01193 int32_t osSignalClear (osThreadId thread_id, int32_t signals) {
01194   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01195   return __svcSignalClear(thread_id, signals);
01196 }
01197 
01198 /// Get Signal Flags status of an active thread
01199 int32_t osSignalGet (osThreadId thread_id) {
01200   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01201   return __svcSignalGet(thread_id);
01202 }
01203 
01204 /// Wait for one or more Signal Flags to become signaled for the current RUNNING thread
01205 os_InRegs osEvent osSignalWait (int32_t signals, uint32_t millisec) {
01206   osEvent ret;
01207 
01208   if (__get_IPSR() != 0) {                      // Not allowed in ISR
01209     ret.status = osErrorISR;
01210     return ret;
01211   }
01212   return __svcSignalWait(signals, millisec);
01213 }
01214 
01215 
01216 // ==== Mutex Management ====
01217 
01218 // Mutex Service Calls declarations
01219 SVC_1_1(svcMutexCreate,  osMutexId, osMutexDef_t *,           RET_pointer)
01220 SVC_2_1(svcMutexWait,    osStatus,  osMutexId,      uint32_t, RET_osStatus)
01221 SVC_1_1(svcMutexRelease, osStatus,  osMutexId,                RET_osStatus)
01222 SVC_1_1(svcMutexDelete,  osStatus,  osMutexId,                RET_osStatus)
01223 
01224 // Mutex Service Calls
01225 
01226 /// Create and Initialize a Mutex object
01227 osMutexId svcMutexCreate (osMutexDef_t *mutex_def) {
01228   OS_ID mut;
01229 
01230   if (mutex_def == NULL) {
01231     sysThreadError(osErrorParameter);
01232     return NULL;
01233   }
01234 
01235   mut = mutex_def->mutex;
01236   if (mut == NULL) {
01237     sysThreadError(osErrorParameter);
01238     return NULL;
01239   }
01240 
01241   if (((P_MUCB)mut)->cb_type != 0) {
01242     sysThreadError(osErrorParameter);
01243     return NULL;
01244   }
01245 
01246   rt_mut_init(mut);                             // Initialize Mutex
01247 
01248   return mut;
01249 }
01250 
01251 /// Wait until a Mutex becomes available
01252 osStatus svcMutexWait (osMutexId mutex_id, uint32_t millisec) {
01253   OS_ID     mut;
01254   OS_RESULT res;
01255 
01256   mut = rt_id2obj(mutex_id);
01257   if (mut == NULL) return osErrorParameter;
01258 
01259   if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
01260 
01261   res = rt_mut_wait(mut, rt_ms2tick(millisec)); // Wait for Mutex
01262 
01263   if (res == OS_R_TMO) {
01264     return (millisec ? osErrorTimeoutResource : osErrorResource);
01265   }
01266 
01267   return osOK;
01268 }
01269 
01270 /// Release a Mutex that was obtained with osMutexWait
01271 osStatus svcMutexRelease (osMutexId mutex_id) {
01272   OS_ID     mut;
01273   OS_RESULT res;
01274 
01275   mut = rt_id2obj(mutex_id);
01276   if (mut == NULL) return osErrorParameter;
01277 
01278   if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
01279 
01280   res = rt_mut_release(mut);                    // Release Mutex
01281 
01282   if (res == OS_R_NOK) return osErrorResource;  // Thread not owner or Zero Counter
01283 
01284   return osOK;
01285 }
01286 
01287 /// Delete a Mutex that was created by osMutexCreate
01288 osStatus svcMutexDelete (osMutexId mutex_id) {
01289   OS_ID mut;
01290 
01291   mut = rt_id2obj(mutex_id);
01292   if (mut == NULL) return osErrorParameter;
01293 
01294   if (((P_MUCB)mut)->cb_type != MUCB) return osErrorParameter;
01295 
01296   rt_mut_delete(mut);                           // Release Mutex
01297 
01298   return osOK;
01299 }
01300 
01301 
01302 // Mutex Public API
01303 
01304 /// Create and Initialize a Mutex object
01305 osMutexId osMutexCreate (osMutexDef_t *mutex_def) {
01306   if (__get_IPSR() != 0) return NULL;           // Not allowed in ISR
01307   if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
01308     // Privileged and not running
01309     return    svcMutexCreate(mutex_def);
01310   } else {
01311     return __svcMutexCreate(mutex_def);
01312   }
01313 }
01314 
01315 /// Wait until a Mutex becomes available
01316 osStatus osMutexWait (osMutexId mutex_id, uint32_t millisec) {
01317   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01318   return __svcMutexWait(mutex_id, millisec);
01319 }
01320 
01321 /// Release a Mutex that was obtained with osMutexWait
01322 osStatus osMutexRelease (osMutexId mutex_id) {
01323   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01324   return __svcMutexRelease(mutex_id);
01325 }
01326 
01327 /// Delete a Mutex that was created by osMutexCreate
01328 osStatus osMutexDelete (osMutexId mutex_id) {
01329   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01330   return __svcMutexDelete(mutex_id);
01331 }
01332 
01333 
01334 // ==== Semaphore Management ====
01335 
01336 // Semaphore Service Calls declarations
01337 SVC_2_1(svcSemaphoreCreate,  osSemaphoreId, const osSemaphoreDef_t *,  int32_t, RET_pointer)
01338 SVC_2_1(svcSemaphoreWait,    int32_t,       osSemaphoreId,      uint32_t, RET_int32_t)
01339 SVC_1_1(svcSemaphoreRelease, osStatus,      osSemaphoreId,                RET_osStatus)
01340 SVC_1_1(svcSemaphoreDelete,  osStatus,            osSemaphoreId,                RET_osStatus)
01341 
01342 // Semaphore Service Calls
01343 
01344 /// Create and Initialize a Semaphore object
01345 osSemaphoreId svcSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t count) {
01346   OS_ID sem;
01347 
01348   if (semaphore_def == NULL) {
01349     sysThreadError(osErrorParameter);
01350     return NULL;
01351   }
01352 
01353   sem = semaphore_def->semaphore;
01354   if (sem == NULL) {
01355     sysThreadError(osErrorParameter);
01356     return NULL;
01357   }
01358 
01359   if (((P_SCB)sem)->cb_type != 0) {
01360     sysThreadError(osErrorParameter);
01361     return NULL;
01362   }
01363 
01364   if (count > osFeature_Semaphore) {
01365     sysThreadError(osErrorValue);
01366     return NULL;
01367   }
01368 
01369   rt_sem_init(sem, count);                      // Initialize Semaphore
01370   
01371   return sem;
01372 }
01373 
01374 /// Wait until a Semaphore becomes available
01375 int32_t svcSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
01376   OS_ID     sem;
01377   OS_RESULT res;
01378 
01379   sem = rt_id2obj(semaphore_id);
01380   if (sem == NULL) return -1;
01381 
01382   if (((P_SCB)sem)->cb_type != SCB) return -1;
01383 
01384   res = rt_sem_wait(sem, rt_ms2tick(millisec)); // Wait for Semaphore
01385 
01386   if (res == OS_R_TMO) return 0;                // Timeout
01387 
01388   return (((P_SCB)sem)->tokens + 1);
01389 }
01390 
01391 /// Release a Semaphore
01392 osStatus svcSemaphoreRelease (osSemaphoreId semaphore_id) {
01393   OS_ID sem;
01394 
01395   sem = rt_id2obj(semaphore_id);
01396   if (sem == NULL) return osErrorParameter;
01397 
01398   if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
01399 
01400   if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource;
01401   
01402   rt_sem_send(sem);                             // Release Semaphore
01403 
01404   return osOK;
01405 }
01406 
01407 /// Delete a Semaphore that was created by osSemaphoreCreate
01408 osStatus svcSemaphoreDelete (osSemaphoreId semaphore_id) {
01409   OS_ID sem;
01410 
01411   sem = rt_id2obj(semaphore_id);
01412   if (sem == NULL) return osErrorParameter;
01413 
01414   if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
01415 
01416   rt_sem_delete(sem);                           // Delete Semaphore
01417 
01418   return osOK;
01419 }
01420 
01421 
01422 // Semaphore ISR Calls
01423 
01424 /// Release a Semaphore
01425 static __INLINE osStatus isrSemaphoreRelease (osSemaphoreId semaphore_id) {
01426   OS_ID sem;
01427 
01428   sem = rt_id2obj(semaphore_id);
01429   if (sem == NULL) return osErrorParameter;
01430 
01431   if (((P_SCB)sem)->cb_type != SCB) return osErrorParameter;
01432 
01433   if (((P_SCB)sem)->tokens == osFeature_Semaphore) return osErrorResource;
01434 
01435   isr_sem_send(sem);                            // Release Semaphore
01436 
01437   return osOK;
01438 }
01439 
01440 
01441 // Semaphore Public API
01442 
01443 /// Create and Initialize a Semaphore object
01444 osSemaphoreId osSemaphoreCreate (osSemaphoreDef_t *semaphore_def, int32_t count) {
01445   if (__get_IPSR() != 0) return NULL;           // Not allowed in ISR
01446   if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
01447     // Privileged and not running
01448     return   svcSemaphoreCreate(semaphore_def, count);
01449   } else {
01450     return __svcSemaphoreCreate(semaphore_def, count);
01451   }
01452 }
01453 
01454 /// Wait until a Semaphore becomes available
01455 int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) {
01456   if (__get_IPSR() != 0) return -1;             // Not allowed in ISR
01457   return __svcSemaphoreWait(semaphore_id, millisec);
01458 }
01459 
01460 /// Release a Semaphore
01461 osStatus osSemaphoreRelease (osSemaphoreId semaphore_id) {
01462   if (__get_IPSR() != 0) {                      // in ISR
01463     return   isrSemaphoreRelease(semaphore_id);
01464   } else {                                      // in Thread
01465     return __svcSemaphoreRelease(semaphore_id);
01466   }
01467 }
01468 
01469 /// Delete a Semaphore that was created by osSemaphoreCreate
01470 osStatus osSemaphoreDelete (osSemaphoreId semaphore_id) {
01471   if (__get_IPSR() != 0) return osErrorISR;     // Not allowed in ISR
01472   return __svcSemaphoreDelete(semaphore_id);
01473 }
01474 
01475 
01476 // ==== Memory Management Functions ====
01477 
01478 // Memory Management Helper Functions
01479 
01480 // Clear Memory Box (Zero init)
01481 static void rt_clr_box (void *box_mem, void *box) {
01482   uint32_t *p, n;
01483 
01484   if (box) {
01485     p = box;
01486     for (n = ((P_BM)box_mem)->blk_size; n; n -= 4) {
01487       *p++ = 0;
01488     }
01489   }
01490 }
01491 
01492 // Memory Management Service Calls declarations
01493 SVC_1_1(svcPoolCreate, osPoolId, const osPoolDef_t *,           RET_pointer)
01494 SVC_2_1(sysPoolAlloc,  void *,   osPoolId,      uint32_t, RET_pointer)
01495 SVC_2_1(sysPoolFree,   osStatus, osPoolId,      void *,   RET_osStatus)
01496 
01497 // Memory Management Service & ISR Calls
01498 
01499 /// Create and Initialize memory pool
01500 osPoolId svcPoolCreate (const osPoolDef_t *pool_def) {
01501   uint32_t blk_sz;
01502 
01503   if ((pool_def == NULL) ||
01504       (pool_def->pool_sz == 0) ||
01505       (pool_def->item_sz == 0) ||
01506       (pool_def->pool == NULL)) {
01507     sysThreadError(osErrorParameter);
01508     return NULL;
01509   }
01510 
01511   blk_sz = (pool_def->item_sz + 3) & ~3;
01512 
01513   _init_box(pool_def->pool, sizeof(struct OS_BM) + pool_def->pool_sz * blk_sz, blk_sz);
01514 
01515   return pool_def->pool;
01516 }
01517 
01518 /// Allocate a memory block from a memory pool
01519 void *sysPoolAlloc (osPoolId pool_id, uint32_t clr) {
01520   void *ptr;
01521 
01522   if (pool_id == NULL) return NULL;
01523 
01524   ptr = rt_alloc_box(pool_id);
01525   if (clr) {
01526     rt_clr_box(pool_id, ptr);
01527   }
01528 
01529   return ptr;
01530 }
01531 
01532 /// Return an allocated memory block back to a specific memory pool
01533 osStatus sysPoolFree (osPoolId pool_id, void *block) {
01534   int32_t res;
01535     
01536   if (pool_id == NULL) return osErrorParameter;
01537 
01538   res = rt_free_box(pool_id, block);
01539   if (res != 0) return osErrorValue;
01540 
01541   return osOK;
01542 }
01543 
01544 
01545 // Memory Management Public API
01546 
01547 /// Create and Initialize memory pool
01548 osPoolId osPoolCreate (osPoolDef_t *pool_def) {
01549   if (__get_IPSR() != 0) return NULL;           // Not allowed in ISR
01550   if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
01551     // Privileged and not running
01552     return   svcPoolCreate(pool_def);
01553   } else {
01554     return __svcPoolCreate(pool_def);
01555   }
01556 }
01557 
01558 /// Allocate a memory block from a memory pool
01559 void *osPoolAlloc (osPoolId pool_id) {
01560   if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) {    // in ISR or Privileged
01561     return   sysPoolAlloc(pool_id, 0);
01562   } else {                                      // in Thread
01563     return __sysPoolAlloc(pool_id, 0);
01564   }
01565 }
01566 
01567 /// Allocate a memory block from a memory pool and set memory block to zero
01568 void *osPoolCAlloc (osPoolId pool_id) {
01569   if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) {    // in ISR or Privileged
01570     return   sysPoolAlloc(pool_id, 1);
01571   } else {                                      // in Thread
01572     return __sysPoolAlloc(pool_id, 1);
01573   }
01574 }
01575 
01576 /// Return an allocated memory block back to a specific memory pool
01577 osStatus osPoolFree (osPoolId pool_id, void *block) {
01578   if ((__get_IPSR() != 0) || ((__get_CONTROL() & 1) == 0)) {    // in ISR or Privileged
01579     return   sysPoolFree(pool_id, block);
01580   } else {                                      // in Thread
01581     return __sysPoolFree(pool_id, block);
01582   }
01583 }
01584 
01585 
01586 // ==== Message Queue Management Functions ====
01587 
01588 // Message Queue Management Service Calls declarations
01589 SVC_2_1(svcMessageCreate,        osMessageQId,    osMessageQDef_t *, osThreadId,           RET_pointer)
01590 SVC_3_1(svcMessagePut,              osStatus,     osMessageQId,      uint32_t,   uint32_t, RET_osStatus)
01591 SVC_2_3(svcMessageGet,    os_InRegs osEvent,      osMessageQId,      uint32_t,             RET_osEvent)
01592 
01593 // Message Queue Service Calls
01594 
01595 /// Create and Initialize Message Queue
01596 osMessageQId svcMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) {
01597 
01598   if ((queue_def == NULL) ||
01599       (queue_def->queue_sz == 0) ||
01600       (queue_def->pool == NULL)) {
01601     sysThreadError(osErrorParameter);
01602     return NULL;
01603   }
01604   
01605   if (((P_MCB)queue_def->pool)->cb_type != 0) {
01606     sysThreadError(osErrorParameter);
01607     return NULL;
01608   }
01609 
01610   rt_mbx_init(queue_def->pool, 4*(queue_def->queue_sz + 4));
01611 
01612   return queue_def->pool;
01613 }
01614 
01615 /// Put a Message to a Queue
01616 osStatus svcMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
01617   OS_RESULT res;
01618 
01619   if (queue_id == NULL) return osErrorParameter;
01620 
01621   if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter;
01622 
01623   res = rt_mbx_send(queue_id, (void *)info, rt_ms2tick(millisec));
01624 
01625   if (res == OS_R_TMO) {
01626     return (millisec ? osErrorTimeoutResource : osErrorResource);
01627   }
01628 
01629   return osOK;
01630 }
01631 
01632 /// Get a Message or Wait for a Message from a Queue
01633 os_InRegs osEvent_type svcMessageGet (osMessageQId queue_id, uint32_t millisec) {
01634   OS_RESULT res;
01635   osEvent   ret;
01636 
01637   if (queue_id == NULL) {
01638     ret.status = osErrorParameter;
01639     return osEvent_ret_status;
01640   }
01641 
01642   if (((P_MCB)queue_id)->cb_type != MCB) {
01643     ret.status = osErrorParameter;
01644     return osEvent_ret_status;
01645   }
01646 
01647   res = rt_mbx_wait(queue_id, &ret.value.p, rt_ms2tick(millisec));
01648   
01649   if (res == OS_R_TMO) {
01650     ret.status = millisec ? osEventTimeout : osOK;
01651     return osEvent_ret_value;
01652   }
01653 
01654   ret.status = osEventMessage;
01655 
01656   return osEvent_ret_value;
01657 }
01658 
01659 
01660 // Message Queue ISR Calls
01661 
01662 /// Put a Message to a Queue
01663 static __INLINE osStatus isrMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
01664 
01665   if ((queue_id == NULL) || (millisec != 0)) {
01666     return osErrorParameter;
01667   }
01668 
01669   if (((P_MCB)queue_id)->cb_type != MCB) return osErrorParameter;
01670 
01671   if (rt_mbx_check(queue_id) == 0) {            // Check if Queue is full
01672     return osErrorResource;
01673   }
01674 
01675   isr_mbx_send(queue_id, (void *)info);
01676 
01677   return osOK;
01678 }
01679 
01680 /// Get a Message or Wait for a Message from a Queue
01681 static __INLINE os_InRegs osEvent isrMessageGet (osMessageQId queue_id, uint32_t millisec) {
01682   OS_RESULT res;
01683   osEvent   ret;
01684 
01685   if ((queue_id == NULL) || (millisec != 0)) {
01686     ret.status = osErrorParameter;
01687     return ret;
01688   }
01689 
01690   if (((P_MCB)queue_id)->cb_type != MCB) {
01691     ret.status = osErrorParameter;
01692     return ret;
01693   }
01694 
01695   res = isr_mbx_receive(queue_id, &ret.value.p);
01696   
01697   if (res != OS_R_MBX) {
01698     ret.status = osOK;
01699     return ret;
01700   }
01701 
01702   ret.status = osEventMessage; 
01703 
01704   return ret;
01705 }
01706 
01707 
01708 // Message Queue Management Public API
01709 
01710 /// Create and Initialize Message Queue
01711 osMessageQId osMessageCreate (osMessageQDef_t *queue_def, osThreadId thread_id) {
01712   if (__get_IPSR() != 0) return NULL;           // Not allowed in ISR
01713   if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
01714     // Privileged and not running
01715     return   svcMessageCreate(queue_def, thread_id);
01716   } else {
01717     return __svcMessageCreate(queue_def, thread_id);
01718   }
01719 }
01720 
01721 /// Put a Message to a Queue
01722 osStatus osMessagePut (osMessageQId queue_id, uint32_t info, uint32_t millisec) {
01723   if (__get_IPSR() != 0) {                      // in ISR
01724     return   isrMessagePut(queue_id, info, millisec);
01725   } else {                                      // in Thread
01726     return __svcMessagePut(queue_id, info, millisec);
01727   }
01728 }
01729 
01730 /// Get a Message or Wait for a Message from a Queue
01731 os_InRegs osEvent osMessageGet (osMessageQId queue_id, uint32_t millisec) {
01732   if (__get_IPSR() != 0) {                      // in ISR
01733     return   isrMessageGet(queue_id, millisec);
01734   } else {                                      // in Thread
01735     return __svcMessageGet(queue_id, millisec);
01736   }
01737 }
01738 
01739 
01740 // ==== Mail Queue Management Functions ====
01741 
01742 // Mail Queue Management Service Calls declarations
01743 SVC_2_1(svcMailCreate, osMailQId, osMailQDef_t *, osThreadId,                   RET_pointer)
01744 SVC_4_1(sysMailAlloc,  void *,    osMailQId,      uint32_t, uint32_t, uint32_t, RET_pointer)
01745 SVC_3_1(sysMailFree,   osStatus,  osMailQId,      void *,   uint32_t,           RET_osStatus)
01746 
01747 // Mail Queue Management Service & ISR Calls
01748 
01749 /// Create and Initialize mail queue
01750 osMailQId svcMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) {
01751   uint32_t blk_sz;
01752   P_MCB    pmcb;
01753   void    *pool;
01754 
01755   if ((queue_def == NULL) ||
01756       (queue_def->queue_sz == 0) ||
01757       (queue_def->item_sz  == 0) ||
01758       (queue_def->pool == NULL)) {
01759     sysThreadError(osErrorParameter);
01760     return NULL;
01761   }
01762 
01763   pmcb = *(((void **)queue_def->pool) + 0);
01764   pool = *(((void **)queue_def->pool) + 1);
01765 
01766   if ((pool == NULL) || (pmcb == NULL) || (pmcb->cb_type != 0)) {
01767     sysThreadError(osErrorParameter);
01768     return NULL;
01769   }
01770 
01771   blk_sz = (queue_def->item_sz + 3) & ~3;
01772 
01773   _init_box(pool, sizeof(struct OS_BM) + queue_def->queue_sz * blk_sz, blk_sz);
01774 
01775   rt_mbx_init(pmcb, 4*(queue_def->queue_sz + 4));
01776 
01777 
01778   return queue_def->pool;
01779 }
01780 
01781 /// Allocate a memory block from a mail
01782 void *sysMailAlloc (osMailQId queue_id, uint32_t millisec, uint32_t isr, uint32_t clr) {
01783   P_MCB pmcb;
01784   void *pool;
01785   void *mem;
01786 
01787   if (queue_id == NULL) return NULL;
01788 
01789   pmcb = *(((void **)queue_id) + 0);
01790   pool = *(((void **)queue_id) + 1);
01791 
01792   if ((pool == NULL) || (pmcb == NULL)) return NULL;
01793 
01794   if (isr && (millisec != 0)) return NULL;
01795 
01796   mem = rt_alloc_box(pool);
01797   if (clr) {
01798     rt_clr_box(pool, mem);
01799   }
01800 
01801   if ((mem == NULL) && (millisec != 0)) {
01802     // Put Task to sleep when Memory not available
01803     if (pmcb->p_lnk != NULL) {
01804       rt_put_prio((P_XCB)pmcb, os_tsk.run);
01805     } else {
01806       pmcb->p_lnk = os_tsk.run;
01807       os_tsk.run->p_lnk = NULL;
01808       os_tsk.run->p_rlnk = (P_TCB)pmcb;
01809       // Task is waiting to allocate a message
01810       pmcb->state = 3;
01811     }
01812     rt_block(rt_ms2tick(millisec), WAIT_MBX);
01813   }
01814 
01815   return mem;  
01816 }
01817 
01818 /// Free a memory block from a mail
01819 osStatus sysMailFree (osMailQId queue_id, void *mail, uint32_t isr) {
01820   P_MCB   pmcb;
01821   P_TCB   ptcb;
01822   void   *pool;
01823   void   *mem;
01824   int32_t res;
01825 
01826   if (queue_id == NULL) return osErrorParameter;
01827 
01828   pmcb = *(((void **)queue_id) + 0);
01829   pool = *(((void **)queue_id) + 1);
01830 
01831   if ((pmcb == NULL) || (pool == NULL)) return osErrorParameter;
01832 
01833   res = rt_free_box(pool, mail);
01834 
01835   if (res != 0) return osErrorValue;
01836 
01837   if (pmcb->state == 3) {
01838     // Task is waiting to allocate a message
01839     if (isr) {
01840       rt_psq_enq (pmcb, (U32)pool);
01841       rt_psh_req ();
01842     } else {
01843       mem = rt_alloc_box(pool);
01844       if (mem != NULL) {
01845         ptcb = rt_get_first((P_XCB)pmcb);
01846         if (pmcb->p_lnk == NULL) {
01847           pmcb->state = 0;
01848         }
01849         rt_ret_val(ptcb, (U32)mem);
01850         rt_rmv_dly(ptcb);
01851         rt_dispatch(ptcb);
01852       }
01853     }
01854   }
01855 
01856   return osOK;
01857 }
01858 
01859 
01860 // Mail Queue Management Public API
01861 
01862 /// Create and Initialize mail queue
01863 osMailQId osMailCreate (osMailQDef_t *queue_def, osThreadId thread_id) {
01864   if (__get_IPSR() != 0) return NULL;           // Not allowed in ISR
01865   if (((__get_CONTROL() & 1) == 0) && (os_running == 0)) {
01866     // Privileged and not running
01867     return   svcMailCreate(queue_def, thread_id);
01868   } else {
01869     return __svcMailCreate(queue_def, thread_id);
01870   }
01871 }
01872 
01873 /// Allocate a memory block from a mail
01874 void *osMailAlloc (osMailQId queue_id, uint32_t millisec) {
01875   if (__get_IPSR() != 0) {                      // in ISR
01876     return   sysMailAlloc(queue_id, millisec, 1, 0);
01877   } else {                                      // in Thread
01878     return __sysMailAlloc(queue_id, millisec, 0, 0);
01879   }
01880 }
01881 
01882 /// Allocate a memory block from a mail and set memory block to zero
01883 void *osMailCAlloc (osMailQId queue_id, uint32_t millisec) {
01884   if (__get_IPSR() != 0) {                      // in ISR
01885     return   sysMailAlloc(queue_id, millisec, 1, 1);
01886   } else {                                      // in Thread
01887     return __sysMailAlloc(queue_id, millisec, 0, 1);
01888   }
01889 }
01890 
01891 /// Free a memory block from a mail
01892 osStatus osMailFree (osMailQId queue_id, void *mail) {
01893   if (__get_IPSR() != 0) {                      // in ISR
01894     return   sysMailFree(queue_id, mail, 1);
01895   } else {                                      // in Thread
01896     return __sysMailFree(queue_id, mail, 0);
01897   }
01898 }
01899 
01900 /// Put a mail to a queue
01901 osStatus osMailPut (osMailQId queue_id, void *mail) {
01902   if (queue_id == NULL) return osErrorParameter;
01903   if (mail == NULL)     return osErrorValue;
01904   return osMessagePut(*((void **)queue_id), (uint32_t)mail, 0);
01905 }
01906 
01907 /// Get a mail from a queue
01908 os_InRegs osEvent osMailGet (osMailQId queue_id, uint32_t millisec) {
01909   osEvent ret;
01910 
01911   if (queue_id == NULL) {
01912     ret.status = osErrorParameter;
01913     return ret;
01914   }
01915 
01916   ret = osMessageGet(*((void **)queue_id), millisec);
01917   if (ret.status == osEventMessage) ret.status = osEventMail;
01918 
01919   return ret;
01920 }