Skip to content

Commit b0c767a

Browse files
committed
M2351: Refactor startup file
1. Re-organize to make clear all targets/toolchains support in single startup file 2. Inline assembly syntax is limited, esp. on IAR. Try paving the way for accessing external symbols still in inline assembly instead of re-write in assembly. 3. Update GCC C run-time sequence to fit future GCC script file.
1 parent 239ec8c commit b0c767a

File tree

1 file changed

+124
-74
lines changed

1 file changed

+124
-74
lines changed

targets/TARGET_NUVOTON/TARGET_M2351/device/startup_M2351.c

Lines changed: 124 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,35 @@
1-
/**************************************************************************//**
2-
* @file startup_M2351.c
3-
* @version V2.00
4-
* $Revision: 9 $
5-
* $Date: 16/08/27 12:33p $
6-
* @brief Startup Source File
1+
/*
2+
* Copyright (c) 2018-2019, Nuvoton Technology Corporation
73
*
8-
* @note
9-
* Copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
4+
* SPDX-License-Identifier: Apache-2.0
105
*
11-
******************************************************************************/
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
1218

1319
#include "M2351.h"
1420

1521
/* Suppress warning messages */
16-
#if defined(__CC_ARM)
17-
// Suppress warning message: extended constant initialiser used
22+
#if defined(__ARMCC_VERSION)
23+
// Suppress warning message: extended constant initializer used
1824
#pragma diag_suppress 1296
1925
#elif defined(__ICCARM__)
26+
// Suppress warning message Pe1665
27+
#pragma diag_suppress=Pe1665
2028
#elif defined(__GNUC__)
2129
#endif
2230

2331
/* Macro Definitions */
24-
#if defined(__CC_ARM)
32+
#if defined(__ARMCC_VERSION)
2533
#define WEAK __attribute__ ((weak))
2634
#define ALIAS(f) __attribute__ ((weak, alias(#f)))
2735

