Skip to content

Commit 0494866

Browse files
committed
M467: Support HyperRAM
1. For GCC, support multi-block .data/.bss initialization 2. HyperRAM is mapped to two regions: 0x0A000000 and 0x80000000 According to default system address map, 0x0A000000 is located at 'Code' region and 0x80000000 at 'RAM' region. With MPU enabled on Mbed OS, 'Code' region is write-never and 'RAM' region execute-never. 0x80000000 is chosen because 'RAM' regioin is naturally for HyperRAM. 3. Configurable multi-function pins for HBI 4. To locate code/data at external HyperRAM: - Specify __attribute__((section(".text.nu.exthyperram"))) for RO/.text/readonly section type Invoke mbed_mpu_manager_lock_ram_execution()/mbed_mpu_manager_unlock_ram_execution() to run HyperRAM code - Specify __attribute__((section(".data.nu.exthyperram"))) for RW/.data/readwrite section type - Specify __attribute__((section(".bss.nu.exthyperram"))) for ZI/.bss/zeroinit section type 5. Add readme
1 parent 8da2e31 commit 0494866

File tree

7 files changed

+385
-28
lines changed

7 files changed

+385
-28
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Nuvoton M460 series
2+
3+
## HyperRAM
4+
5+
HyperRAM, via Hyper Bus Interface Controller (HBI), is mapped to two regions: `0x0A00_0000``0x0BFF_FFFF` and `0x8000_0000``0x81FF_FFFF`, through which CPU can direct access.
6+
7+
### Enable HBI for HyperRAM
8+
9+
To enable HBI for HyperRAM, create one Mbed OS application configuration file named `mbed_app.json` under root directory of your sample program.
10+
The file should have the following content which will enable HBI and configure its multi-function pins:
11+
12+
**mbed_app.json**:
13+
14+
```json
15+
{
16+
......
17+
"target_overrides": {
18+
......
19+
"NUMAKER_IOT_M467": {
20+
"target.hbi-enable": true,
21+
"target.hbi-mfp-reg-list": "0x40000534, 0x4000057C, 0x40000590, 0x40000594",
22+
"target.hbi-mfp-reg-msk-list": "0xFFFFFF00, 0xFFFFFFFF, 0xFFFF0000, 0xFFFFFFFF",
23+
"target.hbi-mfp-reg-val-list": "0x10101000, 0x10101010, 0x10100000, 0x10101010"
24+
}
25+
}
26+
}
27+
```
28+
29+
Where:
30+
31+
- `hbi-mfp-reg-list`: Comma-separated list of relevant multi-function pin registers
32+
- `hbi-mfp-reg-msk-list`: Comma-separated list of relevant multi-function pin register masks
33+
- `hbi-mfp-reg-val-list`: Comma-separated list of relevant multi-function pin register values
34+
35+
> **_NOTE:_** Make sure your HyperRAM hardware is ready.
36+
37+
> **_NOTE:_** Change the multi-function pins to align with your hardware.
38+
39+
### Locate data at HyperRAM
40+
41+
In the port, the region `0x8000_0000``0x81FF_FFFF` is chosen for the goal because on Mbed OS, MPU is enabled and the region is configured to be write-able, which naturally fits HyperRAM.
42+
To get to the goal, data must place in specified sections:
43+
44+
**Locate initialized data**
45+
46+
Initialized data are just like `RW` sections for ARM, `.data` sectionis for GCC_ARM, and `readwrite` sections for IAR.
47+
To locate them at HyperRAM, place in specified sections named `.data.nu.hyperram`.
48+
49+
```c++
50+
__attribute__((section(".data.nu.hyperram")))
51+
uint32_t my_data = 100;
52+
```
53+
54+
**Locate zero-initialized data**
55+
56+
Zero-initialized data are just like `ZI` sections for ARM, `.bss` sections for GCC_ARM, and `zeroinit` sections for IAR.
57+
To locate them at HyperRAM, place in specified sections named`.bss.nu.hyperram`.
58+
59+
```c++
60+
__attribute__((section(".bss.nu.hyperram")))
61+
uint32_t my_bss;
62+
```
63+
64+
> **_NOTE:_** Don't mis-place in sections,
65+
or behavior is undefined because C runtime is not correctly initialized for these sections.
66+
67+
> **_NOTE:_** Check linker-generated .map file to make sure your data are actually located at HyperRAM.

