Skip to content

Stack unification and test #7238

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions TESTS/mbed_hal/stack_size_unification/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* mbed Microcontroller Library
* Copyright (c) 2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed.h"
#include "greentea-client/test_env.h"
#include "unity.h"
#include "utest.h"

using namespace utest::v1;

/* Exception for Renesas boards - since these boards are based on Cortex-A
* stack size unification does not apply.
*/
#ifdef RENESAS
#error [NOT_SUPPORTED] Cortex-A target
#endif

extern osThreadAttr_t _main_thread_attr;
extern uint32_t mbed_stack_isr_size;

/* Exception for Nordic boards - BLE requires 2KB ISR stack. */
#ifdef NORDIC
#define EXPECTED_ISR_STACK_SIZE (2048)
#else
#define EXPECTED_ISR_STACK_SIZE (1024)
#endif


#define EXPECTED_MAIN_THREAD_STACK_SIZE (4096)
#define EXPECTED_USER_THREAD_DEFAULT_STACK_SIZE (4096)

/* Test sizes of ISR stack, main thread stack, default user thread stack.
*
* On some platforms with lower RAM size (e.g. NUCLEO_F070RB - 16 KB RAM) it is impossible
* to create thread with default stack size to check its size, that is why we will
* check only macro which specifies default user thread stack.
*
*/
void stack_size_unification_test()
{
TEST_ASSERT_EQUAL(EXPECTED_ISR_STACK_SIZE, mbed_stack_isr_size);
TEST_ASSERT_EQUAL(EXPECTED_MAIN_THREAD_STACK_SIZE, _main_thread_attr.stack_size);
TEST_ASSERT_EQUAL(EXPECTED_USER_THREAD_DEFAULT_STACK_SIZE, OS_STACK_SIZE);
}

utest::v1::status_t test_setup(const size_t number_of_cases)
{
GREENTEA_SETUP(10, "default_auto");
return verbose_test_setup_handler(number_of_cases);
}

Case cases[] = {
Case("Stack size unification test", stack_size_unification_test)
};

Specification specification(test_setup, cases);

int main()
{
return !Harness::run(specification);
}
49 changes: 49 additions & 0 deletions TESTS/mbed_hal/stack_size_unification/stack_size_unification.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* mbed Microcontroller Library
* Copyright (c) 2017-2018 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/** \addtogroup hal_rtc_tests
* @{
*/

#ifndef MBED_STACK_SIZE_UNIFICATION_H
#define MBED_STACK_SIZE_UNIFICATION_H

#ifdef __cplusplus
extern "C" {
#endif

/** Test sizes of ISR stack, main thread stack, default user thread stack.
*
* Given is Mbed OS configuration.
* When ISR stack, main thread stack, default user thread stack sizes are defined.
* Then ISR stack size is equal to 1 KB,
* main thread stack size is equal to 4 KB,
* default user thread stack size is equal to 4 KB.
*
* NOTE:
* It is impossible to verify RTOS-less thread stack size since all tests are build with RTOS.
*/
void stack_size_unification_test(void);

/**@}*/

#ifdef __cplusplus
}
#endif

#endif

/** @}*/
39 changes: 26 additions & 13 deletions rtos/TARGET_CORTEX/mbed_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,27 +132,24 @@
* 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
* -Block of memory from symbol __end__ to define ISR_STACK_START 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
* -Block of memory from end of region "RW_IRAM1" to define ISR_STACK_START 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
Expand Down Expand Up @@ -213,12 +210,6 @@ osMutexAttr_t singleton_mutex_attr;
#error "HEAP_START must be defined if HEAP_SIZE is defined"
#endif

/* IAR - INITIAL_SP and HEAP_START ignored as described in Memory layout notes above
*/
#if !defined(__ICCARM__) && !defined(INITIAL_SP) && !defined(HEAP_START)
#error "no target defined"
#endif

/* Interrupt stack and heap always defined for IAR
* Main thread defined here
*/
Expand All @@ -231,21 +222,43 @@ osMutexAttr_t singleton_mutex_attr;
#define ISR_STACK_SIZE ((uint32_t)__section_size("CSTACK"))
#endif

/* Define ISR stack region if it has not been defined already */
#if !defined(ISR_STACK_START)
#if (defined(__GNUC__) && !defined(__CC_ARM) && !defined(__ARMCC_VERSION))
extern uint32_t __StackLimit;
extern uint32_t __StackTop;
#define ISR_STACK_START ((unsigned char*)&__StackLimit)
#define ISR_STACK_SIZE ((uint32_t)((uint32_t)&__StackTop - (uint32_t)&__StackLimit))
#elif (defined(__CC_ARM))
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Base[];
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$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)
#endif
#endif


/* 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) || (defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
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))
#define HEAP_SIZE ((uint32_t)((uint32_t)ISR_STACK_START - (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))
#define HEAP_SIZE ((uint32_t)((uint32_t)ISR_STACK_START - (uint32_t)HEAP_START))
#endif
#endif

/* IAR - ISR_STACK_START and HEAP_START ignored as described in Memory layout notes above
*/
#if !defined(__ICCARM__) && !defined(ISR_STACK_START) && !defined(HEAP_START)
#error "no target defined"
#endif