@@ -46,22 +54,22 @@ void FUN(void) __attribute__ ((weak, alias(#FUN_ALIAS)));
4654

4755
#endif
4856

49-
5057
/* Initialize segments */
51-
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
58+
#if defined(__ARMCC_VERSION)
5259
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
5360
extern void __main(void);
5461
#elif defined(__ICCARM__)
62+
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
63+
extern uint32_t CSTACK$$Limit;
5564
void __iar_program_start(void);
5665
#elif defined(__GNUC__)
66+
extern uint32_t Image$$ARM_LIB_STACK$$ZI$$Limit;
5767
extern uint32_t __StackTop;
58-
extern uint32_t __etext;
59-
extern uint32_t __data_start__;
60-
extern uint32_t __data_end__;
61-
extern uint32_t __bss_start__;
62-
extern uint32_t __bss_end__;
68+
extern uint32_t __copy_table_start__;
69+
extern uint32_t __copy_table_end__;
70+
extern uint32_t __zero_table_start__;
71+
extern uint32_t __zero_table_end__;
6372

64-
extern void uvisor_init(void);
6573
#if defined(TOOLCHAIN_GCC_ARM)
6674
extern void _start(void);
6775
#else
@@ -87,7 +95,7 @@ WEAK_ALIAS_FUNC(SysTick_Handler, Default_Handler)
8795
WEAK_ALIAS_FUNC(BOD_IRQHandler, Default_Handler) // 0: Brown Out detection
8896
WEAK_ALIAS_FUNC(IRC_IRQHandler, Default_Handler) // 1: Internal RC
8997
WEAK_ALIAS_FUNC(PWRWU_IRQHandler, Default_Handler) // 2: Power down wake up
90-
WEAK_ALIAS_FUNC(SRAM_IRQHandler, Default_Handler) // 3: SRAM
98+
WEAK_ALIAS_FUNC(SRAM_IRQHandler, Default_Handler) // 3: SRAM
9199
WEAK_ALIAS_FUNC(CLKFAIL_IRQHandler, Default_Handler) // 4: Clock detection fail
92100
// 5: Reserved
93101
WEAK_ALIAS_FUNC(RTC_IRQHandler, Default_Handler) // 6: Real Time Clock
@@ -106,16 +114,16 @@ WEAK_ALIAS_FUNC(GPC_IRQHandler, Default_Handler) // 18: GPIO Port C
106114
WEAK_ALIAS_FUNC(GPD_IRQHandler, Default_Handler) // 19: GPIO Port D
107115
WEAK_ALIAS_FUNC(GPE_IRQHandler, Default_Handler) // 20: GPIO Port E
108116
WEAK_ALIAS_FUNC(GPF_IRQHandler, Default_Handler) // 21: GPIO Port F
109-
WEAK_ALIAS_FUNC(QSPI0_IRQHandler, Default_Handler) // 22: SPI0
117+
WEAK_ALIAS_FUNC(QSPI0_IRQHandler, Default_Handler) // 22: SPI0
110118
WEAK_ALIAS_FUNC(SPI0_IRQHandler, Default_Handler) // 23: SPI1
111119
WEAK_ALIAS_FUNC(BRAKE0_IRQHandler, Default_Handler) // 24:
112-
WEAK_ALIAS_FUNC(EPWM0_P0_IRQHandler, Default_Handler) // 25:
113-
WEAK_ALIAS_FUNC(EPWM0_P1_IRQHandler, Default_Handler) // 26:
114-
WEAK_ALIAS_FUNC(EPWM0_P2_IRQHandler, Default_Handler) // 27:
120+
WEAK_ALIAS_FUNC(EPWM0_P0_IRQHandler, Default_Handler) // 25:
121+
WEAK_ALIAS_FUNC(EPWM0_P1_IRQHandler, Default_Handler) // 26:
122+
WEAK_ALIAS_FUNC(EPWM0_P2_IRQHandler, Default_Handler) // 27:
115123
WEAK_ALIAS_FUNC(BRAKE1_IRQHandler, Default_Handler) // 28:
116-
WEAK_ALIAS_FUNC(EPWM1_P0_IRQHandler, Default_Handler) // 29:
117-
WEAK_ALIAS_FUNC(EPWM1_P1_IRQHandler, Default_Handler) // 30:
118-
WEAK_ALIAS_FUNC(EPWM1_P2_IRQHandler, Default_Handler) // 31:
124+
WEAK_ALIAS_FUNC(EPWM1_P0_IRQHandler, Default_Handler) // 29:
125+
WEAK_ALIAS_FUNC(EPWM1_P1_IRQHandler, Default_Handler) // 30:
126+
WEAK_ALIAS_FUNC(EPWM1_P2_IRQHandler, Default_Handler) // 31:
119127
WEAK_ALIAS_FUNC(TMR0_IRQHandler, Default_Handler) // 32: Timer 0
120128
WEAK_ALIAS_FUNC(TMR1_IRQHandler, Default_Handler) // 33: Timer 1
121129
WEAK_ALIAS_FUNC(TMR2_IRQHandler, Default_Handler) // 34: Timer 2
@@ -124,7 +132,7 @@ WEAK_ALIAS_FUNC(UART0_IRQHandler, Default_Handler) // 36: UART0
124132
WEAK_ALIAS_FUNC(UART1_IRQHandler, Default_Handler) // 37: UART1
125133
WEAK_ALIAS_FUNC(I2C0_IRQHandler, Default_Handler) // 38: I2C0
126134
WEAK_ALIAS_FUNC(I2C1_IRQHandler, Default_Handler) // 39: I2C1
127-
WEAK_ALIAS_FUNC(PDMA0_IRQHandler, Default_Handler) // 40: Peripheral DMA
135+
WEAK_ALIAS_FUNC(PDMA0_IRQHandler, Default_Handler) // 40: Peripheral DMA
128136
WEAK_ALIAS_FUNC(DAC_IRQHandler, Default_Handler) // 41: DAC
129137
WEAK_ALIAS_FUNC(EADC0_IRQHandler, Default_Handler) // 42: ADC0 interrupt source 0
130138
WEAK_ALIAS_FUNC(EADC1_IRQHandler, Default_Handler) // 43: ADC0 interrupt source 1
@@ -177,26 +185,24 @@ WEAK_ALIAS_FUNC(DSRC_IRQHandler, Default_Handler) // 97:
177185
WEAK_ALIAS_FUNC(PDMA1_IRQHandler, Default_Handler) // 98:
178186
WEAK_ALIAS_FUNC(SCU_IRQHandler, Default_Handler) // 99:
179187
// 100: Reserved
180-
WEAK_ALIAS_FUNC(TRNG_IRQHandler, Default_Handler) // 101:
188+
WEAK_ALIAS_FUNC(TRNG_IRQHandler, Default_Handler) // 101:
181189

182190

183191
/* Vector table */
184-
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
185-
__attribute__ ((section("RESET")))
192+
#if defined(__ARMCC_VERSION)
193+
__attribute__ ((section("RESET"), used))
186194
const uint32_t __vector_handlers[] = {
187195
#elif defined(__ICCARM__)
188-
extern uint32_t CSTACK$$Limit;
189196
const uint32_t __vector_table[] @ ".intvec" = {
190197
#elif defined(__GNUC__)
191198
__attribute__ ((section(".vector_table")))
192199
const uint32_t __vector_handlers[] = {
193200
#endif
194201

195202
/* Configure Initial Stack Pointer, using linker-generated symbols */
196-
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
203+
#if defined(__ARMCC_VERSION)
197204
(uint32_t) &Image$$ARM_LIB_STACK$$ZI$$Limit,
198205
#elif defined(__ICCARM__)
199-
//(uint32_t) __sfe("CSTACK"),
200206
(uint32_t) &CSTACK$$Limit,
201207
#elif defined(__GNUC__)
202208
(uint32_t) &__StackTop,
@@ -323,12 +329,48 @@ const uint32_t __vector_handlers[] = {
323329
(uint32_t) TRNG_IRQHandler, // 101:
324330
};
325331

326-
/**
327-
* \brief This is the code that gets called on processor reset.
332+
/* Some reset handler code cannot implement in pure C. Implement it in inline/embedded assembly.
333+
*
334+
* Reset_Handler:
335+
* For non-secure PSA/non-secure non-PSA/secure non-PSA, jump directly to Reset_Handler_1
336+
* For secure PSA, switch from MSP to PSP, then jump to Reset_Handler_1
337+
*
338+
* Reset_Handler_1:
339+
* Platform initialization
340+
* C/C++ runtime initialization
341+
*/
342+
343+
/* Forward declaration */
344+
void Reset_Handler_1(void);
345+
346+
/* Add '__attribute__((naked))' here to make sure compiler does not generate prologue and
347+
* epilogue sequences for Reset_Handler. We don't want MSP is updated by compiler-generated
348+
* code during stack switch.
349+
*
350+
* Don't allow extended assembly in naked functions:
351+
* The compiler only supports basic __asm statements in __attribute__((naked))
352+
* functions. Using extended assembly, parameter references or mixing C code with
353+
* __asm statements might not work reliably.
328354
*/
329-
void Reset_Handler(void)
355+
__attribute__((naked)) void Reset_Handler(void)
356+
{
357+
#if defined(__GNUC__)
358+
__asm(".syntax unified \n");
359+
#endif
360+
361+
/* Jump to Reset_Handler_1 */
362+
#if !defined(__ICCARM__)
363+
__asm("movw r0, #:lower16:Reset_Handler_1 \n");
364+
__asm("movt r0, #:upper16:Reset_Handler_1 \n");
365+
#else
366+
__asm("mov32 r0, Reset_Handler_1 \n");
367+
#endif
368+
__asm("bx r0 \n");
369+
}
370+
371+
void Reset_Handler_1(void)
330372
{
331-
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
373+
#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
332374
/* Disable register write-protection function */
333375
SYS_UnlockReg();
334376

@@ -339,38 +381,61 @@ void Reset_Handler(void)
339381
SYS_LockReg();
340382
#endif
341383

342-
/**
343-
* SystemInit() must be called at the very start.
344-
*/
384+
/* SystemInit() must be called at the very start. */
345385
SystemInit();
346386

347-
#if defined(__CC_ARM) || (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
387+
#if defined(__ARMCC_VERSION)
348388
__main();
349389

350390
#elif defined(__ICCARM__)
351391
__iar_program_start();
352392

353393
#elif defined(__GNUC__)
354-
uint32_t *src_ind = (uint32_t *) &__etext;
355-
uint32_t *dst_ind = (uint32_t *) &__data_start__;
356-
uint32_t *dst_end = (uint32_t *) &__data_end__;
357-
358-
/* Move .data section from ROM to RAM */
359-
if (src_ind != dst_ind) {
360-
for (; dst_ind < dst_end;) {
361-
*dst_ind ++ = *src_ind ++;
394+
/* Move (multiple) .data section(s) from ROM to RAM */
395+
{
396+
/* Struct of copy table entry which must match linker script */
397+
typedef struct copy_table_entry_ {
398+
uint32_t src; // Address to copy from
399+
uint32_t dst; // Address to copy to
400+
uint32_t size; // Copy size in bytes
401+
} copy_table_entry;
402+
403+
copy_table_entry *copy_table_ind = (copy_table_entry *) &__copy_table_start__;
404+
copy_table_entry *copy_table_end = (copy_table_entry *) &__copy_table_end__;
405+
406+
for (; copy_table_ind != copy_table_end; copy_table_ind ++) {
407+
uint32_t *src_ind = (uint32_t *) copy_table_ind->src;
408+
uint32_t *src_end = (uint32_t *) (copy_table_ind->src + copy_table_ind->size);
409+
uint32_t *dst_ind = (uint32_t *) copy_table_ind->dst;
410+
if (src_ind != dst_ind) {
411+
for (; src_ind < src_end;) {
412+
*dst_ind ++ = *src_ind ++;
413+
}
414+
}
362415
}
363416
}
364-
365-
/* Initialize .bss section to zero */
366-
dst_ind = (uint32_t *) &__bss_start__;
367-
dst_end = (uint32_t *) &__bss_end__;
368-
if (dst_ind != dst_end) {
369-
for (; dst_ind < dst_end;) {
370-
*dst_ind ++ = 0;
417+
418+
/* Initialize (multiple) .bss sections to zero */
419+
{
420+
/* Struct of zero table entry which must match linker script */
421+
typedef struct zero_table_entry_ {
422+
uint32_t start; // Address to start zero'ing
423+
uint32_t size; // Zero size in bytes
424+
} zero_table_entry;
425+
426+
zero_table_entry *zero_table_ind = (zero_table_entry *) &__zero_table_start__;
427+
zero_table_entry *zero_table_end = (zero_table_entry *) &__zero_table_end__;
428+
429+
for (; zero_table_ind != zero_table_end; zero_table_ind ++) {
430+
uint32_t *dst_ind = (uint32_t *) zero_table_ind->start;
431+
uint32_t *dst_end = (uint32_t *) (zero_table_ind->start + zero_table_ind->size);
432+
433+
for (; dst_ind < dst_end; ) {
434+
*dst_ind ++ = 0;
435+
}
371436
}
372437
}
373-
438+
374439
_start();
375440

376441
#endif
@@ -386,18 +451,3 @@ void Default_Handler(void)
386451
{
387452
while (1);
388453
}
389-
390-
#if 0
391-
#if defined(__CC_ARM)
392-
uint32_t GetPC(void)
393-
{
394-
uint32_t val=0;
395-
__asm {
396-
MOV R0, #0 // dumy
397-
//MOV R0, LR // Except R0~R12, SP/LR/PC cannot be read or directly modified in inline assembly code
398-
MOV val, R0
399-
}
400-
return val;
401-
}
402-
#endif
403-
#endif

0 commit comments

Comments
 (0)