targets/TARGET_NUVOTON/TARGET_M460/device/TOOLCHAIN_ARM_STD/M467.sct

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,19 @@
2121
#include "../M460_mem.h"
2222

2323
#if !defined(MBED_BOOT_STACK_SIZE)
24-
#define MBED_BOOT_STACK_SIZE 0x400
24+
#define MBED_BOOT_STACK_SIZE 0x400
2525
#endif
2626

2727
#define VECTOR_SIZE (4*(16 + 128))
2828

29+
#if !defined(NU_HYPERRAM_START)
30+
#define NU_HYPERRAM_START 0x80000000
31+
#endif
32+
33+
#if !defined(NU_HYPERRAM_SIZE)
34+
#define NU_HYPERRAM_SIZE 0x800000
35+
#endif
36+
2937
LR_IROM1 MBED_APP_START MBED_APP_SIZE {
3038
ER_IROM1 MBED_APP_START MBED_APP_SIZE { ; load address = execution address
3139
*(RESET, +First)
@@ -53,6 +61,12 @@ LR_IROM1 MBED_APP_START MBED_APP_SIZE {
5361

5462
ARM_LIB_HEAP AlignExpr(+0, 16) EMPTY (MBED_RAM_APP_START + MBED_RAM_APP_SIZE - AlignExpr(ImageLimit(RW_IRAM1), 16)) {
5563
}
64+
65+
NU_HYPERRAM NU_HYPERRAM_START NU_HYPERRAM_SIZE {
66+
*(.text.nu.hyperram)
67+
*(.data.nu.hyperram)
68+
*(.bss.nu.hyperram)
69+
}
5670
}
5771

5872
ScatterAssert(LoadLimit(LR_IROM1) <= (MBED_APP_START + MBED_APP_SIZE))

targets/TARGET_NUVOTON/TARGET_M460/device/TOOLCHAIN_GCC_ARM/M467.ld

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,15 @@
2323
#include "../M460_mem.h"
2424

2525
#if !defined(MBED_BOOT_STACK_SIZE)
26-
#define MBED_BOOT_STACK_SIZE 0x400
26+
#define MBED_BOOT_STACK_SIZE 0x400
27+
#endif
28+
29+
#if !defined(NU_HYPERRAM_START)
30+
#define NU_HYPERRAM_START 0x80000000
31+
#endif
32+
33+
#if !defined(NU_HYPERRAM_SIZE)
34+
#define NU_HYPERRAM_SIZE 0x800000
2735
#endif
2836

2937
M_CRASH_DATA_RAM_SIZE = 0x100;
@@ -34,6 +42,7 @@ MEMORY
3442
VECTORS (rx) : ORIGIN = MBED_APP_START, LENGTH = 0x00000400
3543
FLASH (rx) : ORIGIN = MBED_APP_START + 0x400, LENGTH = MBED_APP_SIZE - 0x00000400
3644
RAM_INTERN (rwx) : ORIGIN = MBED_RAM_APP_START, LENGTH = MBED_RAM_APP_SIZE
45+
HYPERRAM (rwx) : ORIGIN = NU_HYPERRAM_START, LENGTH = NU_HYPERRAM_SIZE
3746
}
3847

3948
/**
@@ -79,6 +88,52 @@ SECTIONS
7988
. = ALIGN(8);
8089
} > VECTORS
8190

91+
.copy.table : ALIGN(4)
92+
{
93+
__copy_table_start__ = .;
94+
95+
/* .data located at internal SRAM */
96+
LONG (LOADADDR(.data))
97+
LONG (ADDR(.data))
98+
LONG (SIZEOF(.data))
99+
100+
/* .text.nu.hyperram located at HyperRAM */
101+
LONG (LOADADDR(.text.nu.hyperram))
102+
LONG (ADDR(.text.nu.hyperram))
103+
LONG (SIZEOF(.text.nu.hyperram))
104+
105+
/* .data.nu.hyperram located at HyperRAM */
106+
LONG (LOADADDR(.data.nu.hyperram))
107+
LONG (ADDR(.data.nu.hyperram))
108+
LONG (SIZEOF(.data.nu.hyperram))
109+
110+
__copy_table_end__ = .;
111+
} > FLASH
112+
113+
.zero.table : ALIGN(4)
114+
{
115+
__zero_table_start__ = .;
116+
117+
/* .bss located at internal SRAM */
118+
LONG (ADDR(.bss))
119+
LONG (SIZEOF(.bss))
120+
121+
/* .bss.nu.hyperram located at HyperRAM */
122+
LONG (ADDR(.bss.nu.hyperram))
123+
LONG (SIZEOF(.bss.nu.hyperram))
124+
125+
__zero_table_end__ = .;
126+
} > FLASH
127+
128+
/* First match used, so place in front of .text */
129+
.text.nu.hyperram :
130+
{
131+
*(.text.nu.hyperram)
132+
} >HYPERRAM AT>FLASH
133+
134+
Image$$NU_HYPERRAM$$RO$$Base = ADDR(.text.nu.hyperram);
135+
Image$$NU_HYPERRAM$$RO$$Limit = ADDR(.text.nu.hyperram) + SIZEOF(.text.nu.hyperram);
136+
Image$$NU_HYPERRAM$$RO$$Length = SIZEOF(.text.nu.hyperram);
82137

