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.

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();