Official mbed Real Time Operating System based on the RTX implementation of the CMSIS-RTOS API open standard.
Dependents: denki-yohou_b TestY201 Network-RTOS NTPClient_HelloWorld ... more
Deprecated
This is the mbed 2 rtos library. mbed OS 5 integrates the mbed library with mbed-rtos. With this, we have provided thread safety for all mbed APIs. If you'd like to learn about using mbed OS 5, please see the docs.
Diff: rtx/TARGET_CORTEX_M/RTX_CM_lib.h
- Revision:
- 120:4dc938e301cc
- Parent:
- 119:19af2d39a542
- Child:
- 121:3da5f554d8bf
--- a/rtx/TARGET_CORTEX_M/RTX_CM_lib.h Wed Aug 10 16:09:20 2016 +0100 +++ b/rtx/TARGET_CORTEX_M/RTX_CM_lib.h Thu Aug 18 14:38:56 2016 +0100 @@ -350,7 +350,46 @@ /* Main Thread definition */ extern void pre_main (void); -osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, 0U, NULL}; + +#if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832) +static uint32_t thread_stack_main[DEFAULT_STACK_SIZE / sizeof(uint32_t)]; +#else +static uint32_t thread_stack_main[DEFAULT_STACK_SIZE * 2 / sizeof(uint32_t)]; +#endif +osThreadDef_t os_thread_def_main = {(os_pthread)pre_main, osPriorityNormal, 1U, sizeof(thread_stack_main), thread_stack_main}; + +/* + * IAR Default Memory layout notes: + * -Heap defined by "HEAP" region in .icf file + * -Interrupt stack defined by "CSTACK" region in .icf file + * -Value INITIAL_SP is ignored + * + * IAR Custom Memory layout notes: + * -There is no custom layout available for IAR - everything must be defined in + * the .icf file and use the default layout + * + * + * GCC Default Memory layout notes: + * -Block of memory from symbol __end__ to define INITIAL_SP used to setup interrupt + * stack and heap in the function set_stack_heap() + * -ISR_STACK_SIZE can be overridden to be larger or smaller + * + * GCC Custom Memory layout notes: + * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE + * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE + * + * + * ARM Memory layout + * -Block of memory from end of region "RW_IRAM1" to define INITIAL_SP used to setup interrupt + * stack and heap in the function set_stack_heap() + * -ISR_STACK_SIZE can be overridden to be larger or smaller + * + * ARM Custom Memory layout notes: + * -Heap can be explicitly placed by defining both HEAP_START and HEAP_SIZE + * -Interrupt stack can be explicitly placed by defining both ISR_STACK_START and ISR_STACK_SIZE + * + */ + // This define should be probably moved to the CMSIS layer #if defined(TARGET_LPC1768) @@ -381,12 +420,18 @@ #define INITIAL_SP (0x20003000UL) #elif defined(TARGET_K64F) -#if defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED) +#if defined(__GNUC__) && !defined(__CC_ARM) /* GCC */ extern uint32_t __StackTop[]; #define INITIAL_SP (__StackTop) #else #define INITIAL_SP (0x20030000UL) #endif +#if defined(__CC_ARM) || defined(__GNUC__) +#define ISR_STACK_SIZE (0x1000) +#endif + +#elif defined(TARGET_K66F) +#define INITIAL_SP (0x20030000UL) #elif defined(TARGET_K22F) #define INITIAL_SP (0x20010000UL) @@ -534,19 +579,25 @@ #elif defined(TARGET_NUMAKER_PFM_NUC472) # if defined(__CC_ARM) -extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit[]; -extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[]; -#define INITIAL_SP ((uint32_t) Image$$ARM_LIB_STACK$$ZI$$Limit) -#define FINAL_SP ((uint32_t) Image$$ARM_LIB_STACK$$ZI$$Base) +extern uint32_t Image$$ARM_LIB_HEAP$$Base[]; +extern uint32_t Image$$ARM_LIB_HEAP$$Length[]; +extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[]; +extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Length[]; +#define HEAP_START ((unsigned char*) Image$$ARM_LIB_HEAP$$Base) +#define HEAP_SIZE ((uint32_t) Image$$ARM_LIB_HEAP$$Length) +#define ISR_STACK_START ((unsigned char*)Image$$ARM_LIB_STACK$$ZI$$Base) +#define ISR_STACK_SIZE ((uint32_t)Image$$ARM_LIB_STACK$$ZI$$Length) # elif defined(__GNUC__) extern uint32_t __StackTop[]; extern uint32_t __StackLimit[]; -#define INITIAL_SP ((uint32_t) __StackTop) -#define FINAL_SP ((uint32_t) __StackLimit) +extern uint32_t __end__[]; +extern uint32_t __HeapLimit[]; +#define HEAP_START ((unsigned char*)__end__) +#define HEAP_SIZE ((uint32_t)((uint32_t)__HeapLimit - (uint32_t)HEAP_START)) +#define ISR_STACK_START ((unsigned char*)__StackLimit) +#define ISR_STACK_SIZE ((uint32_t)((uint32_t)__StackTop - (uint32_t)__StackLimit)) # elif defined(__ICCARM__) -#pragma section="CSTACK" -#define INITIAL_SP ((uint32_t) __section_end("CSTACK")) -#define FINAL_SP ((uint32_t) __section_begin("CSTACK")) +/* No region declarations needed */ # else #error "no toolchain defined" # endif @@ -556,48 +607,90 @@ #endif -#ifdef __CC_ARM -#if defined(TARGET_NUMAKER_PFM_NUC472) -extern uint32_t Image$$ARM_LIB_HEAP$$Base[]; -#define HEAP_START ((uint32_t) Image$$ARM_LIB_HEAP$$Base) -#else -extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[]; -#define HEAP_START (Image$$RW_IRAM1$$ZI$$Limit) +extern unsigned char *mbed_heap_start; +extern uint32_t mbed_heap_size; + +unsigned char *mbed_stack_isr_start = 0; +uint32_t mbed_stack_isr_size = 0; + +/* + * Sanity check values + */ +#if defined(__ICCARM__) && \ + (defined(HEAP_START) || defined(HEAP_SIZE) || \ + defined(ISR_STACK_START) && defined(ISR_STACK_SIZE)) + #error "No custom layout allowed for IAR. Use .icf file instead" +#endif +#if defined(HEAP_START) && !defined(HEAP_SIZE) + #error "HEAP_SIZE must be defined if HEAP_START is defined" #endif -#elif defined(__GNUC__) -extern uint32_t __end__[]; -#define HEAP_START (__end__) -#elif defined(__ICCARM__) -#pragma section="HEAP" -#define HEAP_END (void *)__section_end("HEAP") +#if defined(ISR_STACK_START) && !defined(ISR_STACK_SIZE) + #error "ISR_STACK_SIZE must be defined if ISR_STACK_START is defined" +#endif +#if defined(HEAP_SIZE) && !defined(HEAP_START) + #error "HEAP_START must be defined if HEAP_SIZE is defined" +#endif + +/* Interrupt stack and heap always defined for IAR + * Main thread defined here + */ +#if defined(__ICCARM__) + #pragma section="CSTACK" + #pragma section="HEAP" + #define HEAP_START ((unsigned char*)__section_begin("HEAP")) + #define HEAP_SIZE ((uint32_t)__section_size("HEAP")) + #define ISR_STACK_START ((unsigned char*)__section_begin("CSTACK")) + #define ISR_STACK_SIZE ((uint32_t)__section_size("CSTACK")) #endif -void set_main_stack(void) { -#if defined(TARGET_NUMAKER_PFM_NUC472) - // Scheduler stack: OS_MAINSTKSIZE words - // Main thread stack: Reserved stack size - OS_MAINSTKSIZE words - os_thread_def_main.stack_pointer = (uint32_t *) FINAL_SP; - os_thread_def_main.stacksize = (uint32_t) INITIAL_SP - (uint32_t) FINAL_SP - OS_MAINSTKSIZE * 4; -#else - uint32_t interrupt_stack_size = ((uint32_t)OS_MAINSTKSIZE * 4); -#if defined(__ICCARM__) - /* For IAR heap is defined .icf file */ - uint32_t main_stack_size = ((uint32_t)INITIAL_SP - (uint32_t)HEAP_END) - interrupt_stack_size; +/* Define heap region if it has not been defined already */ +#if !defined(HEAP_START) + #if defined(__ICCARM__) + #error "Heap should already be defined for IAR" + #elif defined(__CC_ARM) + extern uint32_t Image$$RW_IRAM1$$ZI$$Limit[]; + #define HEAP_START ((unsigned char*)Image$$RW_IRAM1$$ZI$$Limit) + #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START)) + #elif defined(__GNUC__) + extern uint32_t __end__[]; + #define HEAP_START ((unsigned char*)__end__) + #define HEAP_SIZE ((uint32_t)((uint32_t)INITIAL_SP - (uint32_t)HEAP_START)) + #endif +#endif + +/* Define stack sizes if they haven't been set already */ +#if !defined(ISR_STACK_SIZE) + #define ISR_STACK_SIZE ((uint32_t)OS_MAINSTKSIZE * 4) +#endif + +/* + * set_stack_heap purpose is to set the following variables: + * -mbed_heap_start + * -mbed_heap_size + * -mbed_stack_isr_start + * -mbed_stack_isr_size + * + * Along with setting up os_thread_def_main + */ +void set_stack_heap(void) { + + unsigned char *free_start = HEAP_START; + uint32_t free_size = HEAP_SIZE; + +#ifdef ISR_STACK_START + /* Interrupt stack explicitly specified */ + mbed_stack_isr_size = ISR_STACK_SIZE; + mbed_stack_isr_start = ISR_STACK_START; #else - /* For ARM , uARM, or GCC_ARM , heap can grow and reach main stack */ - uint32_t heap_plus_stack_size = ((uint32_t)INITIAL_SP - (uint32_t)HEAP_START) - interrupt_stack_size; - // Main thread's stack is 1/4 of the heap - uint32_t main_stack_size = heap_plus_stack_size/4; + /* Interrupt stack - reserve space at the end of the free block */ + mbed_stack_isr_size = ISR_STACK_SIZE; + mbed_stack_isr_start = free_start + free_size - mbed_stack_isr_size; + free_size -= mbed_stack_isr_size; #endif - // The main thread must be 4 byte aligned - uint32_t main_stack_start = ((uint32_t)INITIAL_SP - interrupt_stack_size - main_stack_size) & ~0x7; - // That is the bottom of the main stack block: no collision detection - os_thread_def_main.stack_pointer = (uint32_t*)main_stack_start; - - // Leave OS_MAINSTKSIZE words for the scheduler and interrupts - os_thread_def_main.stacksize = main_stack_size; -#endif + /* Heap - everything else */ + mbed_heap_size = free_size; + mbed_heap_start = free_start; } #if defined (__CC_ARM) @@ -611,7 +704,7 @@ void _main_init (void) { osKernelInitialize(); #ifdef __MBED_CMSIS_RTOS_CM - set_main_stack(); + set_stack_heap(); #endif osThreadCreate(&os_thread_def_main, NULL); osKernelStart(); @@ -633,15 +726,12 @@ #else -void * armcc_heap_base; -void * armcc_heap_top; - int main(void); void pre_main (void) { singleton_mutex_id = osMutexCreate(osMutex(singleton_mutex)); - __rt_lib_init((unsigned)armcc_heap_base, (unsigned)armcc_heap_top); + __rt_lib_init((unsigned)mbed_heap_start, (unsigned)(mbed_heap_start + mbed_heap_size)); main(); } @@ -656,12 +746,10 @@ __asm void __rt_entry (void) { IMPORT __user_setup_stackheap - IMPORT armcc_heap_base - IMPORT armcc_heap_top IMPORT os_thread_def_main IMPORT osKernelInitialize #ifdef __MBED_CMSIS_RTOS_CM - IMPORT set_main_stack + IMPORT set_stack_heap #endif IMPORT osKernelStart IMPORT osThreadCreate @@ -675,13 +763,12 @@ * ARM Compiler ARM C and C++ Libraries and Floating-Point Support User Guide */ BL __user_setup_stackheap - LDR R3,=armcc_heap_base - LDR R4,=armcc_heap_top - STR R0,[R3] - STR R2,[R4] + /* Ignore return value of __user_setup_stackheap since + * this will be setup by set_stack_heap + */ BL osKernelInitialize #ifdef __MBED_CMSIS_RTOS_CM - BL set_main_stack + BL set_stack_heap #endif LDR R0,=os_thread_def_main MOVS R1,#0 @@ -719,7 +806,7 @@ __asm ( "bl osKernelInitialize\n" #ifdef __MBED_CMSIS_RTOS_CM - "bl set_main_stack\n" + "bl set_stack_heap\n" #endif "ldr r0,=os_thread_def_main\n" "movs r1,#0\n" @@ -796,7 +883,7 @@ #endif osKernelInitialize(); #ifdef __MBED_CMSIS_RTOS_CM - set_main_stack(); + set_stack_heap(); #endif osThreadCreate(&os_thread_def_main, NULL); osKernelStart();