83138
.text :
84139
{
@@ -156,7 +211,17 @@ SECTIONS
156211
. = ALIGN(8);
157212
__CRASH_DATA_RAM_END__ = .; /* Define a global symbol at data end */
158213
} > RAM_INTERN
159-
214+
215+
/* First match used, so place in front of .data */
216+
.data.nu.hyperram :
217+
{
218+
*(.data.nu.hyperram)
219+
} >HYPERRAM AT>FLASH
220+
221+
Image$$NU_HYPERRAM$$RW$$Base = ADDR(.data.nu.hyperram);
222+
Image$$NU_HYPERRAM$$RW$$Limit = ADDR(.data.nu.hyperram) + SIZEOF(.data.nu.hyperram);
223+
Image$$NU_HYPERRAM$$RW$$Length = SIZEOF(.data.nu.hyperram);
224+
160225
.data :
161226
{
162227
PROVIDE( __etext = LOADADDR(.data) );
@@ -205,6 +270,20 @@ SECTIONS
205270
__uninitialized_end = .;
206271
} > RAM_INTERN
207272

273+
/* First match used, so place in front of .bss */
274+
/* If a variable defined with __attribute__((section())) keyword the
275+
* variable is treated like an initialized variable. To not waste memory
276+
* NOLOAD attribute used here. The whole section is zero initialized by
277+
* adding section information to .zero.table */
278+
.bss.nu.hyperram (NOLOAD):
279+
{
280+
*(.bss.nu.hyperram)
281+
} > HYPERRAM
282+
283+
Image$$NU_HYPERRAM$$ZI$$Base = ADDR(.bss.nu.hyperram);
284+
Image$$NU_HYPERRAM$$ZI$$Limit = ADDR(.bss.nu.hyperram) + SIZEOF(.bss.nu.hyperram);
285+
Image$$NU_HYPERRAM$$ZI$$Length = SIZEOF(.bss.nu.hyperram);
286+
208287
.bss (NOLOAD):
209288
{
210289
__bss_start__ = .;
@@ -226,5 +305,4 @@ SECTIONS
226305
PROVIDE(__heap_size = SIZEOF(.heap));
227306
PROVIDE(__mbed_sbrk_start = ADDR(.heap));
228307
PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap));
229-
230308
}

targets/TARGET_NUVOTON/TARGET_M460/device/TOOLCHAIN_IAR/M467.icf

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ if (!isdefinedsymbol(MBED_BOOT_STACK_SIZE)) {
2626
define symbol MBED_BOOT_STACK_SIZE = 0x400;
2727
}
2828

