non blocking queue
Fork of mbed-rtos by
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();
