Skip to content

Commit 153fa05

Browse files
authored
Merge pull request #6172 from adustm/l4_linkergcc
Use SRAM2 32Kbytes on STM32L475 / L476 and L486 devices
2 parents 21483cd + d1e6e8f commit 153fa05

File tree

7 files changed

+128
-27
lines changed

7 files changed

+128
-27
lines changed

platform/mbed_retarget.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,12 +1053,13 @@ extern "C" uint32_t __HeapLimit;
10531053
extern "C" int errno;
10541054

10551055
// Dynamic memory allocation related syscall.
1056-
#if defined(TARGET_NUVOTON)
1056+
#if (defined(TARGET_NUVOTON) || defined(TWO_RAM_REGIONS))
10571057

10581058
// Overwrite _sbrk() to support two region model (heap and stack are two distinct regions).
10591059
// __wrap__sbrk() is implemented in:
10601060
// TARGET_NUMAKER_PFM_NUC472 targets/TARGET_NUVOTON/TARGET_NUC472/TARGET_NUMAKER_PFM_NUC472/TOOLCHAIN_GCC_ARM/nuc472_retarget.c
10611061
// TARGET_NUMAKER_PFM_M453 targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/TOOLCHAIN_GCC_ARM/m451_retarget.c
1062+
// TARGET_STM32L4 targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L4/l4_retarget.c
10621063
extern "C" void *__wrap__sbrk(int incr);
10631064
extern "C" caddr_t _sbrk(int incr) {
10641065
return (caddr_t) __wrap__sbrk(incr);

targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L475xG/device/TOOLCHAIN_GCC_ARM/STM32L475XX.ld

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,24 +139,29 @@ SECTIONS
139139
__end__ = .;
140140
end = __end__;
141141
*(.heap*)
142+
. += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .);
142143
__HeapLimit = .;
143144
} > SRAM1
144-
145+
PROVIDE(__heap_size = SIZEOF(.heap));
146+
PROVIDE(__mbed_sbrk_start = ADDR(.heap));
147+
PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
148+
/* Check if data + heap exceeds RAM1 limit */
149+
ASSERT((ORIGIN(SRAM1)+LENGTH(SRAM1)) >= __HeapLimit, "SRAM1 overflow")
145150
/* .stack_dummy section doesn't contains any symbols. It is only
146151
* used for linker to calculate size of stack sections, and assign
147152
* values to stack symbols later */
148153
.stack_dummy (COPY):
149154
{
150155
*(.stack*)
151-
} > SRAM1
156+
} > SRAM2
152157

153158
/* Set stack top to end of RAM, and stack limit move down by
154159
* size of stack_dummy section */
155-
__StackTop = ORIGIN(SRAM1) + LENGTH(SRAM1);
160+
__StackTop = ORIGIN(SRAM2) + LENGTH(SRAM2);
156161
_estack = __StackTop;
157162
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
158163
PROVIDE(__stack = __StackTop);
164+
/* Check if stack exceeds RAM2 limit */
165+
ASSERT((ORIGIN(SRAM2)+LENGTH(SRAM2)) >= __StackLimit, "SRAM2 overflow")
159166

160-
/* Check if data + heap + stack exceeds RAM limit */
161-
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
162167
}

targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L476xG/device/TOOLCHAIN_GCC_ARM/STM32L476XX.ld

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,24 +139,29 @@ SECTIONS
139139
__end__ = .;
140140
end = __end__;
141141
*(.heap*)
142+
. += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .);
142143
__HeapLimit = .;
143144
} > SRAM1
144-
145+
PROVIDE(__heap_size = SIZEOF(.heap));
146+
PROVIDE(__mbed_sbrk_start = ADDR(.heap));
147+
PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
148+
/* Check if data + heap exceeds RAM1 limit */
149+
ASSERT((ORIGIN(SRAM1)+LENGTH(SRAM1)) >= __HeapLimit, "SRAM1 overflow")
145150
/* .stack_dummy section doesn't contains any symbols. It is only
146151
* used for linker to calculate size of stack sections, and assign
147152
* values to stack symbols later */
148153
.stack_dummy (COPY):
149154
{
150155
*(.stack*)
151-
} > SRAM1
156+
} > SRAM2
152157

153158
/* Set stack top to end of RAM, and stack limit move down by
154159
* size of stack_dummy section */
155-
__StackTop = ORIGIN(SRAM1) + LENGTH(SRAM1);
160+
__StackTop = ORIGIN(SRAM2) + LENGTH(SRAM2);
156161
_estack = __StackTop;
157162
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
158163
PROVIDE(__stack = __StackTop);
164+
/* Check if stack exceeds RAM2 limit */
165+
ASSERT((ORIGIN(SRAM2)+LENGTH(SRAM2)) >= __StackLimit, "SRAM2 overflow")
159166

