Lee Kai Xuan / mbed-os

Fork of mbed-os by erkin yucel

Committer:
elessair
Date:
Sun Oct 23 15:10:02 2016 +0000
Revision:
0:f269e3021894
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
elessair 0:f269e3021894 1
elessair 0:f269e3021894 2 /** \addtogroup rtos */
elessair 0:f269e3021894 3 /** @{*/
elessair 0:f269e3021894 4 /*----------------------------------------------------------------------------
elessair 0:f269e3021894 5 * CMSIS-RTOS - RTX
elessair 0:f269e3021894 6 *----------------------------------------------------------------------------
elessair 0:f269e3021894 7 * Name: RTX_CM_LIB.H
elessair 0:f269e3021894 8 * Purpose: RTX Kernel System Configuration
elessair 0:f269e3021894 9 * Rev.: V4.79
elessair 0:f269e3021894 10 *----------------------------------------------------------------------------
elessair 0:f269e3021894 11 *
elessair 0:f269e3021894 12 * Copyright (c) 1999-2009 KEIL, 2009-2015 ARM Germany GmbH
elessair 0:f269e3021894 13 * All rights reserved.
elessair 0:f269e3021894 14 * Redistribution and use in source and binary forms, with or without
elessair 0:f269e3021894 15 * modification, are permitted provided that the following conditions are met:
elessair 0:f269e3021894 16 * - Redistributions of source code must retain the above copyright
elessair 0:f269e3021894 17 * notice, this list of conditions and the following disclaimer.
elessair 0:f269e3021894 18 * - Redistributions in binary form must reproduce the above copyright
elessair 0:f269e3021894 19 * notice, this list of conditions and the following disclaimer in the
elessair 0:f269e3021894 20 * documentation and/or other materials provided with the distribution.
elessair 0:f269e3021894 21 * - Neither the name of ARM nor the names of its contributors may be used
elessair 0:f269e3021894 22 * to endorse or promote products derived from this software without
elessair 0:f269e3021894 23 * specific prior written permission.
elessair 0:f269e3021894 24 *
elessair 0:f269e3021894 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
elessair 0:f269e3021894 26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
elessair 0:f269e3021894 27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
elessair 0:f269e3021894 28 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
elessair 0:f269e3021894 29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
elessair 0:f269e3021894 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
elessair 0:f269e3021894 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
elessair 0:f269e3021894 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
elessair 0:f269e3021894 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
elessair 0:f269e3021894 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
elessair 0:f269e3021894 35 * POSSIBILITY OF SUCH DAMAGE.
elessair 0:f269e3021894 36 *---------------------------------------------------------------------------*/
elessair 0:f269e3021894 37 #include "mbed_error.h"
elessair 0:f269e3021894 38
elessair 0:f269e3021894 39 #if defined (__CC_ARM)
elessair 0:f269e3021894 40 #include <rt_misc.h>
elessair 0:f269e3021894 41 #pragma O3
elessair 0:f269e3021894 42 #define __USED __attribute__((used))
elessair 0:f269e3021894 43 #elif defined (__GNUC__)
elessair 0:f269e3021894 44 #pragma GCC optimize ("O3")
elessair 0:f269e3021894 45 #define __USED __attribute__((used))
elessair 0:f269e3021894 46 #elif defined (__ICCARM__)
elessair 0:f269e3021894 47 #define __USED __root
elessair 0:f269e3021894 48 #endif
elessair 0:f269e3021894 49
elessair 0:f269e3021894 50
elessair 0:f269e3021894 51 /*----------------------------------------------------------------------------
elessair 0:f269e3021894 52 * Definitions
elessair 0:f269e3021894 53 *---------------------------------------------------------------------------*/
elessair 0:f269e3021894 54
elessair 0:f269e3021894 55 #define _declare_box(pool,size,cnt) uint32_t pool[(((size)+3)/4)*(cnt) + 3]
elessair 0:f269e3021894 56 #define _declare_box8(pool,size,cnt) uint64_t pool[(((size)+7)/8)*(cnt) + 2]
elessair 0:f269e3021894 57
elessair 0:f269e3021894 58 #define OS_TCB_SIZE 64
elessair 0:f269e3021894 59 #define OS_TMR_SIZE 8
elessair 0:f269e3021894 60
elessair 0:f269e3021894 61 typedef void *OS_ID;
elessair 0:f269e3021894 62 typedef uint32_t OS_TID;
elessair 0:f269e3021894 63 typedef uint32_t OS_MUT[4];
elessair 0:f269e3021894 64 typedef uint32_t OS_RESULT;
elessair 0:f269e3021894 65
elessair 0:f269e3021894 66 #if defined (__CC_ARM) && !defined (__MICROLIB)
elessair 0:f269e3021894 67
elessair 0:f269e3021894 68 #define runtask_id() rt_tsk_self()
elessair 0:f269e3021894 69 #define mutex_init(m) rt_mut_init(m)
elessair 0:f269e3021894 70 #define mutex_wait(m) os_mut_wait(m,0xFFFFU)
elessair 0:f269e3021894 71 #define mutex_rel(m) os_mut_release(m)
elessair 0:f269e3021894 72
elessair 0:f269e3021894 73 extern uint8_t os_running;
elessair 0:f269e3021894 74 extern OS_TID rt_tsk_self (void);
elessair 0:f269e3021894 75 extern void rt_mut_init (OS_ID mutex);
elessair 0:f269e3021894 76 extern OS_RESULT rt_mut_release (OS_ID mutex);
elessair 0:f269e3021894 77 extern OS_RESULT rt_mut_wait (OS_ID mutex, uint16_t timeout);
elessair 0:f269e3021894 78
elessair 0:f269e3021894 79 #define os_mut_wait(mutex,timeout) _os_mut_wait((uint32_t)rt_mut_wait,mutex,timeout)
elessair 0:f269e3021894 80 #define os_mut_release(mutex) _os_mut_release((uint32_t)rt_mut_release,mutex)
elessair 0:f269e3021894 81
elessair 0:f269e3021894 82 OS_RESULT _os_mut_release (uint32_t p, OS_ID mutex) __svc_indirect(0);
elessair 0:f269e3021894 83 OS_RESULT _os_mut_wait (uint32_t p, OS_ID mutex, uint16_t timeout) __svc_indirect(0);
elessair 0:f269e3021894 84
elessair 0:f269e3021894 85 #endif
elessair 0:f269e3021894 86
elessair 0:f269e3021894 87
elessair 0:f269e3021894 88 /*----------------------------------------------------------------------------
elessair 0:f269e3021894 89 * Global Variables
elessair 0:f269e3021894 90 *---------------------------------------------------------------------------*/
elessair 0:f269e3021894 91
elessair 0:f269e3021894 92 #if (OS_TASKCNT == 0)
elessair 0:f269e3021894 93 #error "Invalid number of concurrent running threads!"
elessair 0:f269e3021894 94 #endif
elessair 0:f269e3021894 95
elessair 0:f269e3021894 96 #if (OS_PRIVCNT >= OS_TASKCNT)
elessair 0:f269e3021894 97 #error "Too many threads with user-provided stack size!"
elessair 0:f269e3021894 98 #endif
elessair 0:f269e3021894 99
elessair 0:f269e3021894 100 #if (OS_TIMERS != 0)
elessair 0:f269e3021894 101 #define OS_TASK_CNT (OS_TASKCNT + 1)
elessair 0:f269e3021894 102 #ifndef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 103 #define OS_PRIV_CNT (OS_PRIVCNT + 2)
elessair 0:f269e3021894 104 #define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE+OS_TIMERSTKSZ))
elessair 0:f269e3021894 105 #endif
elessair 0:f269e3021894 106 #else
elessair 0:f269e3021894 107 #define OS_TASK_CNT OS_TASKCNT
elessair 0:f269e3021894 108 #ifndef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 109 #define OS_PRIV_CNT (OS_PRIVCNT + 1)
elessair 0:f269e3021894 110 #define OS_STACK_SZ (4*(OS_PRIVSTKSIZE+OS_MAINSTKSIZE))
elessair 0:f269e3021894 111 #endif
elessair 0:f269e3021894 112 #endif
elessair 0:f269e3021894 113
elessair 0:f269e3021894 114 #ifndef OS_STKINIT
elessair 0:f269e3021894 115 #define OS_STKINIT 0
elessair 0:f269e3021894 116 #endif
elessair 0:f269e3021894 117
elessair 0:f269e3021894 118 uint16_t const os_maxtaskrun = OS_TASK_CNT;
elessair 0:f269e3021894 119 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 120 uint32_t const os_stackinfo = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_IDLESTKSIZE*4);
elessair 0:f269e3021894 121 #else
elessair 0:f269e3021894 122 uint32_t const os_stackinfo = (OS_STKINIT<<28) | (OS_STKCHECK<<24) | (OS_PRIV_CNT<<16) | (OS_STKSIZE*4);
elessair 0:f269e3021894 123 #endif
elessair 0:f269e3021894 124 uint32_t const os_rrobin = (OS_ROBIN << 16) | OS_ROBINTOUT;
elessair 0:f269e3021894 125 uint32_t const os_tickfreq = OS_CLOCK;
elessair 0:f269e3021894 126 uint16_t const os_tickus_i = OS_CLOCK/1000000;
elessair 0:f269e3021894 127 uint16_t const os_tickus_f = (((uint64_t)(OS_CLOCK-1000000*(OS_CLOCK/1000000)))<<16)/1000000;
elessair 0:f269e3021894 128 uint32_t const os_trv = OS_TRV;
elessair 0:f269e3021894 129 #if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED)
elessair 0:f269e3021894 130 uint8_t const os_flags = 0;
elessair 0:f269e3021894 131 #else /* defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) */
elessair 0:f269e3021894 132 uint8_t const os_flags = OS_RUNPRIV;
elessair 0:f269e3021894 133 #endif /* defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) */
elessair 0:f269e3021894 134
elessair 0:f269e3021894 135 /* Export following defines to uVision debugger. */
elessair 0:f269e3021894 136 __USED uint32_t const CMSIS_RTOS_API_Version = osCMSIS;
elessair 0:f269e3021894 137 __USED uint32_t const CMSIS_RTOS_RTX_Version = osCMSIS_RTX;
elessair 0:f269e3021894 138 __USED uint32_t const os_clockrate = OS_TICK;
elessair 0:f269e3021894 139 __USED uint32_t const os_timernum = 0U;
elessair 0:f269e3021894 140
elessair 0:f269e3021894 141 /* Memory pool for TCB allocation */
elessair 0:f269e3021894 142 _declare_box (mp_tcb, OS_TCB_SIZE, OS_TASK_CNT);
elessair 0:f269e3021894 143 uint16_t const mp_tcb_size = sizeof(mp_tcb);
elessair 0:f269e3021894 144
elessair 0:f269e3021894 145 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 146 /* Memory pool for os_idle_demon stack allocation. */
elessair 0:f269e3021894 147 _declare_box8 (mp_stk, OS_IDLESTKSIZE*4, 1);
elessair 0:f269e3021894 148 uint32_t const mp_stk_size = sizeof(mp_stk);
elessair 0:f269e3021894 149 #else
elessair 0:f269e3021894 150 /* Memory pool for System stack allocation (+os_idle_demon). */
elessair 0:f269e3021894 151 _declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASK_CNT-OS_PRIV_CNT+1);
elessair 0:f269e3021894 152 uint32_t const mp_stk_size = sizeof(mp_stk);
elessair 0:f269e3021894 153
elessair 0:f269e3021894 154 /* Memory pool for user specified stack allocation (+main, +timer) */
elessair 0:f269e3021894 155 uint64_t os_stack_mem[2+OS_PRIV_CNT+(OS_STACK_SZ/8)];
elessair 0:f269e3021894 156 uint32_t const os_stack_sz = sizeof(os_stack_mem);
elessair 0:f269e3021894 157 #endif
elessair 0:f269e3021894 158
elessair 0:f269e3021894 159 #ifndef OS_FIFOSZ
elessair 0:f269e3021894 160 #define OS_FIFOSZ 16
elessair 0:f269e3021894 161 #endif
elessair 0:f269e3021894 162
elessair 0:f269e3021894 163 /* Fifo Queue buffer for ISR requests.*/
elessair 0:f269e3021894 164 uint32_t os_fifo[OS_FIFOSZ*2+1];
elessair 0:f269e3021894 165 uint8_t const os_fifo_size = OS_FIFOSZ;
elessair 0:f269e3021894 166
elessair 0:f269e3021894 167 /* An array of Active task pointers. */
elessair 0:f269e3021894 168 void *os_active_TCB[OS_TASK_CNT];
elessair 0:f269e3021894 169
elessair 0:f269e3021894 170 /* User Timers Resources */
elessair 0:f269e3021894 171 #if (OS_TIMERS != 0)
elessair 0:f269e3021894 172 extern void osTimerThread (void const *argument);
elessair 0:f269e3021894 173 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 174 osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 4*OS_TIMERSTKSZ);
elessair 0:f269e3021894 175 #else
elessair 0:f269e3021894 176 osThreadDef(osTimerThread, (osPriority)(OS_TIMERPRIO-3), 1, 4*OS_TIMERSTKSZ);
elessair 0:f269e3021894 177 #endif
elessair 0:f269e3021894 178 osThreadId osThreadId_osTimerThread;
elessair 0:f269e3021894 179 osMessageQDef(osTimerMessageQ, OS_TIMERCBQS, void *);
elessair 0:f269e3021894 180 osMessageQId osMessageQId_osTimerMessageQ;
elessair 0:f269e3021894 181 #else
elessair 0:f269e3021894 182 osThreadDef_t os_thread_def_osTimerThread = { NULL };
elessair 0:f269e3021894 183 osThreadId osThreadId_osTimerThread;
elessair 0:f269e3021894 184 osMessageQDef(osTimerMessageQ, 0U, void *);
elessair 0:f269e3021894 185 osMessageQId osMessageQId_osTimerMessageQ;
elessair 0:f269e3021894 186 #endif
elessair 0:f269e3021894 187
elessair 0:f269e3021894 188 /* Legacy RTX User Timers not used */
elessair 0:f269e3021894 189 uint32_t os_tmr = 0U;
elessair 0:f269e3021894 190 uint32_t const *m_tmr = NULL;
elessair 0:f269e3021894 191 uint16_t const mp_tmr_size = 0U;
elessair 0:f269e3021894 192
elessair 0:f269e3021894 193 /* singleton mutex */
elessair 0:f269e3021894 194 osMutexId singleton_mutex_id;
elessair 0:f269e3021894 195 osMutexDef(singleton_mutex);
elessair 0:f269e3021894 196
elessair 0:f269e3021894 197 #if defined (__CC_ARM) && !defined (__MICROLIB)
elessair 0:f269e3021894 198 /* A memory space for arm standard library. */
elessair 0:f269e3021894 199 static uint32_t std_libspace[OS_TASK_CNT][96/4];
elessair 0:f269e3021894 200 static OS_MUT std_libmutex[OS_MUTEXCNT];
elessair 0:f269e3021894 201 static uint32_t nr_mutex;
elessair 0:f269e3021894 202 extern void *__libspace_start;
elessair 0:f269e3021894 203 #endif
elessair 0:f269e3021894 204
elessair 0:f269e3021894 205 #if defined (__ICCARM__)
elessair 0:f269e3021894 206 static osMutexId std_mutex_id_sys[_MAX_LOCK] = {0};
elessair 0:f269e3021894 207 static OS_MUT std_mutex_sys[_MAX_LOCK] = {0};
elessair 0:f269e3021894 208 #define _FOPEN_MAX 10
elessair 0:f269e3021894 209 static osMutexId std_mutex_id_file[_FOPEN_MAX] = {0};
elessair 0:f269e3021894 210 static OS_MUT std_mutex_file[_FOPEN_MAX] = {0};
elessair 0:f269e3021894 211 void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */
elessair 0:f269e3021894 212 {
elessair 0:f269e3021894 213 osMutexDef_t def;
elessair 0:f269e3021894 214 uint32_t index;
elessair 0:f269e3021894 215 for (index = 0; index < _MAX_LOCK; index++) {
elessair 0:f269e3021894 216 if (0 == std_mutex_id_sys[index]) {
elessair 0:f269e3021894 217 def.mutex = &std_mutex_sys[index];
elessair 0:f269e3021894 218 std_mutex_id_sys[index] = osMutexCreate(&def);
elessair 0:f269e3021894 219 *mutex = (__iar_Rmtx*)&std_mutex_id_sys[index];
elessair 0:f269e3021894 220 return;
elessair 0:f269e3021894 221 }
elessair 0:f269e3021894 222 }
elessair 0:f269e3021894 223 // This should never happen
elessair 0:f269e3021894 224 error("Not enough mutexes\n");
elessair 0:f269e3021894 225 }
elessair 0:f269e3021894 226
elessair 0:f269e3021894 227 void __iar_system_Mtxdst(__iar_Rmtx *mutex)/*Destroy a system lock */
elessair 0:f269e3021894 228 {
elessair 0:f269e3021894 229 osMutexDelete(*(osMutexId*)*mutex);
elessair 0:f269e3021894 230 *mutex = 0;
elessair 0:f269e3021894 231 }
elessair 0:f269e3021894 232
elessair 0:f269e3021894 233 void __iar_system_Mtxlock(__iar_Rmtx *mutex) /* Lock a system lock */
elessair 0:f269e3021894 234 {
elessair 0:f269e3021894 235 osMutexWait(*(osMutexId*)*mutex, osWaitForever);
elessair 0:f269e3021894 236 }
elessair 0:f269e3021894 237
elessair 0:f269e3021894 238 void __iar_system_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a system lock */
elessair 0:f269e3021894 239 {
elessair 0:f269e3021894 240 osMutexRelease(*(osMutexId*)*mutex);
elessair 0:f269e3021894 241 }
elessair 0:f269e3021894 242
elessair 0:f269e3021894 243 void __iar_file_Mtxinit(__iar_Rmtx *mutex)/*Initialize a file lock */
elessair 0:f269e3021894 244 {
elessair 0:f269e3021894 245 osMutexDef_t def;
elessair 0:f269e3021894 246 uint32_t index;
elessair 0:f269e3021894 247 for (index = 0; index < _FOPEN_MAX; index++) {
elessair 0:f269e3021894 248 if (0 == std_mutex_id_file[index]) {
elessair 0:f269e3021894 249 def.mutex = &std_mutex_file[index];
elessair 0:f269e3021894 250 std_mutex_id_file[index] = osMutexCreate(&def);
elessair 0:f269e3021894 251 *mutex = (__iar_Rmtx*)&std_mutex_id_file[index];
elessair 0:f269e3021894 252 return;
elessair 0:f269e3021894 253 }
elessair 0:f269e3021894 254 }
elessair 0:f269e3021894 255 // The variable _FOPEN_MAX needs to be increased
elessair 0:f269e3021894 256 error("Not enough mutexes\n");
elessair 0:f269e3021894 257 }
elessair 0:f269e3021894 258
elessair 0:f269e3021894 259 void __iar_file_Mtxdst(__iar_Rmtx *mutex) /* Destroy a file lock */
elessair 0:f269e3021894 260 {
elessair 0:f269e3021894 261 osMutexDelete(*(osMutexId*)*mutex);
elessair 0:f269e3021894 262 *mutex = 0;
elessair 0:f269e3021894 263 }
elessair 0:f269e3021894 264
elessair 0:f269e3021894 265 void __iar_file_Mtxlock(__iar_Rmtx *mutex) /* Lock a file lock */
elessair 0:f269e3021894 266 {
elessair 0:f269e3021894 267 osMutexWait(*(osMutexId*)*mutex, osWaitForever);
elessair 0:f269e3021894 268 }
elessair 0:f269e3021894 269
elessair 0:f269e3021894 270 void __iar_file_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a file lock */
elessair 0:f269e3021894 271 {
elessair 0:f269e3021894 272 osMutexRelease(*(osMutexId*)*mutex);
elessair 0:f269e3021894 273 }
elessair 0:f269e3021894 274
elessair 0:f269e3021894 275 #endif
elessair 0:f269e3021894 276
elessair 0:f269e3021894 277 /*----------------------------------------------------------------------------
elessair 0:f269e3021894 278 * RTX Optimizations (empty functions)
elessair 0:f269e3021894 279 *---------------------------------------------------------------------------*/
elessair 0:f269e3021894 280
elessair 0:f269e3021894 281 #if OS_ROBIN == 0
elessair 0:f269e3021894 282 void rt_init_robin (void) {;}
elessair 0:f269e3021894 283 void rt_chk_robin (void) {;}
elessair 0:f269e3021894 284 #endif
elessair 0:f269e3021894 285
elessair 0:f269e3021894 286 #if OS_STKCHECK == 0
elessair 0:f269e3021894 287 void rt_stk_check (void) {;}
elessair 0:f269e3021894 288 #endif
elessair 0:f269e3021894 289
elessair 0:f269e3021894 290
elessair 0:f269e3021894 291 /*----------------------------------------------------------------------------
elessair 0:f269e3021894 292 * Standard Library multithreading interface
elessair 0:f269e3021894 293 *---------------------------------------------------------------------------*/
elessair 0:f269e3021894 294
elessair 0:f269e3021894 295 #if defined (__CC_ARM) && !defined (__MICROLIB)
elessair 0:f269e3021894 296
elessair 0:f269e3021894 297 /*--------------------------- __user_perthread_libspace ---------------------*/
elessair 0:f269e3021894 298
elessair 0:f269e3021894 299 void *__user_perthread_libspace (void) {
elessair 0:f269e3021894 300 /* Provide a separate libspace for each task. */
elessair 0:f269e3021894 301 uint32_t idx;
elessair 0:f269e3021894 302
elessair 0:f269e3021894 303 idx = (os_running != 0U) ? runtask_id () : 0U;
elessair 0:f269e3021894 304 if (idx == 0U) {
elessair 0:f269e3021894 305 /* RTX not running yet. */
elessair 0:f269e3021894 306 return (&__libspace_start);
elessair 0:f269e3021894 307 }
elessair 0:f269e3021894 308 return ((void *)&std_libspace[idx-1]);
elessair 0:f269e3021894 309 }
elessair 0:f269e3021894 310
elessair 0:f269e3021894 311 /*--------------------------- _mutex_initialize -----------------------------*/
elessair 0:f269e3021894 312
elessair 0:f269e3021894 313 int _mutex_initialize (OS_ID *mutex) {
elessair 0:f269e3021894 314 /* Allocate and initialize a system mutex. */
elessair 0:f269e3021894 315
elessair 0:f269e3021894 316 if (nr_mutex >= OS_MUTEXCNT) {
elessair 0:f269e3021894 317 /* If you are here, you need to increase the number OS_MUTEXCNT. */
elessair 0:f269e3021894 318 error("Not enough stdlib mutexes\n");
elessair 0:f269e3021894 319 }
elessair 0:f269e3021894 320 *mutex = &std_libmutex[nr_mutex++];
elessair 0:f269e3021894 321 mutex_init (*mutex);
elessair 0:f269e3021894 322 return (1);
elessair 0:f269e3021894 323 }
elessair 0:f269e3021894 324
elessair 0:f269e3021894 325
elessair 0:f269e3021894 326 /*--------------------------- _mutex_acquire --------------------------------*/
elessair 0:f269e3021894 327
elessair 0:f269e3021894 328 __attribute__((used)) void _mutex_acquire (OS_ID *mutex) {
elessair 0:f269e3021894 329 /* Acquire a system mutex, lock stdlib resources. */
elessair 0:f269e3021894 330 if (os_running) {
elessair 0:f269e3021894 331 /* RTX running, acquire a mutex. */
elessair 0:f269e3021894 332 mutex_wait (*mutex);
elessair 0:f269e3021894 333 }
elessair 0:f269e3021894 334 }
elessair 0:f269e3021894 335
elessair 0:f269e3021894 336
elessair 0:f269e3021894 337 /*--------------------------- _mutex_release --------------------------------*/
elessair 0:f269e3021894 338
elessair 0:f269e3021894 339 __attribute__((used)) void _mutex_release (OS_ID *mutex) {
elessair 0:f269e3021894 340 /* Release a system mutex, unlock stdlib resources. */
elessair 0:f269e3021894 341 if (os_running) {
elessair 0:f269e3021894 342 /* RTX running, release a mutex. */
elessair 0:f269e3021894 343 mutex_rel (*mutex);
elessair 0:f269e3021894 344 }
elessair 0:f269e3021894 345 }
elessair 0:f269e3021894 346
elessair 0:f269e3021894 347 #endif
elessair 0:f269e3021894 348
elessair 0:f269e3021894 349
elessair 0:f269e3021894 350 /*----------------------------------------------------------------------------
elessair 0:f269e3021894 351 * RTX Startup
elessair 0:f269e3021894 352 *---------------------------------------------------------------------------*/
elessair 0:f269e3021894 353
elessair 0:f269e3021894 354 /* Main Thread definition */
elessair 0:f269e3021894 355 extern void pre_main (void);
elessair 0:f269e3021894 356
elessair 0:f269e3021894 357 #if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832) || defined (TARGET_STM32F334R8) ||\
elessair 0:f269e3021894 358 defined(TARGET_STM32F070RB) || defined(TARGET_STM32F072RB) || \
elessair 0:f269e3021894 359 defined(TARGET_STM32F302R8) || defined(TARGET_STM32F303K8) || defined (TARGET_STM32F334C8) ||\
elessair 0:f269e3021894 360 defined(TARGET_STM32F103RB)
elessair 0:f269e3021894 361 static uint32_t thread_stack_main[DEFAULT_STACK_SIZE / sizeof(uint32_t)];
elessair 0:f269e3021894 362 #elif defined(TARGET_XDOT_L151CC)
elessair 0:f269e3021894 363 static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 6 / sizeof(uint32_t)];
elessair 0:f269e3021894 364 #else
elessair 0:f269e3021894 365 static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 2 / sizeof(uint32_t)];
elessair 0:f269e3021894 366 #endif
elessair 0:f269e3021894 367 osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, sizeof(thread_stack_main), thread_stack_main};
elessair 0:f269e3021894 368
elessair 0:f269e3021894 369 /*
elessair 0:f269e3021894 370 * IAR Default Memory layout notes:
elessair 0:f269e3021894 371 * -Heap defined by "HEAP" region in .icf file
elessair 0:f269e3021894 372 * -Interrupt stack defined by "CSTACK" region in .icf file
elessair 0:f269e3021894 373 * -Value INITIAL_SP is ignored
elessair 0:f269e3021894 374 *
elessair 0:f269e3021894 375 * IAR Custom Memory layout notes:
elessair 0:f269e3021894 376 * -There is no custom layout available for IAR - everything must be defined in
elessair 0:f269e3021894 377 * the .icf file and use the default layout
elessair 0:f269e3021894 378 *
elessair 0:f269e3021894 379 *
elessair 0:f269e3021894 380 * GCC Default Memory layout notes:
elessair 0:f269e3021894 381 * -Block of memory from symbol __end__ to define INITIAL_SP used to setup interrupt
elessair 0:f269e3021894 382 * stack and heap in the function set_stack_heap()
elessair 0:f269e3021894 383 * -ISR_STACK_SIZE can be overridden to be larger or smaller
elessair 0:f269e3021894 384 *
elessair 0:f269e3021894 385 * GCC Custom Memory layout notes:
elessair 0:f269e3021894 386 * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
elessair 0:f269e3021894 387 * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
elessair 0:f269e3021894 388 *
elessair 0:f269e3021894 389 *
elessair 0:f269e3021894 390 * ARM Memory layout
elessair 0:f269e3021894 391 * -Block of memory from end of region "RW_IRAM1" to define INITIAL_SP used to setup interrupt
elessair 0:f269e3021894 392 * stack and heap in the function set_stack_heap()
elessair 0:f269e3021894 393 * -ISR_STACK_SIZE can be overridden to be larger or smaller
elessair 0:f269e3021894 394 *
elessair 0:f269e3021894 395 * ARM Custom Memory layout notes:
elessair 0:f269e3021894 396 * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
elessair 0:f269e3021894 397 * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
elessair 0:f269e3021894 398 *
elessair 0:f269e3021894 399 */
elessair 0:f269e3021894 400
elessair 0:f269e3021894 401 extern unsigned char *mbed_heap_start;
elessair 0:f269e3021894 402 extern uint32_t mbed_heap_size;
elessair 0:f269e3021894 403
elessair 0:f269e3021894 404 unsigned char *mbed_stack_isr_start = 0;
elessair 0:f269e3021894 405 uint32_t mbed_stack_isr_size = 0;
elessair 0:f269e3021894 406
elessair 0:f269e3021894 407 /*
elessair 0:f269e3021894 408 * Sanity check values
elessair 0:f269e3021894 409 */
elessair 0:f269e3021894 410 #if defined(__ICCARM__) && \
elessair 0:f269e3021894 411 (defined(HEAP_START) || defined(HEAP_SIZE) || \
elessair 0:f269e3021894 412 defined(ISR_STACK_START) && defined(ISR_STACK_SIZE))
elessair 0:f269e3021894 413 #error "No custom layout allowed for IAR. Use .icf file instead"
elessair 0:f269e3021894 414 #endif
elessair 0:f269e3021894 415 #if defined(HEAP_START) && !defined(HEAP_SIZE)
elessair 0:f269e3021894 416 #error "HEAP_SIZE must be defined if HEAP_START is defined"
elessair 0:f269e3021894 417 #endif
elessair 0:f269e3021894 418 #if defined(ISR_STACK_START) && !defined(ISR_STACK_SIZE)
elessair 0:f269e3021894 419 #error "ISR_STACK_SIZE must be defined if ISR_STACK_START is defined"
elessair 0:f269e3021894 420 #endif
elessair 0:f269e3021894 421 #if defined(HEAP_SIZE) && !defined(HEAP_START)
elessair 0:f269e3021894 422 #error "HEAP_START must be defined if HEAP_SIZE is defined"
elessair 0:f269e3021894 423 #endif
elessair 0:f269e3021894 424
elessair 0:f269e3021894 425 /* Interrupt stack and heap always defined for IAR
elessair 0:f269e3021894 426 * Main thread defined here
elessair 0:f269e3021894 427 */
elessair 0:f269e3021894 428 #if defined(__ICCARM__)
elessair 0:f269e3021894 429 #pragma section="CSTACK"
elessair 0:f269e3021894 430 #pragma section="HEAP"
elessair 0:f269e3021894 431 #define HEAP_START ((unsigned char*)__section_begin("HEAP"))
elessair 0:f269e3021894 432 #define HEAP_SIZE ((uint32_t)__section_size("HEAP"))
elessair 0:f269e3021894 433 #define ISR_STACK_START ((unsigned char*)__section_begin("CSTACK"))
elessair 0:f269e3021894 434 #define ISR_STACK_SIZE ((uint32_t)__section_size("CSTACK"))
elessair 0:f269e3021894 435 #endif
elessair 0:f269e3021894 436
elessair 0:f269e3021894 437 #if !defined(INITIAL_SP) && !defined(HEAP_START)
elessair 0:f269e3021894 438 #error "no target defined"
elessair 0:f269e3021894 439 #endif
elessair 0:f269e3021894 440
elessair 0:f269e3021894 441 /* Define heap region if it has not been defined already */
elessair 0:f269e3021894 442 #if !defined(HEAP_START)
elessair 0:f269e3021894 443 #if defined(__ICCARM__)
elessair 0:f269e3021894 444 #error "Heap should already be defined for IAR"
elessair 0:f269e3021894 445 #elif defined(__CC_ARM)
elessair 0:f269e3021894 446 extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
elessair 0:f269e3021894 447 #define HEAP_START ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit)
elessair 0:f269e3021894 448 #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
elessair 0:f269e3021894 449 #elif defined(__GNUC__)
elessair 0:f269e3021894 450 extern uint32_t __end__[];
elessair 0:f269e3021894 451 #define HEAP_START ((unsigned char*)__end__)
elessair 0:f269e3021894 452 #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
elessair 0:f269e3021894 453 #endif
elessair 0:f269e3021894 454 #endif
elessair 0:f269e3021894 455
elessair 0:f269e3021894 456 /* Define stack sizes if they haven't been set already */
elessair 0:f269e3021894 457 #if !defined(ISR_STACK_SIZE)
elessair 0:f269e3021894 458 #define ISR_STACK_SIZE ((uint32_t)OS_MAINSTKSIZE * 4)
elessair 0:f269e3021894 459 #endif
elessair 0:f269e3021894 460
elessair 0:f269e3021894 461 /*
elessair 0:f269e3021894 462 * set_stack_heap purpose is to set the following variables:
elessair 0:f269e3021894 463 * -mbed_heap_start
elessair 0:f269e3021894 464 * -mbed_heap_size
elessair 0:f269e3021894 465 * -mbed_stack_isr_start
elessair 0:f269e3021894 466 * -mbed_stack_isr_size
elessair 0:f269e3021894 467 *
elessair 0:f269e3021894 468 * Along with setting up os_thread_def_main
elessair 0:f269e3021894 469 */
elessair 0:f269e3021894 470 void set_stack_heap(void) {
elessair 0:f269e3021894 471
elessair 0:f269e3021894 472 unsigned char *free_start = HEAP_START;
elessair 0:f269e3021894 473 uint32_t free_size = HEAP_SIZE;
elessair 0:f269e3021894 474
elessair 0:f269e3021894 475 #ifdef ISR_STACK_START
elessair 0:f269e3021894 476 /* Interrupt stack explicitly specified */
elessair 0:f269e3021894 477 mbed_stack_isr_size = ISR_STACK_SIZE;
elessair 0:f269e3021894 478 mbed_stack_isr_start = ISR_STACK_START;
elessair 0:f269e3021894 479 #else
elessair 0:f269e3021894 480 /* Interrupt stack - reserve space at the end of the free block */
elessair 0:f269e3021894 481 mbed_stack_isr_size = ISR_STACK_SIZE;
elessair 0:f269e3021894 482 mbed_stack_isr_start = free_start + free_size - mbed_stack_isr_size;
elessair 0:f269e3021894 483 free_size -= mbed_stack_isr_size;
elessair 0:f269e3021894 484 #endif
elessair 0:f269e3021894 485
elessair 0:f269e3021894 486 /* Heap - everything else */
elessair 0:f269e3021894 487 mbed_heap_size = free_size;
elessair 0:f269e3021894 488 mbed_heap_start = free_start;
elessair 0:f269e3021894 489 }
elessair 0:f269e3021894 490
elessair 0:f269e3021894 491 #if defined (__CC_ARM)
elessair 0:f269e3021894 492
elessair 0:f269e3021894 493 #ifdef __MICROLIB
elessair 0:f269e3021894 494
elessair 0:f269e3021894 495 int main(void);
elessair 0:f269e3021894 496 void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF")));
elessair 0:f269e3021894 497 void $Super$$__cpp_initialize__aeabi_(void);
elessair 0:f269e3021894 498
elessair 0:f269e3021894 499 void _main_init (void) {
elessair 0:f269e3021894 500 osKernelInitialize();
elessair 0:f269e3021894 501 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 502 set_stack_heap();
elessair 0:f269e3021894 503 #endif
elessair 0:f269e3021894 504 osThreadCreate(&os_thread_def_main, NULL);
elessair 0:f269e3021894 505 osKernelStart();
elessair 0:f269e3021894 506 for (;;);
elessair 0:f269e3021894 507 }
elessair 0:f269e3021894 508
elessair 0:f269e3021894 509 void $Sub$$__cpp_initialize__aeabi_(void)
elessair 0:f269e3021894 510 {
elessair 0:f269e3021894 511 // this should invoke C++ initializers prior _main_init, we keep this empty and
elessair 0:f269e3021894 512 // invoke them after _main_init (=starts RTX kernel)
elessair 0:f269e3021894 513 }
elessair 0:f269e3021894 514
elessair 0:f269e3021894 515 void pre_main()
elessair 0:f269e3021894 516 {
elessair 0:f269e3021894 517 singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
elessair 0:f269e3021894 518 $Super$$__cpp_initialize__aeabi_();
elessair 0:f269e3021894 519 main();
elessair 0:f269e3021894 520 }
elessair 0:f269e3021894 521
elessair 0:f269e3021894 522 #else
elessair 0:f269e3021894 523
elessair 0:f269e3021894 524 int main(void);
elessair 0:f269e3021894 525
elessair 0:f269e3021894 526 void pre_main (void)
elessair 0:f269e3021894 527 {
elessair 0:f269e3021894 528 singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
elessair 0:f269e3021894 529 __rt_lib_init((unsigned)mbed_heap_start, (unsigned)(mbed_heap_start + mbed_heap_size));
elessair 0:f269e3021894 530 main();
elessair 0:f269e3021894 531 }
elessair 0:f269e3021894 532
elessair 0:f269e3021894 533 /* The single memory model is checking for stack collision at run time, verifing
elessair 0:f269e3021894 534 that the heap pointer is underneath the stack pointer.
elessair 0:f269e3021894 535
elessair 0:f269e3021894 536 With the RTOS there is not only one stack above the heap, there are multiple
elessair 0:f269e3021894 537 stacks and some of them are underneath the heap pointer.
elessair 0:f269e3021894 538 */
elessair 0:f269e3021894 539 #pragma import(__use_two_region_memory)
elessair 0:f269e3021894 540
elessair 0:f269e3021894 541 __asm void __rt_entry (void) {
elessair 0:f269e3021894 542
elessair 0:f269e3021894 543 IMPORT __user_setup_stackheap
elessair 0:f269e3021894 544 IMPORT _platform_post_stackheap_init
elessair 0:f269e3021894 545 IMPORT os_thread_def_main
elessair 0:f269e3021894 546 IMPORT osKernelInitialize
elessair 0:f269e3021894 547 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 548 IMPORT set_stack_heap
elessair 0:f269e3021894 549 #endif
elessair 0:f269e3021894 550 IMPORT osKernelStart
elessair 0:f269e3021894 551 IMPORT osThreadCreate
elessair 0:f269e3021894 552
elessair 0:f269e3021894 553 /* __user_setup_stackheap returns:
elessair 0:f269e3021894 554 * - Heap base in r0 (if the program uses the heap).
elessair 0:f269e3021894 555 * - Stack base in sp.
elessair 0:f269e3021894 556 * - Heap limit in r2 (if the program uses the heap and uses two-region memory).
elessair 0:f269e3021894 557 *
elessair 0:f269e3021894 558 * More info can be found in:
elessair 0:f269e3021894 559 * ARM Compiler ARM C and C++ Libraries and Floating-Point Support User Guide
elessair 0:f269e3021894 560 */
elessair 0:f269e3021894 561 BL __user_setup_stackheap
elessair 0:f269e3021894 562 /* Ignore return value of __user_setup_stackheap since
elessair 0:f269e3021894 563 * this will be setup by set_stack_heap
elessair 0:f269e3021894 564 */
elessair 0:f269e3021894 565 BL _platform_post_stackheap_init
elessair 0:f269e3021894 566 BL osKernelInitialize
elessair 0:f269e3021894 567 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 568 BL set_stack_heap
elessair 0:f269e3021894 569 #endif
elessair 0:f269e3021894 570 LDR R0,=os_thread_def_main
elessair 0:f269e3021894 571 MOVS R1,#0
elessair 0:f269e3021894 572 BL osThreadCreate
elessair 0:f269e3021894 573 BL osKernelStart
elessair 0:f269e3021894 574 /* osKernelStart should not return */
elessair 0:f269e3021894 575 B .
elessair 0:f269e3021894 576
elessair 0:f269e3021894 577 ALIGN
elessair 0:f269e3021894 578 }
elessair 0:f269e3021894 579
elessair 0:f269e3021894 580 #endif
elessair 0:f269e3021894 581
elessair 0:f269e3021894 582 #elif defined (__GNUC__)
elessair 0:f269e3021894 583
elessair 0:f269e3021894 584 osMutexDef(malloc_mutex);
elessair 0:f269e3021894 585 static osMutexId malloc_mutex_id;
elessair 0:f269e3021894 586 osMutexDef(env_mutex);
elessair 0:f269e3021894 587 static osMutexId env_mutex_id;
elessair 0:f269e3021894 588
elessair 0:f269e3021894 589 extern int atexit(void (*func)(void));
elessair 0:f269e3021894 590 extern void __libc_fini_array(void);
elessair 0:f269e3021894 591 extern void __libc_init_array (void);
elessair 0:f269e3021894 592 extern int main(int argc, char **argv);
elessair 0:f269e3021894 593
elessair 0:f269e3021894 594 void pre_main(void) {
elessair 0:f269e3021894 595 singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
elessair 0:f269e3021894 596 malloc_mutex_id = osMutexCreate(osMutex(malloc_mutex));
elessair 0:f269e3021894 597 env_mutex_id = osMutexCreate(osMutex(env_mutex));
elessair 0:f269e3021894 598 __libc_init_array();
elessair 0:f269e3021894 599 main(0, NULL);
elessair 0:f269e3021894 600 }
elessair 0:f269e3021894 601
elessair 0:f269e3021894 602 __attribute__((naked)) void software_init_hook_rtos (void) {
elessair 0:f269e3021894 603 __asm (
elessair 0:f269e3021894 604 "bl osKernelInitialize\n"
elessair 0:f269e3021894 605 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 606 "bl set_stack_heap\n"
elessair 0:f269e3021894 607 #endif
elessair 0:f269e3021894 608 "ldr r0,=os_thread_def_main\n"
elessair 0:f269e3021894 609 "movs r1,#0\n"
elessair 0:f269e3021894 610 "bl osThreadCreate\n"
elessair 0:f269e3021894 611 "bl osKernelStart\n"
elessair 0:f269e3021894 612 /* osKernelStart should not return */
elessair 0:f269e3021894 613 "B .\n"
elessair 0:f269e3021894 614 );
elessair 0:f269e3021894 615 }
elessair 0:f269e3021894 616
elessair 0:f269e3021894 617 // Opaque declaration of _reent structure
elessair 0:f269e3021894 618 struct _reent;
elessair 0:f269e3021894 619
elessair 0:f269e3021894 620 void __rtos_malloc_lock( struct _reent *_r )
elessair 0:f269e3021894 621 {
elessair 0:f269e3021894 622 osMutexWait(malloc_mutex_id, osWaitForever);
elessair 0:f269e3021894 623 }
elessair 0:f269e3021894 624
elessair 0:f269e3021894 625 void __rtos_malloc_unlock( struct _reent *_r )
elessair 0:f269e3021894 626 {
elessair 0:f269e3021894 627 osMutexRelease(malloc_mutex_id);
elessair 0:f269e3021894 628 }
elessair 0:f269e3021894 629
elessair 0:f269e3021894 630 void __rtos_env_lock( struct _reent *_r )
elessair 0:f269e3021894 631 {
elessair 0:f269e3021894 632 osMutexWait(env_mutex_id, osWaitForever);
elessair 0:f269e3021894 633 }
elessair 0:f269e3021894 634
elessair 0:f269e3021894 635 void __rtos_env_unlock( struct _reent *_r )
elessair 0:f269e3021894 636 {
elessair 0:f269e3021894 637 osMutexRelease(env_mutex_id);
elessair 0:f269e3021894 638 }
elessair 0:f269e3021894 639
elessair 0:f269e3021894 640 #elif defined (__ICCARM__)
elessair 0:f269e3021894 641
elessair 0:f269e3021894 642 extern void* __vector_table;
elessair 0:f269e3021894 643 extern int __low_level_init(void);
elessair 0:f269e3021894 644 extern void __iar_data_init3(void);
elessair 0:f269e3021894 645 extern __weak void __iar_init_core( void );
elessair 0:f269e3021894 646 extern __weak void __iar_init_vfp( void );
elessair 0:f269e3021894 647 extern void __iar_dynamic_initialization(void);
elessair 0:f269e3021894 648 extern void mbed_sdk_init(void);
elessair 0:f269e3021894 649 extern void mbed_main(void);
elessair 0:f269e3021894 650 extern int main(void);
elessair 0:f269e3021894 651 extern void exit(int arg);
elessair 0:f269e3021894 652
elessair 0:f269e3021894 653 static uint8_t low_level_init_needed;
elessair 0:f269e3021894 654
elessair 0:f269e3021894 655 void pre_main(void) {
elessair 0:f269e3021894 656 singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex));
elessair 0:f269e3021894 657 if (low_level_init_needed) {
elessair 0:f269e3021894 658 __iar_dynamic_initialization();
elessair 0:f269e3021894 659 }
elessair 0:f269e3021894 660 mbed_main();
elessair 0:f269e3021894 661 main();
elessair 0:f269e3021894 662 }
elessair 0:f269e3021894 663
elessair 0:f269e3021894 664 #pragma required=__vector_table
elessair 0:f269e3021894 665 void __iar_program_start( void )
elessair 0:f269e3021894 666 {
elessair 0:f269e3021894 667 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 668 __iar_init_core();
elessair 0:f269e3021894 669 __iar_init_vfp();
elessair 0:f269e3021894 670
elessair 0:f269e3021894 671 uint8_t low_level_init_needed_local;
elessair 0:f269e3021894 672
elessair 0:f269e3021894 673 low_level_init_needed_local = __low_level_init();
elessair 0:f269e3021894 674 if (low_level_init_needed_local) {
elessair 0:f269e3021894 675 __iar_data_init3();
elessair 0:f269e3021894 676 mbed_sdk_init();
elessair 0:f269e3021894 677 }
elessair 0:f269e3021894 678 /* Store in a global variable after RAM has been initialized */
elessair 0:f269e3021894 679 low_level_init_needed = low_level_init_needed_local;
elessair 0:f269e3021894 680 #endif
elessair 0:f269e3021894 681 osKernelInitialize();
elessair 0:f269e3021894 682 #ifdef __MBED_CMSIS_RTOS_CM
elessair 0:f269e3021894 683 set_stack_heap();
elessair 0:f269e3021894 684 #endif
elessair 0:f269e3021894 685 osThreadCreate(&os_thread_def_main, NULL);
elessair 0:f269e3021894 686 osKernelStart();
elessair 0:f269e3021894 687 /* osKernelStart should not return */
elessair 0:f269e3021894 688 while (1);
elessair 0:f269e3021894 689 }
elessair 0:f269e3021894 690
elessair 0:f269e3021894 691 #endif
elessair 0:f269e3021894 692
elessair 0:f269e3021894 693
elessair 0:f269e3021894 694 /*----------------------------------------------------------------------------
elessair 0:f269e3021894 695 * end of file
elessair 0:f269e3021894 696 *---------------------------------------------------------------------------*/
elessair 0:f269e3021894 697
elessair 0:f269e3021894 698 /** @}*/