mbed-os

Dependents:   cobaLCDJoyMotor_Thread odometry_omni_3roda_v3 odometry_omni_3roda_v1 odometry_omni_3roda_v2 ... more

Committer:
be_bryan
Date:
Mon Dec 11 17:54:04 2017 +0000
Revision:
0:b74591d5ab33
motor ++

Who changed what in which revision?

UserRevisionLine numberNew contents of line
be_bryan 0:b74591d5ab33 1 /* mbed Microcontroller Library
be_bryan 0:b74591d5ab33 2 * Copyright (c) 2006-2016 ARM Limited
be_bryan 0:b74591d5ab33 3 *
be_bryan 0:b74591d5ab33 4 * Licensed under the Apache License, Version 2.0 (the "License");
be_bryan 0:b74591d5ab33 5 * you may not use this file except in compliance with the License.
be_bryan 0:b74591d5ab33 6 * You may obtain a copy of the License at
be_bryan 0:b74591d5ab33 7 *
be_bryan 0:b74591d5ab33 8 * http://www.apache.org/licenses/LICENSE-2.0
be_bryan 0:b74591d5ab33 9 *
be_bryan 0:b74591d5ab33 10 * Unless required by applicable law or agreed to in writing, software
be_bryan 0:b74591d5ab33 11 * distributed under the License is distributed on an "AS IS" BASIS,
be_bryan 0:b74591d5ab33 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
be_bryan 0:b74591d5ab33 13 * See the License for the specific language governing permissions and
be_bryan 0:b74591d5ab33 14 * limitations under the License.
be_bryan 0:b74591d5ab33 15 */
be_bryan 0:b74591d5ab33 16
be_bryan 0:b74591d5ab33 17 /* mbed OS boot sequence
be_bryan 0:b74591d5ab33 18 *
be_bryan 0:b74591d5ab33 19 * Most of mbed supported targets use default ARM Cortex M boot approach, where the core starts executing reset vector
be_bryan 0:b74591d5ab33 20 * after power up. Reset ISR is defined for each target by the vendor (basing on CMSIS template). Reset vector is
be_bryan 0:b74591d5ab33 21 * responsible for low level platform init and then calling in libc (__main). Depending on compiler and version of C
be_bryan 0:b74591d5ab33 22 * library, predefined function will be called which is implemented by mbed OS.
be_bryan 0:b74591d5ab33 23 *
be_bryan 0:b74591d5ab33 24 * There's number of functions, vendor and users can provide to setup the platform and/or inject a code to be executed
be_bryan 0:b74591d5ab33 25 * before main():
be_bryan 0:b74591d5ab33 26 * * Reset vector and SystemInit: Reset vector should do low level core and board initialization.
be_bryan 0:b74591d5ab33 27 * * mbed_sdk_init: Higher level board init and making sure the board is ready for the mbed OS.
be_bryan 0:b74591d5ab33 28 * * mbed_main: User's code to be executed before main().
be_bryan 0:b74591d5ab33 29 * * main: Standard application code.
be_bryan 0:b74591d5ab33 30 *
be_bryan 0:b74591d5ab33 31 * Detailed boot procedures:
be_bryan 0:b74591d5ab33 32 *
be_bryan 0:b74591d5ab33 33 * For ARMCC:
be_bryan 0:b74591d5ab33 34 * ==========
be_bryan 0:b74591d5ab33 35 *
be_bryan 0:b74591d5ab33 36 * Reset (TARGET)
be_bryan 0:b74591d5ab33 37 * -> SystemInit (TARGET)
be_bryan 0:b74591d5ab33 38 * -> __main (LIBC)
be_bryan 0:b74591d5ab33 39 * -> __rt_entry (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 40 * -> __user_setup_stackheap (LIBC)
be_bryan 0:b74591d5ab33 41 * -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 42 * -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 43 * -> mbed_sdk_init (TARGET)
be_bryan 0:b74591d5ab33 44 * -> _platform_post_stackheap_init (RTX)
be_bryan 0:b74591d5ab33 45 * -> osKernelInitialize (RTX)
be_bryan 0:b74591d5ab33 46 * -> mbed_start_main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 47 * -> osThreadNew (RTX)
be_bryan 0:b74591d5ab33 48 * -> pre_main(MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 49 * -> __rt_lib_init (LIBC)
be_bryan 0:b74591d5ab33 50 * -> $Sub$$main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 51 * -> mbed_main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 52 * -> main (APP)
be_bryan 0:b74591d5ab33 53 * -> osKernelStart (RTX)
be_bryan 0:b74591d5ab33 54 *
be_bryan 0:b74591d5ab33 55 * In addition to the above, libc will use functions defined by RTX: __user_perthread_libspace, _mutex_initialize,
be_bryan 0:b74591d5ab33 56 * _mutex_acquire, _mutex_release, _mutex_free for details consult: ARM C and C++ Libraries and Floating-Point
be_bryan 0:b74591d5ab33 57 * Support User Guide.
be_bryan 0:b74591d5ab33 58 *
be_bryan 0:b74591d5ab33 59 * For MICROLIB:
be_bryan 0:b74591d5ab33 60 * ==========
be_bryan 0:b74591d5ab33 61 *
be_bryan 0:b74591d5ab33 62 * Reset (TARGET)
be_bryan 0:b74591d5ab33 63 * -> SystemInit (TARGET)
be_bryan 0:b74591d5ab33 64 * -> __main (LIBC)
be_bryan 0:b74591d5ab33 65 * -> _main_init (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 66 * -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 67 * -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 68 * -> mbed_sdk_init (TARGET)
be_bryan 0:b74591d5ab33 69 * -> osKernelInitialize (RTX)
be_bryan 0:b74591d5ab33 70 * -> mbed_start_main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 71 * -> osThreadNew (RTX)
be_bryan 0:b74591d5ab33 72 * -> pre_main(MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 73 * -> __cpp_initialize__aeabi_ (LIBC)
be_bryan 0:b74591d5ab33 74 * -> $Sub$$main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 75 * -> mbed_main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 76 * -> main (APP)
be_bryan 0:b74591d5ab33 77 * -> osKernelStart (RTX)
be_bryan 0:b74591d5ab33 78 *
be_bryan 0:b74591d5ab33 79 * For GCC:
be_bryan 0:b74591d5ab33 80 * ========
be_bryan 0:b74591d5ab33 81 *
be_bryan 0:b74591d5ab33 82 * Reset (TARGET)
be_bryan 0:b74591d5ab33 83 * -> SystemInit (TARGET)
be_bryan 0:b74591d5ab33 84 * -> __main (LIBC)
be_bryan 0:b74591d5ab33 85 * -> software_init_hook (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 86 * -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 87 * -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 88 * -> mbed_sdk_init (TARGET)
be_bryan 0:b74591d5ab33 89 * -> osKernelInitialize (RTX)
be_bryan 0:b74591d5ab33 90 * -> mbed_start_main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 91 * -> osThreadNew (RTX)
be_bryan 0:b74591d5ab33 92 * -> pre_main(MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 93 * -> __libc_init_array (LIBC)
be_bryan 0:b74591d5ab33 94 * -> __wrap_main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 95 * -> mbed_main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 96 * -> __real_main (APP)
be_bryan 0:b74591d5ab33 97 * -> osKernelStart (RTX)
be_bryan 0:b74591d5ab33 98 *
be_bryan 0:b74591d5ab33 99 * For IAR:
be_bryan 0:b74591d5ab33 100 * ========
be_bryan 0:b74591d5ab33 101 *
be_bryan 0:b74591d5ab33 102 * Reset (TARGET)
be_bryan 0:b74591d5ab33 103 * -> SystemInit (TARGET)
be_bryan 0:b74591d5ab33 104 * -> __iar_program_start
be_bryan 0:b74591d5ab33 105 * -> __iar_init_core
be_bryan 0:b74591d5ab33 106 * -> __iar_init_core
be_bryan 0:b74591d5ab33 107 * -> __iar_init_vfp
be_bryan 0:b74591d5ab33 108 * -> __low_level_init
be_bryan 0:b74591d5ab33 109 * -> __iar_data_init3
be_bryan 0:b74591d5ab33 110 * -> mbed_cpy_nvic (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 111 * -> mbed_sdk_init (TARGET)
be_bryan 0:b74591d5ab33 112 * -> mbed_set_stack_heap (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 113 * -> osKernelInitialize (RTX)
be_bryan 0:b74591d5ab33 114 * -> mbed_start_main (MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 115 * -> osThreadNew (RTX)
be_bryan 0:b74591d5ab33 116 * -> pre_main(MBED: rtos/mbed_boot.c)
be_bryan 0:b74591d5ab33 117 * -> __iar_dynamic_initialization
be_bryan 0:b74591d5ab33 118 * -> main
be_bryan 0:b74591d5ab33 119 * -> osKernelStart (RTX)
be_bryan 0:b74591d5ab33 120 *
be_bryan 0:b74591d5ab33 121 * Other notes:
be_bryan 0:b74591d5ab33 122 *
be_bryan 0:b74591d5ab33 123 * * In addition to the above, libc will use functions defined in mbed_boot.c: __rtos_malloc_lock/unlock,
be_bryan 0:b74591d5ab33 124 * __rtos_env_lock/unlock.
be_bryan 0:b74591d5ab33 125 *
be_bryan 0:b74591d5ab33 126 * * First step after the execution is passed to mbed, software_init_hook for GCC and __rt_entry for ARMC is to
be_bryan 0:b74591d5ab33 127 * initialize heap.
be_bryan 0:b74591d5ab33 128 *
be_bryan 0:b74591d5ab33 129 * Memory layout notes:
be_bryan 0:b74591d5ab33 130 * ====================
be_bryan 0:b74591d5ab33 131 *
be_bryan 0:b74591d5ab33 132 * IAR Default Memory layout notes:
be_bryan 0:b74591d5ab33 133 * -Heap defined by "HEAP" region in .icf file
be_bryan 0:b74591d5ab33 134 * -Interrupt stack defined by "CSTACK" region in .icf file
be_bryan 0:b74591d5ab33 135 * -Value INITIAL_SP is ignored
be_bryan 0:b74591d5ab33 136 *
be_bryan 0:b74591d5ab33 137 * IAR Custom Memory layout notes:
be_bryan 0:b74591d5ab33 138 * -There is no custom layout available for IAR - everything must be defined in
be_bryan 0:b74591d5ab33 139 * the .icf file and use the default layout
be_bryan 0:b74591d5ab33 140 *
be_bryan 0:b74591d5ab33 141 *
be_bryan 0:b74591d5ab33 142 * GCC Default Memory layout notes:
be_bryan 0:b74591d5ab33 143 * -Block of memory from symbol __end__ to define INITIAL_SP used to setup interrupt
be_bryan 0:b74591d5ab33 144 * stack and heap in the function set_stack_heap()
be_bryan 0:b74591d5ab33 145 * -ISR_STACK_SIZE can be overridden to be larger or smaller
be_bryan 0:b74591d5ab33 146 *
be_bryan 0:b74591d5ab33 147 * GCC Custom Memory layout notes:
be_bryan 0:b74591d5ab33 148 * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
be_bryan 0:b74591d5ab33 149 * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
be_bryan 0:b74591d5ab33 150 *
be_bryan 0:b74591d5ab33 151 *
be_bryan 0:b74591d5ab33 152 * ARM Memory layout
be_bryan 0:b74591d5ab33 153 * -Block of memory from end of region "RW_IRAM1" to define INITIAL_SP used to setup interrupt
be_bryan 0:b74591d5ab33 154 * stack and heap in the function set_stack_heap()
be_bryan 0:b74591d5ab33 155 * -ISR_STACK_SIZE can be overridden to be larger or smaller
be_bryan 0:b74591d5ab33 156 *
be_bryan 0:b74591d5ab33 157 * ARM Custom Memory layout notes:
be_bryan 0:b74591d5ab33 158 * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE
be_bryan 0:b74591d5ab33 159 * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE
be_bryan 0:b74591d5ab33 160 *
be_bryan 0:b74591d5ab33 161 */
be_bryan 0:b74591d5ab33 162
be_bryan 0:b74591d5ab33 163 #include <stdlib.h>
be_bryan 0:b74591d5ab33 164
be_bryan 0:b74591d5ab33 165 #include "cmsis.h"
be_bryan 0:b74591d5ab33 166 #include "mbed_rtx.h"
be_bryan 0:b74591d5ab33 167 #include "mbed_rtos_storage.h"
be_bryan 0:b74591d5ab33 168 #include "cmsis_os2.h"
be_bryan 0:b74591d5ab33 169 #include "mbed_toolchain.h"
be_bryan 0:b74591d5ab33 170 #include "mbed_error.h"
be_bryan 0:b74591d5ab33 171 #include "mbed_critical.h"
be_bryan 0:b74591d5ab33 172 #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ >= 8000000)
be_bryan 0:b74591d5ab33 173 #include <DLib_Threads.h>
be_bryan 0:b74591d5ab33 174 #endif
be_bryan 0:b74591d5ab33 175 /* Heap limits - only used if set */
be_bryan 0:b74591d5ab33 176 extern unsigned char *mbed_heap_start;
be_bryan 0:b74591d5ab33 177 extern uint32_t mbed_heap_size;
be_bryan 0:b74591d5ab33 178
be_bryan 0:b74591d5ab33 179 unsigned char *mbed_stack_isr_start = 0;
be_bryan 0:b74591d5ab33 180 uint32_t mbed_stack_isr_size = 0;
be_bryan 0:b74591d5ab33 181
be_bryan 0:b74591d5ab33 182 WEAK void mbed_main(void);
be_bryan 0:b74591d5ab33 183 void pre_main (void);
be_bryan 0:b74591d5ab33 184
be_bryan 0:b74591d5ab33 185 osThreadAttr_t _main_thread_attr;
be_bryan 0:b74591d5ab33 186
be_bryan 0:b74591d5ab33 187 /** The main thread's stack size can be configured by the application, if not explicitly specified it'll default to 4K */
be_bryan 0:b74591d5ab33 188 #ifndef MBED_CONF_APP_MAIN_STACK_SIZE
be_bryan 0:b74591d5ab33 189 #define MBED_CONF_APP_MAIN_STACK_SIZE 4096
be_bryan 0:b74591d5ab33 190 #endif
be_bryan 0:b74591d5ab33 191 MBED_ALIGN(8) char _main_stack[MBED_CONF_APP_MAIN_STACK_SIZE];
be_bryan 0:b74591d5ab33 192 mbed_rtos_storage_thread_t _main_obj;
be_bryan 0:b74591d5ab33 193
be_bryan 0:b74591d5ab33 194 osMutexId_t singleton_mutex_id;
be_bryan 0:b74591d5ab33 195 mbed_rtos_storage_mutex_t singleton_mutex_obj;
be_bryan 0:b74591d5ab33 196 osMutexAttr_t singleton_mutex_attr;
be_bryan 0:b74591d5ab33 197
be_bryan 0:b74591d5ab33 198 /*
be_bryan 0:b74591d5ab33 199 * Sanity check values
be_bryan 0:b74591d5ab33 200 */
be_bryan 0:b74591d5ab33 201 #if defined(__ICCARM__) && \
be_bryan 0:b74591d5ab33 202 (defined(HEAP_START) || defined(HEAP_SIZE) || \
be_bryan 0:b74591d5ab33 203 defined(ISR_STACK_START) && defined(ISR_STACK_SIZE))
be_bryan 0:b74591d5ab33 204 #error "No custom layout allowed for IAR. Use .icf file instead"
be_bryan 0:b74591d5ab33 205 #endif
be_bryan 0:b74591d5ab33 206 #if defined(HEAP_START) && !defined(HEAP_SIZE)
be_bryan 0:b74591d5ab33 207 #error "HEAP_SIZE must be defined if HEAP_START is defined"
be_bryan 0:b74591d5ab33 208 #endif
be_bryan 0:b74591d5ab33 209 #if defined(ISR_STACK_START) && !defined(ISR_STACK_SIZE)
be_bryan 0:b74591d5ab33 210 #error "ISR_STACK_SIZE must be defined if ISR_STACK_START is defined"
be_bryan 0:b74591d5ab33 211 #endif
be_bryan 0:b74591d5ab33 212 #if defined(HEAP_SIZE) && !defined(HEAP_START)
be_bryan 0:b74591d5ab33 213 #error "HEAP_START must be defined if HEAP_SIZE is defined"
be_bryan 0:b74591d5ab33 214 #endif
be_bryan 0:b74591d5ab33 215
be_bryan 0:b74591d5ab33 216 /* IAR - INITIAL_SP and HEAP_START ignored as described in Memory layout notes above
be_bryan 0:b74591d5ab33 217 */
be_bryan 0:b74591d5ab33 218 #if !defined(__ICCARM__) && !defined(INITIAL_SP) && !defined(HEAP_START)
be_bryan 0:b74591d5ab33 219 #error "no target defined"
be_bryan 0:b74591d5ab33 220 #endif
be_bryan 0:b74591d5ab33 221
be_bryan 0:b74591d5ab33 222 /* Interrupt stack and heap always defined for IAR
be_bryan 0:b74591d5ab33 223 * Main thread defined here
be_bryan 0:b74591d5ab33 224 */
be_bryan 0:b74591d5ab33 225 #if defined(__ICCARM__)
be_bryan 0:b74591d5ab33 226 #pragma section="CSTACK"
be_bryan 0:b74591d5ab33 227 #pragma section="HEAP"
be_bryan 0:b74591d5ab33 228 #define HEAP_START ((unsigned char*)__section_begin("HEAP"))
be_bryan 0:b74591d5ab33 229 #define HEAP_SIZE ((uint32_t)__section_size("HEAP"))
be_bryan 0:b74591d5ab33 230 #define ISR_STACK_START ((unsigned char*)__section_begin("CSTACK"))
be_bryan 0:b74591d5ab33 231 #define ISR_STACK_SIZE ((uint32_t)__section_size("CSTACK"))
be_bryan 0:b74591d5ab33 232 #endif
be_bryan 0:b74591d5ab33 233
be_bryan 0:b74591d5ab33 234 /* Define heap region if it has not been defined already */
be_bryan 0:b74591d5ab33 235 #if !defined(HEAP_START)
be_bryan 0:b74591d5ab33 236 #if defined(__ICCARM__)
be_bryan 0:b74591d5ab33 237 #error "Heap should already be defined for IAR"
be_bryan 0:b74591d5ab33 238 #elif defined(__CC_ARM) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
be_bryan 0:b74591d5ab33 239 extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[];
be_bryan 0:b74591d5ab33 240 #define HEAP_START ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit)
be_bryan 0:b74591d5ab33 241 #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
be_bryan 0:b74591d5ab33 242 #elif defined(__GNUC__)
be_bryan 0:b74591d5ab33 243 extern uint32_t __end__[];
be_bryan 0:b74591d5ab33 244 #define HEAP_START ((unsigned char*)__end__)
be_bryan 0:b74591d5ab33 245 #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START))
be_bryan 0:b74591d5ab33 246 #endif
be_bryan 0:b74591d5ab33 247 #endif
be_bryan 0:b74591d5ab33 248
be_bryan 0:b74591d5ab33 249 /* Define stack sizes if they haven't been set already */
be_bryan 0:b74591d5ab33 250 #if !defined(ISR_STACK_SIZE)
be_bryan 0:b74591d5ab33 251 #define ISR_STACK_SIZE ((uint32_t)1024)
be_bryan 0:b74591d5ab33 252 #endif
be_bryan 0:b74591d5ab33 253
be_bryan 0:b74591d5ab33 254 /*
be_bryan 0:b74591d5ab33 255 * mbed_set_stack_heap purpose is to set the following variables:
be_bryan 0:b74591d5ab33 256 * -mbed_heap_start
be_bryan 0:b74591d5ab33 257 * -mbed_heap_size
be_bryan 0:b74591d5ab33 258 * -mbed_stack_isr_start
be_bryan 0:b74591d5ab33 259 * -mbed_stack_isr_size
be_bryan 0:b74591d5ab33 260 */
be_bryan 0:b74591d5ab33 261 void mbed_set_stack_heap(void) {
be_bryan 0:b74591d5ab33 262
be_bryan 0:b74591d5ab33 263 unsigned char *free_start = HEAP_START;
be_bryan 0:b74591d5ab33 264 uint32_t free_size = HEAP_SIZE;
be_bryan 0:b74591d5ab33 265
be_bryan 0:b74591d5ab33 266 #ifdef ISR_STACK_START
be_bryan 0:b74591d5ab33 267 /* Interrupt stack explicitly specified */
be_bryan 0:b74591d5ab33 268 mbed_stack_isr_size = ISR_STACK_SIZE;
be_bryan 0:b74591d5ab33 269 mbed_stack_isr_start = ISR_STACK_START;
be_bryan 0:b74591d5ab33 270 #else
be_bryan 0:b74591d5ab33 271 /* Interrupt stack - reserve space at the end of the free block */
be_bryan 0:b74591d5ab33 272 mbed_stack_isr_size = ISR_STACK_SIZE < free_size ? ISR_STACK_SIZE : free_size;
be_bryan 0:b74591d5ab33 273 mbed_stack_isr_start = free_start + free_size - mbed_stack_isr_size;
be_bryan 0:b74591d5ab33 274 free_size -= mbed_stack_isr_size;
be_bryan 0:b74591d5ab33 275 #endif
be_bryan 0:b74591d5ab33 276
be_bryan 0:b74591d5ab33 277 /* Heap - everything else */
be_bryan 0:b74591d5ab33 278 mbed_heap_size = free_size;
be_bryan 0:b74591d5ab33 279 mbed_heap_start = free_start;
be_bryan 0:b74591d5ab33 280 }
be_bryan 0:b74591d5ab33 281
be_bryan 0:b74591d5ab33 282 static void mbed_cpy_nvic(void)
be_bryan 0:b74591d5ab33 283 {
be_bryan 0:b74591d5ab33 284 /* If vector address in RAM is defined, copy and switch to dynamic vectors. Exceptions for M0 which doesn't have
be_bryan 0:b74591d5ab33 285 VTOR register and for A9 for which CMSIS doesn't define NVIC_SetVector; in both cases target code is
be_bryan 0:b74591d5ab33 286 responsible for correctly handling the vectors.
be_bryan 0:b74591d5ab33 287 */
be_bryan 0:b74591d5ab33 288 #if !defined(__CORTEX_M0) && !defined(__CORTEX_A9)
be_bryan 0:b74591d5ab33 289 #ifdef NVIC_RAM_VECTOR_ADDRESS
be_bryan 0:b74591d5ab33 290 uint32_t *old_vectors = (uint32_t *)SCB->VTOR;
be_bryan 0:b74591d5ab33 291 uint32_t *vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
be_bryan 0:b74591d5ab33 292 for (int i = 0; i < NVIC_NUM_VECTORS; i++) {
be_bryan 0:b74591d5ab33 293 vectors[i] = old_vectors[i];
be_bryan 0:b74591d5ab33 294 }
be_bryan 0:b74591d5ab33 295 SCB->VTOR = (uint32_t)NVIC_RAM_VECTOR_ADDRESS;
be_bryan 0:b74591d5ab33 296 #endif /* NVIC_RAM_VECTOR_ADDRESS */
be_bryan 0:b74591d5ab33 297 #endif /* !defined(__CORTEX_M0) && !defined(__CORTEX_A9) */
be_bryan 0:b74591d5ab33 298 }
be_bryan 0:b74591d5ab33 299
be_bryan 0:b74591d5ab33 300 /* mbed_main is a function that is called before main()
be_bryan 0:b74591d5ab33 301 * mbed_sdk_init() is also a function that is called before main(), but unlike
be_bryan 0:b74591d5ab33 302 * mbed_main(), it is not meant for user code, but for the SDK itself to perform
be_bryan 0:b74591d5ab33 303 * initializations before main() is called.
be_bryan 0:b74591d5ab33 304 */
be_bryan 0:b74591d5ab33 305 WEAK void mbed_main(void) {
be_bryan 0:b74591d5ab33 306
be_bryan 0:b74591d5ab33 307 }
be_bryan 0:b74591d5ab33 308
be_bryan 0:b74591d5ab33 309 /* This function can be implemented by the target to perform higher level target initialization, before the mbed OS or
be_bryan 0:b74591d5ab33 310 * RTX is started.
be_bryan 0:b74591d5ab33 311 */
be_bryan 0:b74591d5ab33 312 void mbed_sdk_init(void);
be_bryan 0:b74591d5ab33 313 WEAK void mbed_sdk_init(void) {
be_bryan 0:b74591d5ab33 314 }
be_bryan 0:b74591d5ab33 315
be_bryan 0:b74591d5ab33 316 void mbed_start_main(void)
be_bryan 0:b74591d5ab33 317 {
be_bryan 0:b74591d5ab33 318 _main_thread_attr.stack_mem = _main_stack;
be_bryan 0:b74591d5ab33 319 _main_thread_attr.stack_size = sizeof(_main_stack);
be_bryan 0:b74591d5ab33 320 _main_thread_attr.cb_size = sizeof(_main_obj);
be_bryan 0:b74591d5ab33 321 _main_thread_attr.cb_mem = &_main_obj;
be_bryan 0:b74591d5ab33 322 _main_thread_attr.priority = osPriorityNormal;
be_bryan 0:b74591d5ab33 323 _main_thread_attr.name = "main_thread";
be_bryan 0:b74591d5ab33 324 osThreadId_t result = osThreadNew((osThreadFunc_t)pre_main, NULL, &_main_thread_attr);
be_bryan 0:b74591d5ab33 325 if ((void *)result == NULL) {
be_bryan 0:b74591d5ab33 326 error("Pre main thread not created");
be_bryan 0:b74591d5ab33 327 }
be_bryan 0:b74591d5ab33 328
be_bryan 0:b74591d5ab33 329 osKernelStart();
be_bryan 0:b74591d5ab33 330 }
be_bryan 0:b74591d5ab33 331
be_bryan 0:b74591d5ab33 332 /******************** Toolchain specific code ********************/
be_bryan 0:b74591d5ab33 333
be_bryan 0:b74591d5ab33 334 #if defined (__CC_ARM) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
be_bryan 0:b74591d5ab33 335
be_bryan 0:b74591d5ab33 336 /* Common for both ARMC and MICROLIB */
be_bryan 0:b74591d5ab33 337 int $Super$$main(void);
be_bryan 0:b74591d5ab33 338 int $Sub$$main(void) {
be_bryan 0:b74591d5ab33 339 mbed_main();
be_bryan 0:b74591d5ab33 340 return $Super$$main();
be_bryan 0:b74591d5ab33 341 }
be_bryan 0:b74591d5ab33 342
be_bryan 0:b74591d5ab33 343 #if defined (__MICROLIB) /******************** MICROLIB ********************/
be_bryan 0:b74591d5ab33 344
be_bryan 0:b74591d5ab33 345 int main(void);
be_bryan 0:b74591d5ab33 346 void _main_init (void) __attribute__((section(".ARM.Collect$$$$000000FF")));
be_bryan 0:b74591d5ab33 347 void $Super$$__cpp_initialize__aeabi_(void);
be_bryan 0:b74591d5ab33 348
be_bryan 0:b74591d5ab33 349 void _main_init (void) {
be_bryan 0:b74591d5ab33 350 mbed_set_stack_heap();
be_bryan 0:b74591d5ab33 351 /* Copy the vector table to RAM only if uVisor is not in use. */
be_bryan 0:b74591d5ab33 352 #if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
be_bryan 0:b74591d5ab33 353 mbed_cpy_nvic();
be_bryan 0:b74591d5ab33 354 #endif
be_bryan 0:b74591d5ab33 355 mbed_sdk_init();
be_bryan 0:b74591d5ab33 356 osKernelInitialize();
be_bryan 0:b74591d5ab33 357 mbed_start_main();
be_bryan 0:b74591d5ab33 358 for (;;);
be_bryan 0:b74591d5ab33 359 }
be_bryan 0:b74591d5ab33 360
be_bryan 0:b74591d5ab33 361 void $Sub$$__cpp_initialize__aeabi_(void)
be_bryan 0:b74591d5ab33 362 {
be_bryan 0:b74591d5ab33 363 /* This should invoke C++ initializers prior _main_init, we keep this empty and
be_bryan 0:b74591d5ab33 364 * invoke them after _main_init, when the RTX is already initilized.
be_bryan 0:b74591d5ab33 365 */
be_bryan 0:b74591d5ab33 366 }
be_bryan 0:b74591d5ab33 367
be_bryan 0:b74591d5ab33 368 void pre_main()
be_bryan 0:b74591d5ab33 369 {
be_bryan 0:b74591d5ab33 370 singleton_mutex_attr.name = "singleton_mutex";
be_bryan 0:b74591d5ab33 371 singleton_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 372 singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
be_bryan 0:b74591d5ab33 373 singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
be_bryan 0:b74591d5ab33 374 singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
be_bryan 0:b74591d5ab33 375
be_bryan 0:b74591d5ab33 376 $Super$$__cpp_initialize__aeabi_();
be_bryan 0:b74591d5ab33 377 main();
be_bryan 0:b74591d5ab33 378 }
be_bryan 0:b74591d5ab33 379
be_bryan 0:b74591d5ab33 380 #else /******************** ARMC ********************/
be_bryan 0:b74591d5ab33 381
be_bryan 0:b74591d5ab33 382 #include <rt_misc.h>
be_bryan 0:b74591d5ab33 383 extern __value_in_regs struct __argc_argv __rt_lib_init(unsigned heapbase, unsigned heaptop);
be_bryan 0:b74591d5ab33 384 extern __value_in_regs struct __initial_stackheap __user_setup_stackheap(void);
be_bryan 0:b74591d5ab33 385 extern void _platform_post_stackheap_init (void);
be_bryan 0:b74591d5ab33 386 extern int main(int argc, char* argv[]);
be_bryan 0:b74591d5ab33 387
be_bryan 0:b74591d5ab33 388 void pre_main (void)
be_bryan 0:b74591d5ab33 389 {
be_bryan 0:b74591d5ab33 390 singleton_mutex_attr.name = "singleton_mutex";
be_bryan 0:b74591d5ab33 391 singleton_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 392 singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
be_bryan 0:b74591d5ab33 393 singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
be_bryan 0:b74591d5ab33 394 singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
be_bryan 0:b74591d5ab33 395
be_bryan 0:b74591d5ab33 396 __rt_lib_init((unsigned)mbed_heap_start, (unsigned)(mbed_heap_start + mbed_heap_size));
be_bryan 0:b74591d5ab33 397
be_bryan 0:b74591d5ab33 398 main(0, NULL);
be_bryan 0:b74591d5ab33 399 }
be_bryan 0:b74591d5ab33 400
be_bryan 0:b74591d5ab33 401 /* The single memory model is checking for stack collision at run time, verifing
be_bryan 0:b74591d5ab33 402 that the heap pointer is underneath the stack pointer.
be_bryan 0:b74591d5ab33 403 With the RTOS there is not only one stack above the heap, there are multiple
be_bryan 0:b74591d5ab33 404 stacks and some of them are underneath the heap pointer.
be_bryan 0:b74591d5ab33 405 */
be_bryan 0:b74591d5ab33 406 #if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
be_bryan 0:b74591d5ab33 407 __asm(".global __use_two_region_memory\n\t");
be_bryan 0:b74591d5ab33 408 __asm(".global __use_no_semihosting\n\t");
be_bryan 0:b74591d5ab33 409 #else
be_bryan 0:b74591d5ab33 410 #pragma import(__use_two_region_memory)
be_bryan 0:b74591d5ab33 411 #endif
be_bryan 0:b74591d5ab33 412
be_bryan 0:b74591d5ab33 413 /* Called by the C library */
be_bryan 0:b74591d5ab33 414 void __rt_entry (void) {
be_bryan 0:b74591d5ab33 415 __user_setup_stackheap();
be_bryan 0:b74591d5ab33 416 mbed_set_stack_heap();
be_bryan 0:b74591d5ab33 417 /* Copy the vector table to RAM only if uVisor is not in use. */
be_bryan 0:b74591d5ab33 418 #if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
be_bryan 0:b74591d5ab33 419 mbed_cpy_nvic();
be_bryan 0:b74591d5ab33 420 #endif
be_bryan 0:b74591d5ab33 421 mbed_sdk_init();
be_bryan 0:b74591d5ab33 422 _platform_post_stackheap_init();
be_bryan 0:b74591d5ab33 423 mbed_start_main();
be_bryan 0:b74591d5ab33 424 }
be_bryan 0:b74591d5ab33 425
be_bryan 0:b74591d5ab33 426 typedef void *mutex;
be_bryan 0:b74591d5ab33 427 mutex _static_mutexes[OS_MUTEX_NUM] = {NULL};
be_bryan 0:b74591d5ab33 428
be_bryan 0:b74591d5ab33 429 /* ARM toolchain requires dynamically created mutexes to enforce thread safety. There's
be_bryan 0:b74591d5ab33 430 up to 8 static mutexes, protecting atexit, signalinit, stdin, stdout, stderr, stream_list,
be_bryan 0:b74591d5ab33 431 fp_trap_init and the heap. Additionally for each call to fopen one extra mutex will be
be_bryan 0:b74591d5ab33 432 created.
be_bryan 0:b74591d5ab33 433 mbed OS provides a RTX pool for 8 mutexes, to satisfy the static requirements. All
be_bryan 0:b74591d5ab33 434 additional mutexes will be allocated on the heap. We can't use the heap allocation for
be_bryan 0:b74591d5ab33 435 all the required mutexes, as the heap operations also require a mutex. We don't need to
be_bryan 0:b74591d5ab33 436 worry about freeing the allocated memory as library mutexes are only freed when the
be_bryan 0:b74591d5ab33 437 application finishes executing.
be_bryan 0:b74591d5ab33 438 */
be_bryan 0:b74591d5ab33 439 int _mutex_initialize(mutex *m)
be_bryan 0:b74591d5ab33 440 {
be_bryan 0:b74591d5ab33 441 osMutexAttr_t attr;
be_bryan 0:b74591d5ab33 442 memset(&attr, 0, sizeof(attr));
be_bryan 0:b74591d5ab33 443 attr.name = "ARM toolchain mutex";
be_bryan 0:b74591d5ab33 444 attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 445
be_bryan 0:b74591d5ab33 446 mutex *slot = NULL;
be_bryan 0:b74591d5ab33 447 core_util_critical_section_enter();
be_bryan 0:b74591d5ab33 448 for (int i = 0; i < OS_MUTEX_NUM; i++) {
be_bryan 0:b74591d5ab33 449 if (_static_mutexes[i] == NULL) {
be_bryan 0:b74591d5ab33 450 _static_mutexes[i] = (mutex)-1; // dummy value to reserve slot
be_bryan 0:b74591d5ab33 451 slot = &_static_mutexes[i];
be_bryan 0:b74591d5ab33 452 break;
be_bryan 0:b74591d5ab33 453 }
be_bryan 0:b74591d5ab33 454 }
be_bryan 0:b74591d5ab33 455 core_util_critical_section_exit();
be_bryan 0:b74591d5ab33 456
be_bryan 0:b74591d5ab33 457 if (slot != NULL) {
be_bryan 0:b74591d5ab33 458 *m = osMutexNew(&attr);
be_bryan 0:b74591d5ab33 459 *slot = *m;
be_bryan 0:b74591d5ab33 460 if (*m != NULL) {
be_bryan 0:b74591d5ab33 461 return 1;
be_bryan 0:b74591d5ab33 462 }
be_bryan 0:b74591d5ab33 463 }
be_bryan 0:b74591d5ab33 464
be_bryan 0:b74591d5ab33 465 /* Mutex pool exhausted, try using HEAP */
be_bryan 0:b74591d5ab33 466 attr.cb_size = sizeof(mbed_rtos_storage_mutex_t);
be_bryan 0:b74591d5ab33 467 attr.cb_mem = (void*)malloc(attr.cb_size);
be_bryan 0:b74591d5ab33 468 if (attr.cb_mem == NULL) {
be_bryan 0:b74591d5ab33 469 osRtxErrorNotify(osRtxErrorClibSpace, m);
be_bryan 0:b74591d5ab33 470 return 0;
be_bryan 0:b74591d5ab33 471 }
be_bryan 0:b74591d5ab33 472
be_bryan 0:b74591d5ab33 473 *m = osMutexNew(&attr);
be_bryan 0:b74591d5ab33 474 if (*m == NULL) {
be_bryan 0:b74591d5ab33 475 osRtxErrorNotify(osRtxErrorClibMutex, m);
be_bryan 0:b74591d5ab33 476 return 0;
be_bryan 0:b74591d5ab33 477 }
be_bryan 0:b74591d5ab33 478
be_bryan 0:b74591d5ab33 479 return 1;
be_bryan 0:b74591d5ab33 480 }
be_bryan 0:b74591d5ab33 481
be_bryan 0:b74591d5ab33 482 void _mutex_free(mutex *m) {
be_bryan 0:b74591d5ab33 483 mutex *slot = NULL;
be_bryan 0:b74591d5ab33 484 core_util_critical_section_enter();
be_bryan 0:b74591d5ab33 485 for (int i = 0; i < OS_MUTEX_NUM; i++) {
be_bryan 0:b74591d5ab33 486 if (_static_mutexes[i] == *m) {
be_bryan 0:b74591d5ab33 487 slot = &_static_mutexes[i];
be_bryan 0:b74591d5ab33 488 break;
be_bryan 0:b74591d5ab33 489 }
be_bryan 0:b74591d5ab33 490 }
be_bryan 0:b74591d5ab33 491 core_util_critical_section_exit();
be_bryan 0:b74591d5ab33 492
be_bryan 0:b74591d5ab33 493 osMutexDelete(*m);
be_bryan 0:b74591d5ab33 494
be_bryan 0:b74591d5ab33 495 // if no slot reserved for mutex, must have been dynamically allocated
be_bryan 0:b74591d5ab33 496 if (!slot) {
be_bryan 0:b74591d5ab33 497 free(m);
be_bryan 0:b74591d5ab33 498 } else {
be_bryan 0:b74591d5ab33 499 *slot = NULL;
be_bryan 0:b74591d5ab33 500 }
be_bryan 0:b74591d5ab33 501
be_bryan 0:b74591d5ab33 502 }
be_bryan 0:b74591d5ab33 503
be_bryan 0:b74591d5ab33 504 #endif /* ARMC */
be_bryan 0:b74591d5ab33 505 #elif defined (__GNUC__) /******************** GCC ********************/
be_bryan 0:b74591d5ab33 506
be_bryan 0:b74591d5ab33 507 extern int main(int argc, char* argv[]);
be_bryan 0:b74591d5ab33 508 extern void __libc_init_array (void);
be_bryan 0:b74591d5ab33 509 extern int __real_main(void);
be_bryan 0:b74591d5ab33 510
be_bryan 0:b74591d5ab33 511 osMutexId_t malloc_mutex_id;
be_bryan 0:b74591d5ab33 512 mbed_rtos_storage_mutex_t malloc_mutex_obj;
be_bryan 0:b74591d5ab33 513 osMutexAttr_t malloc_mutex_attr;
be_bryan 0:b74591d5ab33 514
be_bryan 0:b74591d5ab33 515 osMutexId_t env_mutex_id;
be_bryan 0:b74591d5ab33 516 mbed_rtos_storage_mutex_t env_mutex_obj;
be_bryan 0:b74591d5ab33 517 osMutexAttr_t env_mutex_attr;
be_bryan 0:b74591d5ab33 518
be_bryan 0:b74591d5ab33 519 #ifdef FEATURE_UVISOR
be_bryan 0:b74591d5ab33 520 #include "uvisor-lib/uvisor-lib.h"
be_bryan 0:b74591d5ab33 521 #endif/* FEATURE_UVISOR */
be_bryan 0:b74591d5ab33 522
be_bryan 0:b74591d5ab33 523 int __wrap_main(void) {
be_bryan 0:b74591d5ab33 524 mbed_main();
be_bryan 0:b74591d5ab33 525 return __real_main();
be_bryan 0:b74591d5ab33 526 }
be_bryan 0:b74591d5ab33 527
be_bryan 0:b74591d5ab33 528 void pre_main(void)
be_bryan 0:b74591d5ab33 529 {
be_bryan 0:b74591d5ab33 530 singleton_mutex_attr.name = "singleton_mutex";
be_bryan 0:b74591d5ab33 531 singleton_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 532 singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
be_bryan 0:b74591d5ab33 533 singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
be_bryan 0:b74591d5ab33 534 singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
be_bryan 0:b74591d5ab33 535
be_bryan 0:b74591d5ab33 536 malloc_mutex_attr.name = "malloc_mutex";
be_bryan 0:b74591d5ab33 537 malloc_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 538 malloc_mutex_attr.cb_size = sizeof(malloc_mutex_obj);
be_bryan 0:b74591d5ab33 539 malloc_mutex_attr.cb_mem = &malloc_mutex_obj;
be_bryan 0:b74591d5ab33 540 malloc_mutex_id = osMutexNew(&malloc_mutex_attr);
be_bryan 0:b74591d5ab33 541
be_bryan 0:b74591d5ab33 542 env_mutex_attr.name = "env_mutex";
be_bryan 0:b74591d5ab33 543 env_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 544 env_mutex_attr.cb_size = sizeof(env_mutex_obj);
be_bryan 0:b74591d5ab33 545 env_mutex_attr.cb_mem = &env_mutex_obj;
be_bryan 0:b74591d5ab33 546 env_mutex_id = osMutexNew(&env_mutex_attr);
be_bryan 0:b74591d5ab33 547
be_bryan 0:b74591d5ab33 548 __libc_init_array();
be_bryan 0:b74591d5ab33 549
be_bryan 0:b74591d5ab33 550 main(0, NULL);
be_bryan 0:b74591d5ab33 551 }
be_bryan 0:b74591d5ab33 552
be_bryan 0:b74591d5ab33 553 void software_init_hook(void)
be_bryan 0:b74591d5ab33 554 {
be_bryan 0:b74591d5ab33 555 mbed_set_stack_heap();
be_bryan 0:b74591d5ab33 556 /* Copy the vector table to RAM only if uVisor is not in use. */
be_bryan 0:b74591d5ab33 557 #if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
be_bryan 0:b74591d5ab33 558 mbed_cpy_nvic();
be_bryan 0:b74591d5ab33 559 #endif
be_bryan 0:b74591d5ab33 560 mbed_sdk_init();
be_bryan 0:b74591d5ab33 561 osKernelInitialize();
be_bryan 0:b74591d5ab33 562 /* uvisor_lib_init calls RTOS functions, so must be called after the RTOS has
be_bryan 0:b74591d5ab33 563 * been initialized. */
be_bryan 0:b74591d5ab33 564 #ifdef FEATURE_UVISOR
be_bryan 0:b74591d5ab33 565 int return_code;
be_bryan 0:b74591d5ab33 566
be_bryan 0:b74591d5ab33 567 return_code = uvisor_lib_init();
be_bryan 0:b74591d5ab33 568 if (return_code) {
be_bryan 0:b74591d5ab33 569 mbed_die();
be_bryan 0:b74591d5ab33 570 }
be_bryan 0:b74591d5ab33 571 #endif/* FEATURE_UVISOR */
be_bryan 0:b74591d5ab33 572 mbed_start_main();
be_bryan 0:b74591d5ab33 573 }
be_bryan 0:b74591d5ab33 574
be_bryan 0:b74591d5ab33 575 /* Opaque declaration of _reent structure */
be_bryan 0:b74591d5ab33 576 struct _reent;
be_bryan 0:b74591d5ab33 577
be_bryan 0:b74591d5ab33 578 void __rtos_malloc_lock( struct _reent *_r )
be_bryan 0:b74591d5ab33 579 {
be_bryan 0:b74591d5ab33 580 osMutexAcquire(malloc_mutex_id, osWaitForever);
be_bryan 0:b74591d5ab33 581 }
be_bryan 0:b74591d5ab33 582
be_bryan 0:b74591d5ab33 583 void __rtos_malloc_unlock( struct _reent *_r )
be_bryan 0:b74591d5ab33 584 {
be_bryan 0:b74591d5ab33 585 osMutexRelease(malloc_mutex_id);
be_bryan 0:b74591d5ab33 586 }
be_bryan 0:b74591d5ab33 587
be_bryan 0:b74591d5ab33 588 void __rtos_env_lock( struct _reent *_r )
be_bryan 0:b74591d5ab33 589 {
be_bryan 0:b74591d5ab33 590 osMutexAcquire(env_mutex_id, osWaitForever);
be_bryan 0:b74591d5ab33 591 }
be_bryan 0:b74591d5ab33 592
be_bryan 0:b74591d5ab33 593 void __rtos_env_unlock( struct _reent *_r )
be_bryan 0:b74591d5ab33 594 {
be_bryan 0:b74591d5ab33 595 osMutexRelease(env_mutex_id);
be_bryan 0:b74591d5ab33 596 }
be_bryan 0:b74591d5ab33 597
be_bryan 0:b74591d5ab33 598 #endif
be_bryan 0:b74591d5ab33 599
be_bryan 0:b74591d5ab33 600 #if defined(__ICCARM__) /******************** IAR ********************/
be_bryan 0:b74591d5ab33 601
be_bryan 0:b74591d5ab33 602 extern void* __vector_table;
be_bryan 0:b74591d5ab33 603 extern int __low_level_init(void);
be_bryan 0:b74591d5ab33 604 extern void __iar_data_init3(void);
be_bryan 0:b74591d5ab33 605 extern __weak void __iar_init_core( void );
be_bryan 0:b74591d5ab33 606 extern __weak void __iar_init_vfp( void );
be_bryan 0:b74591d5ab33 607 extern void __iar_dynamic_initialization(void);
be_bryan 0:b74591d5ab33 608 extern void mbed_sdk_init(void);
be_bryan 0:b74591d5ab33 609 extern int main(void);
be_bryan 0:b74591d5ab33 610 extern void exit(int arg);
be_bryan 0:b74591d5ab33 611
be_bryan 0:b74591d5ab33 612 static uint8_t low_level_init_needed;
be_bryan 0:b74591d5ab33 613
be_bryan 0:b74591d5ab33 614 void pre_main(void)
be_bryan 0:b74591d5ab33 615 {
be_bryan 0:b74591d5ab33 616 singleton_mutex_attr.name = "singleton_mutex";
be_bryan 0:b74591d5ab33 617 singleton_mutex_attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 618 singleton_mutex_attr.cb_size = sizeof(singleton_mutex_obj);
be_bryan 0:b74591d5ab33 619 singleton_mutex_attr.cb_mem = &singleton_mutex_obj;
be_bryan 0:b74591d5ab33 620 singleton_mutex_id = osMutexNew(&singleton_mutex_attr);
be_bryan 0:b74591d5ab33 621
be_bryan 0:b74591d5ab33 622 #if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ >= 8000000)
be_bryan 0:b74591d5ab33 623 __iar_Initlocks();
be_bryan 0:b74591d5ab33 624 #endif
be_bryan 0:b74591d5ab33 625
be_bryan 0:b74591d5ab33 626 if (low_level_init_needed) {
be_bryan 0:b74591d5ab33 627 __iar_dynamic_initialization();
be_bryan 0:b74591d5ab33 628 }
be_bryan 0:b74591d5ab33 629
be_bryan 0:b74591d5ab33 630 mbed_main();
be_bryan 0:b74591d5ab33 631 main();
be_bryan 0:b74591d5ab33 632 }
be_bryan 0:b74591d5ab33 633
be_bryan 0:b74591d5ab33 634 #pragma required=__vector_table
be_bryan 0:b74591d5ab33 635 void __iar_program_start( void )
be_bryan 0:b74591d5ab33 636 {
be_bryan 0:b74591d5ab33 637 __iar_init_core();
be_bryan 0:b74591d5ab33 638 __iar_init_vfp();
be_bryan 0:b74591d5ab33 639
be_bryan 0:b74591d5ab33 640 uint8_t low_level_init_needed_local;
be_bryan 0:b74591d5ab33 641
be_bryan 0:b74591d5ab33 642 low_level_init_needed_local = __low_level_init();
be_bryan 0:b74591d5ab33 643 if (low_level_init_needed_local) {
be_bryan 0:b74591d5ab33 644 __iar_data_init3();
be_bryan 0:b74591d5ab33 645
be_bryan 0:b74591d5ab33 646 /* Copy the vector table to RAM only if uVisor is not in use. */
be_bryan 0:b74591d5ab33 647 #if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
be_bryan 0:b74591d5ab33 648 mbed_cpy_nvic();
be_bryan 0:b74591d5ab33 649 #endif
be_bryan 0:b74591d5ab33 650 mbed_sdk_init();
be_bryan 0:b74591d5ab33 651 }
be_bryan 0:b74591d5ab33 652
be_bryan 0:b74591d5ab33 653 mbed_set_stack_heap();
be_bryan 0:b74591d5ab33 654
be_bryan 0:b74591d5ab33 655 /* Store in a global variable after RAM has been initialized */
be_bryan 0:b74591d5ab33 656 low_level_init_needed = low_level_init_needed_local;
be_bryan 0:b74591d5ab33 657
be_bryan 0:b74591d5ab33 658 osKernelInitialize();
be_bryan 0:b74591d5ab33 659
be_bryan 0:b74591d5ab33 660 mbed_start_main();
be_bryan 0:b74591d5ab33 661 }
be_bryan 0:b74591d5ab33 662
be_bryan 0:b74591d5ab33 663 /* Thread safety */
be_bryan 0:b74591d5ab33 664 static osMutexId_t std_mutex_id_sys[_MAX_LOCK] = {0};
be_bryan 0:b74591d5ab33 665 static mbed_rtos_storage_mutex_t std_mutex_sys[_MAX_LOCK] = {0};
be_bryan 0:b74591d5ab33 666 #define _FOPEN_MAX 10
be_bryan 0:b74591d5ab33 667 static osMutexId_t std_mutex_id_file[_FOPEN_MAX] = {0};
be_bryan 0:b74591d5ab33 668 static mbed_rtos_storage_mutex_t std_mutex_file[_FOPEN_MAX] = {0};
be_bryan 0:b74591d5ab33 669
be_bryan 0:b74591d5ab33 670 void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */
be_bryan 0:b74591d5ab33 671 {
be_bryan 0:b74591d5ab33 672 osMutexAttr_t attr;
be_bryan 0:b74591d5ab33 673 uint32_t index;
be_bryan 0:b74591d5ab33 674 for (index = 0; index < _MAX_LOCK; index++) {
be_bryan 0:b74591d5ab33 675 if (0 == std_mutex_id_sys[index]) {
be_bryan 0:b74591d5ab33 676 attr.name = "system_mutex";
be_bryan 0:b74591d5ab33 677 attr.cb_mem = &std_mutex_sys[index];
be_bryan 0:b74591d5ab33 678 attr.cb_size = sizeof(std_mutex_sys[index]);
be_bryan 0:b74591d5ab33 679 attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 680 std_mutex_id_sys[index] = osMutexNew(&attr);
be_bryan 0:b74591d5ab33 681 *mutex = (__iar_Rmtx*)&std_mutex_id_sys[index];
be_bryan 0:b74591d5ab33 682 return;
be_bryan 0:b74591d5ab33 683 }
be_bryan 0:b74591d5ab33 684 }
be_bryan 0:b74591d5ab33 685
be_bryan 0:b74591d5ab33 686 /* This should never happen */
be_bryan 0:b74591d5ab33 687 error("Not enough mutexes\n");
be_bryan 0:b74591d5ab33 688 }
be_bryan 0:b74591d5ab33 689
be_bryan 0:b74591d5ab33 690 void __iar_system_Mtxdst(__iar_Rmtx *mutex) /* Destroy a system lock */
be_bryan 0:b74591d5ab33 691 {
be_bryan 0:b74591d5ab33 692 osMutexDelete(*(osMutexId_t*)*mutex);
be_bryan 0:b74591d5ab33 693 *mutex = 0;
be_bryan 0:b74591d5ab33 694 }
be_bryan 0:b74591d5ab33 695
be_bryan 0:b74591d5ab33 696 void __iar_system_Mtxlock(__iar_Rmtx *mutex) /* Lock a system lock */
be_bryan 0:b74591d5ab33 697 {
be_bryan 0:b74591d5ab33 698 osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever);
be_bryan 0:b74591d5ab33 699 }
be_bryan 0:b74591d5ab33 700
be_bryan 0:b74591d5ab33 701 void __iar_system_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a system lock */
be_bryan 0:b74591d5ab33 702 {
be_bryan 0:b74591d5ab33 703 osMutexRelease(*(osMutexId_t*)*mutex);
be_bryan 0:b74591d5ab33 704 }
be_bryan 0:b74591d5ab33 705
be_bryan 0:b74591d5ab33 706 void __iar_file_Mtxinit(__iar_Rmtx *mutex) /* Initialize a file lock */
be_bryan 0:b74591d5ab33 707 {
be_bryan 0:b74591d5ab33 708 osMutexAttr_t attr;
be_bryan 0:b74591d5ab33 709 uint32_t index;
be_bryan 0:b74591d5ab33 710 for (index = 0; index < _FOPEN_MAX; index++) {
be_bryan 0:b74591d5ab33 711 if (0 == std_mutex_id_file[index]) {
be_bryan 0:b74591d5ab33 712 attr.name = "file_mutex";
be_bryan 0:b74591d5ab33 713 attr.cb_mem = &std_mutex_file[index];
be_bryan 0:b74591d5ab33 714 attr.cb_size = sizeof(std_mutex_file[index]);
be_bryan 0:b74591d5ab33 715 attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
be_bryan 0:b74591d5ab33 716 std_mutex_id_file[index] = osMutexNew(&attr);
be_bryan 0:b74591d5ab33 717 *mutex = (__iar_Rmtx*)&std_mutex_id_file[index];
be_bryan 0:b74591d5ab33 718 return;
be_bryan 0:b74591d5ab33 719 }
be_bryan 0:b74591d5ab33 720 }
be_bryan 0:b74591d5ab33 721 /* The variable _FOPEN_MAX needs to be increased */
be_bryan 0:b74591d5ab33 722 error("Not enough mutexes\n");
be_bryan 0:b74591d5ab33 723 }
be_bryan 0:b74591d5ab33 724
be_bryan 0:b74591d5ab33 725 void __iar_file_Mtxdst(__iar_Rmtx *mutex) /* Destroy a file lock */
be_bryan 0:b74591d5ab33 726 {
be_bryan 0:b74591d5ab33 727 osMutexDelete(*(osMutexId_t*)*mutex);
be_bryan 0:b74591d5ab33 728 *mutex = 0;
be_bryan 0:b74591d5ab33 729 }
be_bryan 0:b74591d5ab33 730
be_bryan 0:b74591d5ab33 731 void __iar_file_Mtxlock(__iar_Rmtx *mutex) /* Lock a file lock */
be_bryan 0:b74591d5ab33 732 {
be_bryan 0:b74591d5ab33 733 osMutexAcquire(*(osMutexId_t*)*mutex, osWaitForever);
be_bryan 0:b74591d5ab33 734 }
be_bryan 0:b74591d5ab33 735
be_bryan 0:b74591d5ab33 736 void __iar_file_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a file lock */
be_bryan 0:b74591d5ab33 737 {
be_bryan 0:b74591d5ab33 738 osMutexRelease(*(osMutexId_t*)*mutex);
be_bryan 0:b74591d5ab33 739 }
be_bryan 0:b74591d5ab33 740
be_bryan 0:b74591d5ab33 741 #endif