160-
/* Check if data + heap + stack exceeds RAM limit */
161-
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
162167
}

targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L486xG/device/TOOLCHAIN_GCC_ARM/STM32L486XX.ld

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,24 +131,29 @@ SECTIONS
131131
__end__ = .;
132132
end = __end__;
133133
*(.heap*)
134+
. += (ORIGIN(SRAM1) + LENGTH(SRAM1) - .);
134135
__HeapLimit = .;
135136
} > SRAM1
136-
137+
PROVIDE(__heap_size = SIZEOF(.heap));
138+
PROVIDE(__mbed_sbrk_start = ADDR(.heap));
139+
PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
140+
/* Check if data + heap exceeds RAM1 limit */
141+
ASSERT((ORIGIN(SRAM1)+LENGTH(SRAM1)) >= __HeapLimit, "SRAM1 overflow")
137142
/* .stack_dummy section doesn't contains any symbols. It is only
138143
* used for linker to calculate size of stack sections, and assign
139144
* values to stack symbols later */
140145
.stack_dummy (COPY):
141146
{
142147
*(.stack*)
143-
} > SRAM1
148+
} > SRAM2
144149

145150
/* Set stack top to end of RAM, and stack limit move down by
146151
* size of stack_dummy section */
147-
__StackTop = ORIGIN(SRAM1) + LENGTH(SRAM1);
152+
__StackTop = ORIGIN(SRAM2) + LENGTH(SRAM2);
148153
_estack = __StackTop;
149154
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
150155
PROVIDE(__stack = __StackTop);
156+
/* Check if stack exceeds RAM2 limit */
157+
ASSERT((ORIGIN(SRAM2)+LENGTH(SRAM2)) >= __StackLimit, "SRAM2 overflow")
151158

152-
/* Check if data + heap + stack exceeds RAM limit */
153-
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
154159
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
******************************************************************************
3+
* @file l4_retarget.c
4+
* @author MCD Application Team
5+
* @brief CMSIS Cortex-M4 Core Peripheral Access Layer Source File for STM32L475xG
6+
******************************************************************************
7+
* @attention
8+
*
9+
* <h2><center>&copy; COPYRIGHT(c) 2018 STMicroelectronics</center></h2>
10+
*
11+
* Redistribution and use in source and binary forms, with or without modification,
12+
* are permitted provided that the following conditions are met:
13+
* 1. Redistributions of source code must retain the above copyright notice,
14+
* this list of conditions and the following disclaimer.
15+
* 2. Redistributions in binary form must reproduce the above copyright notice,
16+
* this list of conditions and the following disclaimer in the documentation
17+
* and/or other materials provided with the distribution.
18+
* 3. Neither the name of STMicroelectronics nor the names of its contributors
19+
* may be used to endorse or promote products derived from this software
20+
* without specific prior written permission.
21+
*
22+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
26+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29+
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30+
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32+
*
33+
******************************************************************************
34+
*/
35+
#if (defined(TWO_RAM_REGIONS) && defined(__GNUC__) && !defined(__CC_ARM))
36+
#include <errno.h>
37+
#include "stm32l4xx.h"
38+
extern uint32_t __mbed_sbrk_start;
39+
extern uint32_t __mbed_krbs_start;
40+
41+
#define STM32L4_HEAP_ALIGN 32
42+
#define STM32L4_ALIGN_UP(X, ALIGN) (((X) + (ALIGN) - 1) & ~((ALIGN) - 1))
43+
/**
44+
* The default implementation of _sbrk() (in platform/mbed_retarget.cpp) for GCC_ARM requires one-region model (heap and
45+
* stack share one region), which doesn't fit two-region model (heap and stack are two distinct regions), for example,
46+
* STM32L475xG locates heap on SRAM1 and stack on SRAM2.
47+
* Define __wrap__sbrk() to override the default _sbrk(). It is expected to get called through gcc
48+
* hooking mechanism ('-Wl,--wrap,_sbrk') or in _sbrk().
49+
*/
50+
void *__wrap__sbrk(int incr)
51+
{
52+
static uint32_t heap_ind = (uint32_t) &__mbed_sbrk_start;
53+
uint32_t heap_ind_old = STM32L4_ALIGN_UP(heap_ind, STM32L4_HEAP_ALIGN);
54+
uint32_t heap_ind_new = STM32L4_ALIGN_UP(heap_ind_old + incr, STM32L4_HEAP_ALIGN);
55+
56+
if (heap_ind_new > &__mbed_krbs_start) {
57+
errno = ENOMEM;
58+
return (void *) -1;
59+
}
60+
61+
heap_ind = heap_ind_new;
62+
63+
return (void *) heap_ind_old;
64+
}
65+
#endif /* GCC_ARM toolchain && TWO_RAM_REGIONS*/
66+