/* Define stack sizes if they haven't been set already */
#if !defined(ISR_STACK_SIZE)
#define ISR_STACK_SIZE ((uint32_t)1024)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#! armcc -E
#include "mbed_config.h"

;/*
; * BEETLE CMSIS Library
; */
Expand All @@ -22,6 +25,16 @@
; *** Scatter-Loading Description File ***
; *************************************************************

#if (defined(__stack_size__))
#define Stack_Size __stack_size__
#else
#if (defined(MBED_CONF_RTOS_PRESENT))
#define Stack_Size 0x0400
#else
#define Stack_Size 0x1000
#endif
#endif

LR_IROM1 0x00000000 0x00040000 { ; load region size_region
ER_IROM1 0x00000000 0x00040000 { ; load address = execution address
*.o (RESET, +FIRST)
Expand All @@ -30,7 +43,10 @@ LR_IROM1 0x00000000 0x00040000 { ; load region size_region
CORDIO_RO_2.1.o (*)
}
; Total: 80 vectors = 320 bytes (0x140) to be reserved in RAM
RW_IRAM1 (0x20000000+0x140) (0x20000-0x140) { ; RW data
RW_IRAM1 (0x20000000+0x140) (0x20000-0x140-Stack_Size) { ; RW data
.ANY (+RW +ZI)
}

ARM_LIB_STACK (0x20000000 + 0x20000) EMPTY -Stack_Size { ; Stack region growing down
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ MEMORY
*/
ENTRY(Reset_Handler)

/* Heap 1/4 of ram and stack 1/8 */
__stack_size__ = 0x4000;
__heap_size__ = 0x8000;

HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;

Expand Down Expand Up @@ -202,11 +198,17 @@ SECTIONS
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
. = ORIGIN(RAM) + LENGTH(RAM) - Stack_Size;
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > RAM

.stack_dummy :
{
*(.stack)
. += Stack_Size;
} > RAM

/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@
.syntax unified
.arch armv7-m

.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
#if defined(MBED_CONF_RTOS_PRESENT)
.equ Stack_Size, 0x400
#else
.equ Stack_Size, 0x1000
#endif
#endif
.globl Stack_Size

.section .vector_table,"a",%progbits
.align 2
.globl __isr_vector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ define symbol __ICFEDIT_region_RAM_start__ = 0x20000140;
define symbol __ICFEDIT_region_RAM_end__ = 0x2001FFFF;
/*-Sizes-*/
/* Heap and Stack size */
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_heap__ = 0x4000;
/**** End of ICF editor section. ###ICF###*/

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#! armcc -E
#include "mbed_config.h"

/*
* MPS2 CMSIS Library
Expand Down Expand Up @@ -29,6 +30,16 @@
#include "../memory_zones.h"
#include "../cmsis_nvic.h"

#if (defined(__stack_size__))
#define Stack_Size __stack_size__
#else
#if (defined(MBED_CONF_RTOS_PRESENT))
#define Stack_Size 0x0400
#else
#define Stack_Size 0x1000
#endif
#endif

; The vector table is loaded at address 0x00000000 in Flash memory region.
LR_IROM1 FLASH_START FLASH_SIZE {
ER_IROM1 FLASH_START FLASH_SIZE {
Expand All @@ -44,8 +55,10 @@ LR_IROM2 ZBT_SSRAM1_START ZBT_SSRAM1_SIZE {
}
; At execution, RAM is set to be in ZBT SSRAM2 and 3, just after the vector
; table previously moved from Flash.
RW_IRAM1 (ZBT_SSRAM23_START + NVIC_VECTORS_SIZE) (ZBT_SSRAM23_SIZE - NVIC_VECTORS_SIZE) {
RW_IRAM1 (ZBT_SSRAM23_START + NVIC_VECTORS_SIZE) (ZBT_SSRAM23_SIZE - NVIC_VECTORS_SIZE - Stack_Size) {
.ANY (+RW +ZI)
}
ARM_LIB_STACK (ZBT_SSRAM23_START + ZBT_SSRAM23_SIZE) EMPTY -Stack_Size { ; Stack region growing down
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ MEMORY
*/
ENTRY(Reset_Handler)

HEAP_SIZE = 0x4000;
STACK_SIZE = 0x1000;

/* Size of the vector table in SRAM */
M_VECTOR_RAM_SIZE = NVIC_VECTORS_SIZE;

Expand Down Expand Up @@ -192,15 +189,21 @@ SECTIONS
__end__ = .;
PROVIDE(end = .);
__HeapBase = .;
. += HEAP_SIZE;
. = ORIGIN(RAM) + LENGTH(RAM) - Stack_Size;
__HeapLimit = .;
__heap_limit = .; /* Add for _sbrk */
} > RAM

.stack_dummy :
{
*(.stack)
. += Stack_Size;
} > RAM

/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - STACK_SIZE;
__StackLimit = __StackTop - Stack_Size;
PROVIDE(__stack = __StackTop);

/* Check if data + heap + stack exceeds RAM limit */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@
.syntax unified
.arch armv7-m

.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
#if defined(MBED_CONF_RTOS_PRESENT)
.equ Stack_Size, 0x400
#else
.equ Stack_Size, 0x1000
#endif
#endif
.globl Stack_Size

.section .vector_table,"a",%progbits
.align 2
.globl __isr_vector
Expand Down
Loading