29+
if (!isdefinedsymbol(NU_HYPERRAM_START)) {
30+
define symbol NU_HYPERRAM_START = 0x80000000;
31+
}
32+
33+
if (!isdefinedsymbol(NU_HYPERRAM_SIZE)) {
34+
define symbol NU_HYPERRAM_SIZE = 0x800000;
35+
}
36+
2937
/*-Specials-*/
3038
define symbol __ICFEDIT_intvec_start__ = MBED_APP_START;
3139
/*-Memory Regions-*/
@@ -35,6 +43,8 @@ define symbol __ICFEDIT_region_IRAM_start__ = MBED_RAM_APP_START;
3543
define symbol __ICFEDIT_region_IRAM_end__ = MBED_RAM_APP_START + MBED_RAM_APP_SIZE - 0x100 - 1;
3644
define symbol __region_CRASH_DATA_RAM_start__ = MBED_RAM_APP_START + MBED_RAM_APP_SIZE - 0x100;
3745
define symbol __region_CRASH_DATA_RAM_end__ = MBED_RAM_APP_START + MBED_RAM_APP_SIZE - 1;
46+
define symbol __ICFEDIT_region_HYPERRAM_start__ = NU_HYPERRAM_START;
47+
define symbol __ICFEDIT_region_HYPERRAM_end__ = NU_HYPERRAM_START + NU_HYPERRAM_SIZE - 1;
3848
/*-Sizes-*/
3949
define symbol __ICFEDIT_size_cstack__ = MBED_BOOT_STACK_SIZE;
4050
define symbol __ICFEDIT_size_intvec__ = (4 * (16 + 128));
@@ -46,23 +56,42 @@ define memory mem with size = 4G;
4656
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
4757
define region IRAM_region = mem:[from __ICFEDIT_region_IRAM_start__ to __ICFEDIT_region_IRAM_end__];
4858
define region CRASH_DATA_RAM_region = mem:[from __region_CRASH_DATA_RAM_start__ to __region_CRASH_DATA_RAM_end__];
59+
define region HYPERRAM_region = mem:[from __ICFEDIT_region_HYPERRAM_start__ to __ICFEDIT_region_HYPERRAM_end__];
4960

5061
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
5162
define block HEAP with expanding size, alignment = 8, minimum size = __ICFEDIT_size_heap__ { };
5263
/* NOTE: Vector table base requires to be aligned to the power of vector table size. Give a safe value here. */
5364
define block IRAMVEC with alignment = 1024, size = __ICFEDIT_size_intvec__ { };
65+
/* Place .text.nu.hyperram/.data.nu.hyperram/.bss.nu.hyperram together
66+
*
67+
* NOTE: Don't use wildcard like .text.nu.hyperram*. This can collide with .text.nu.hyperram*_init or
68+
* linker-generated initializer for .text.nu.hyperram*.
69+
* NOTE: Per test, 'section .data.nu.hyperram*' will cause linker-generated initializer (const)
70+
* also placed here, resulting in large gap, though it can get fixed with
71+
* 'readwrite section .data.nu.hyperram*'.
72+
* NOTE: With 'initialize by copy { section .text.nu.hyperram }', .text.nu.hyperram is still taken
73+
* as readonly (for initializer), resulting in large gap.
74+
* NOTE: With 'initialize manually { section .text.nu.hyperram }', .text.nu.hyperram becomes readwrite
75+
* .text.nu.hyperram_init is generated by linker to be readonly. We need to do the initialization
76+
* for .text.nu.hyperram manually.
77+
*/
78+
define block NU_HYPERRAM with alignment = 8 { section .text.nu.hyperram,
79+
section .data.nu.hyperram,
80+
section .bss.nu.hyperram };
5481

5582
/* Define Crash Data Symbols */
5683
define exported symbol __CRASH_DATA_RAM_START__ = __region_CRASH_DATA_RAM_start__;
5784
define exported symbol __CRASH_DATA_RAM_END__ = __region_CRASH_DATA_RAM_end__;
5885

59-
initialize by copy { readwrite };
60-
do not initialize { section .noinit };
86+
initialize by copy { readwrite };
87+
initialize manually { section .text.nu.hyperram };
88+
do not initialize { section .noinit };
6189

6290
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
6391

64-
place in ROM_region { readonly };
92+
place in ROM_region { readonly };
6593
place at start of IRAM_region { block CSTACK };
6694
place in IRAM_region { block IRAMVEC };
6795
place in IRAM_region { readwrite };
6896
place in IRAM_region { block HEAP };
97+
place in HYPERRAM_region { block NU_HYPERRAM };

0 commit comments

Comments
 (0)