targets/TARGET_STM/mbed_rtx.h

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,21 @@
1919

2020
#ifndef INITIAL_SP
2121

22-
#if (defined(TARGET_STM32F051R8) ||\
22+
#if (defined(TARGET_STM32L475VG) ||\
23+
defined(TARGET_STM32L476RG) ||\
24+
defined(TARGET_STM32L476JG) ||\
25+
defined(TARGET_STM32L476VG) ||\
26+
defined(TARGET_STM32L486RG))
27+
/* only GCC_ARM and IAR toolchains have the stack on SRAM2 */
28+
#if (((defined(__GNUC__) && !defined(__CC_ARM)) ||\
29+
defined(__IAR_SYSTEMS_ICC__ )) &&\
30+
defined(TWO_RAM_REGIONS))
31+
#define INITIAL_SP (0x10008000UL)
32+
#else
33+
#define INITIAL_SP (0x20018000UL)
34+
#endif /* toolchains */
35+
36+
#elif (defined(TARGET_STM32F051R8) ||\
2337
defined(TARGET_STM32F100RB) ||\
2438
defined(TARGET_STM32L031K6) ||\
2539
defined(TARGET_STM32L053C8) ||\
@@ -68,12 +82,7 @@
6882
#elif defined(TARGET_STM32L152RE)
6983
#define INITIAL_SP (0x20014000UL)
7084

71-
#elif (defined(TARGET_STM32F401RE) ||\
72-
defined(TARGET_STM32L475VG) ||\
73-
defined(TARGET_STM32L476RG) ||\
74-
defined(TARGET_STM32L476JG) ||\
75-
defined(TARGET_STM32L476VG) ||\
76-
defined(TARGET_STM32L486RG))
85+
#elif defined(TARGET_STM32F401RE)
7786
#define INITIAL_SP (0x20018000UL)
7887

7988
#elif (defined(TARGET_STM32F207ZG) ||\
@@ -110,5 +119,15 @@
110119
#endif
111120

112121
#endif // INITIAL_SP
122+
#if (defined(__GNUC__) && !defined(__CC_ARM) && defined(TWO_RAM_REGIONS))
123+
extern uint32_t __StackLimit[];
124+
extern uint32_t __StackTop[];
125+
extern uint32_t __end__[];
126+
extern uint32_t __HeapLimit[];
127+
#define HEAP_START ((unsigned char*)__end__)
128+
#define HEAP_SIZE ((uint32_t)((uint32_t)__HeapLimit - (uint32_t)HEAP_START))
129+
#define ISR_STACK_START ((unsigned char*)__StackLimit)
130+
#define ISR_STACK_SIZE ((uint32_t)((uint32_t)__StackTop - (uint32_t)__StackLimit))
131+
#endif
113132

114133
#endif // MBED_MBED_RTX_H

targets/targets.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,7 +1550,7 @@
15501550
}
15511551
},
15521552
"detect_code": ["0765"],
1553-
"macros_add": ["USBHOST_OTHER"],
1553+
"macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
15541554
"device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH"],
15551555
"release_versions": ["2", "5"],
15561556
"device_name": "STM32L476RG",
@@ -1569,7 +1569,7 @@
15691569
}
15701570
},
15711571
"detect_code": ["0766"],
1572-
"macros_add": ["USBHOST_OTHER"],
1572+
"macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
15731573
"device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH"],
15741574
"release_versions": ["5"],
15751575
"device_name": "STM32L476JG"
@@ -1861,7 +1861,7 @@
18611861
},
18621862
"supported_form_factors": ["ARDUINO"],
18631863
"detect_code": ["0764"],
1864-
"macros_add": ["USBHOST_OTHER"],
1864+
"macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
18651865
"device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_FC", "TRNG", "FLASH"],
18661866
"release_versions": ["2", "5"],
18671867
"device_name": "STM32L475VG",
@@ -1883,7 +1883,7 @@
18831883
}
18841884
},
18851885
"detect_code": ["0820"],
1886-
"macros_add": ["USBHOST_OTHER"],
1886+
"macros_add": ["USBHOST_OTHER", "TWO_RAM_REGIONS"],
18871887
"device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_FC", "TRNG", "FLASH"],
18881888
"release_versions": ["2", "5"],
18891889
"device_name": "STM32L476VG",

0 commit comments

Comments
 (0)