Startup (System Configuration Files)

group group_system_config

Provides device startup, system configuration, and linker script files.

The system startup provides the followings features:

  • See Device Initialization for the:

    • Dual-Core Devices

    • Single-Core Devices

  • Device Memory Definition

  • Heap and Stack Configuration

  • Default Interrupt Handlers Definition

  • Vectors Table Copy from Flash to RAM

  • Cortex-M4 Control

Configuration Considerations

Device Memory Definition

The flash and RAM allocation for each CPU is defined by the linker scripts. For dual-core devices, the physical flash and RAM memory is shared between the CPU cores. 2 KB of RAM (allocated at the end of RAM) are reserved for system use. For Single-Core devices the system reserves additional 80 bytes of RAM. Using the reserved memory area for other purposes will lead to unexpected behavior.

note

The linker files provided with the PDL are generic and handle all common use cases. Your project may not use every section defined in the linker files. In that case you may see warnings during the build process. To eliminate build warnings in your project, you can simply comment out or remove the relevant code in the linker file.

note

For the PSoC 64 Secure MCUs devices, refer to the following page: https://www.cypress.com/documentation/software-and-drivers/psoc-64-secure-mcu-secure-boot-sdk-user-guide

ARM GCC

The flash and RAM sections for the CPU are defined in the linker files: ‘xx_yy.ld’, where ‘xx’ is the device group, and ‘yy’ is the target CPU; for example, ‘cy8c6xx7_cm0plus.ld’ and ‘cy8c6xx7_cm4_dual.ld’.

note

If the start of the Cortex-M4 application image is changed, the value of the CY_CORTEX_M4_APPL_ADDR should also be changed. The CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the Cy_SysEnableCM4() function call. By default, the COMPONENT_CM0P_SLEEP prebuilt image is used for the CM0p core. More about CM0+ prebuilt images, see here: https://github.com/cypresssemiconductorco/psoc6cm0p

Change the flash and RAM sizes by editing the macros value in the linker files for both CPUs:

  • ’xx_cm0plus.ld’, where ‘xx’ is the device group:

    flash       (rx)  : ORIGIN = 0x10000000, LENGTH = 0x2000
    ram         (rwx) : ORIGIN = 0x08000000, LENGTH = 0x2000
    

  • ’xx_cm4_dual.ld’, where ‘xx’ is the device group:

    flash       (rx)  : ORIGIN = 0x10000000, LENGTH = 0x100000
    ram         (rwx) : ORIGIN = 0x08002000, LENGTH = 0x45800
    

Change the value of the CY_CORTEX_M4_APPL_ADDR macro to the ROM ORIGIN’s value (0x10000000) + FLASH_CM0P_SIZE value (0x2000, the size of a flash image of the Cortex-M0+ application should be the same value as the flash LENGTH in ‘xx_cm0plus.ld’) in the ‘xx_cm4_dual.ld’ file, where ‘xx’ is the device group. Do this by either:

  • Passing the following commands to the compiler:

    -D CY_CORTEX_M4_APPL_ADDR=0x10002000 
    
    or

  • Editing the CY_CORTEX_M4_APPL_ADDR value in the ‘system_xx.h’, where ‘xx’ is the device family:

    #define CY_CORTEX_M4_APPL_ADDR (0x10002000u) 
    

ARM Compiler

The flash and RAM sections for the CPU are defined in the linker files: ‘xx_yy.sct’, where ‘xx’ is the device group, and ‘yy’ is the target CPU; for example ‘cy8c6xx7_cm0plus.sct’ and ‘cy8c6xx7_cm4_dual.sct’.

note

If the start of the Cortex-M4 application image is changed, the value of the of the CY_CORTEX_M4_APPL_ADDR should also be changed. The CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the Cy_SysEnableCM4() function call. By default, the COMPONENT_CM0P_SLEEP prebuilt image is used for the CM0p core. More about CM0+ prebuilt images, see here: https://github.com/cypresssemiconductorco/psoc6cm0p

note

The linker files provided with the PDL are generic and handle all common use cases. Your project may not use every section defined in the linker files. In that case you may see the warnings during the build process: L6314W (no section matches pattern) and/or L6329W (pattern only matches removed unused sections). In your project, you can suppress the warning by passing the "--diag_suppress=L6314W,L6329W" option to the linker. You can also comment out or remove the relevant code in the linker file.

Change the flash and RAM sizes by editing the macros value in the linker files for both CPUs:

  • ’xx_cm0plus.sct’, where ‘xx’ is the device group:

    #define FLASH_START 0x10000000
    #define FLASH_SIZE  0x00002000
    #define RAM_START   0x08000000
    #define RAM_SIZE    0x00002000
    

  • ’xx_cm4_dual.sct’, where ‘xx’ is the device group:

    #define FLASH_START 0x10000000
    #define FLASH_SIZE  0x00100000
    #define RAM_START   0x08002000
    #define RAM_SIZE    0x00045800
    

Change the value of the CY_CORTEX_M4_APPL_ADDR macro to the FLASH_START value (0x10000000) + FLASH_CM0P_SIZE value (0x2000, the size of a flash image of the Cortex-M0+ application should be the same value as the FLASH_SIZE in the ‘xx_cm0plus.sct’) in the ‘xx_cm4_dual.sct’ file, where ‘xx’ is the device group. Do this by either:

  • Passing the following commands to the compiler:

    -D CY_CORTEX_M4_APPL_ADDR=0x10002000 
    
    or

  • Editing the CY_CORTEX_M4_APPL_ADDR value in the ‘system_xx.h’, where ‘xx’ is the device family:

    #define CY_CORTEX_M4_APPL_ADDR (0x10002000u) 
    

IAR

The flash and RAM sections for the CPU are defined in the linker files: ‘xx_yy.icf’, where ‘xx’ is the device group, and ‘yy’ is the target CPU; for example, ‘cy8c6xx7_cm0plus.icf’ and ‘cy8c6xx7_cm4_dual.icf’.

note

If the start of the Cortex-M4 application image is changed, the value of the of the CY_CORTEX_M4_APPL_ADDR should also be changed. The CY_CORTEX_M4_APPL_ADDR macro should be used as the parameter for the Cy_SysEnableCM4() function call. By default, the COMPONENT_CM0P_SLEEP prebuilt image is used for the CM0p core. More about CM0+ prebuilt images, see here: https://github.com/cypresssemiconductorco/psoc6cm0p

Change the flash and RAM sizes by editing the macros value in the linker files for both CPUs:

  • ’xx_cm0plus.icf’, where ‘xx’ is the device group:

    define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000;
    define symbol __ICFEDIT_region_IROM1_end__   = 0x10001FFF;
    define symbol __ICFEDIT_region_IRAM1_start__ = 0x08000000;
    define symbol __ICFEDIT_region_IRAM1_end__   = 0x08001FFF;
    

  • ’xx_cm4_dual.icf’, where ‘xx’ is the device group:

    define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000;
    define symbol __ICFEDIT_region_IROM1_end__   = 0x100FFFFF;
    define symbol __ICFEDIT_region_IRAM1_start__ = 0x08002000;
    define symbol __ICFEDIT_region_IRAM1_end__   = 0x080477FF;
    

Change the value of the CY_CORTEX_M4_APPL_ADDR macro to the ICFEDIT_region_IROM1_start value (0x10000000) + FLASH_CM0P_SIZE value (0x2000, the size of a flash image of the Cortex-M0+ application) in the ‘xx_cm4_dual.icf’ file, where ‘xx’ is the device group. The sum result should be the same as (ICFEDIT_region_IROM1_end + 1) value in the ‘xx_cm0plus.icf’. Do this by either:

  • Passing the following commands to the compiler:

    -D CY_CORTEX_M4_APPL_ADDR=0x10002000 
    
    or

  • Editing the CY_CORTEX_M4_APPL_ADDR value in the ‘system_xx.h’, where ‘xx’ is the device family:

    #define CY_CORTEX_M4_APPL_ADDR (0x10002000u) 
    

Device Initialization

After a power-on-reset (POR), the boot process is handled by the boot code from the on-chip ROM that is always executed by the Cortex-M0+ core. The boot code passes the control to the Cortex-M0+ startup code located in flash.

Dual-Core Devices

The Cortex-M0+ startup code performs the device initialization by a call to SystemInit() and then calls the main() function. The Cortex-M4 core is disabled by default. Enable the core using the Cy_SysEnableCM4() function. See Cortex-M4 Control for more details.

note

Startup code executes SystemInit() function for the both Cortex-M0+ and Cortex-M4 cores. The function has a separate implementation on each core. Both function implementations unlock and disable the WDT. Therefore enable the WDT after both cores have been initialized.

Single-Core Devices

The Cortex-M0+ core is not user-accessible on these devices. In this case the Flash Boot handles setup of the CM0+ core and starts the Cortex-M4 core.

Heap and Stack Configuration

There are two ways to adjust heap and stack configurations:

  1. Editing source code files

  2. Specifying via command line

By default, the stack size is set to 0x00001000 and the heap size is allocated dynamically to the whole available free memory up to stack memory and it is set to the 0x00000400 (for ARM GCC and IAR compilers) as minimal value.

ARM GCC

  • Editing source code files

    The heap and stack sizes are defined in the assembler startup files (e.g. startup_psoc6_01_cm0plus.S and startup_psoc6_01_cm4.S). Change the heap and stack sizes by modifying the following lines:

    .equ  Stack_Size, 0x00001000 
    
    .equ  Heap_Size,  0x00000400 
    
    Also, the stack size is defined in the linker script files: ‘xx_yy.ld’, where ‘xx’ is the device family, and ‘yy’ is the target CPU; for example, cy8c6xx7_cm0plus.ld and cy8c6xx7_cm4_dual.ld. Change the stack size by modifying the following line:
    STACK_SIZE = 0x1000; 
    

note

Correct operation of malloc and related functions depends on the working implementation of the 'sbrk' function. Newlib-nano (default C runtime library used by the GNU Arm Embedded toolchain) provides weak 'sbrk' implementation that doesn't check for heap and stack collisions during excessive memory allocations. To ensure the heap always remains within the range defined by __HeapBase and __HeapLimit linker symbols, provide a strong override for the 'sbrk' function:

void
*_sbrk(uint32_tincr)
{
extern
uint8_t__HeapBase,__HeapLimit;
static
uint8_t*heapBrk=&__HeapBase;
uint8_t*prevBrk=heapBrk;
if
(incr>(uint32_t)(&__HeapLimit-heapBrk))
{
errno=ENOMEM;
return
(
void
*)-1;
}
heapBrk+=incr;
return
prevBrk;
}
For FreeRTOS-enabled multi-threaded applications, it is sufficient to include clib-support library that provides newlib-compatible implementations of 'sbrk', '__malloc_lock' and '__malloc_unlock':
https://github.com/cypresssemiconductorco/clib-support.

ARM Compiler

  • Editing source code files

    The stack size is defined in the linker script files: ‘xx_yy.sct’, where ‘xx’ is the device family, and ‘yy’ is the target CPU; for example, cy8c6xx7_cm0plus.sct and cy8c6xx7_cm4_dual.sct. Change the stack size by modifying the following line:

    STACK_SIZE = 0x1000; 
    

IAR

  • Editing source code files

    The heap and stack sizes are defined in the linker script files: ‘xx_yy.icf’, where ‘xx’ is the device family, and ‘yy’ is the target CPU; for example, cy8c6xx7_cm0plus.icf and cy8c6xx7_cm4_dual.icf. Change the heap and stack sizes by modifying the following lines:

    Stack_Size      EQU     0x00001000 
    
    Heap_Size       EQU     0x00000400 
    

  • Specifying via command line

    Change the heap and stack sizes passing the following commands to the linker (including quotation marks):

    --define_symbol __STACK_SIZE=0x000000400 
    
    --define_symbol __HEAP_SIZE=0x000000100 
    

Default Interrupt Handlers Definition

The default interrupt handler functions are defined as weak functions to a dummy handler in the startup file. The naming convention for the interrupt handler names is <interrupt_name>_IRQHandler. A default interrupt handler can be overwritten in user code by defining the handler function using the same name. For example:

 void scb_0_interrupt_IRQHandler(void)
{
    ...
}

Vectors Table Copy from Flash to RAM

This process uses memory sections defined in the linker script. The startup code actually defines the contents of the vector table and performs the copy.

ARM GCC

The linker script file is ‘xx_yy.ld’, where ‘xx’ is the device family, and ‘yy’ is the target CPU; for example, cy8c6xx7_cm0plus.ld and cy8c6xx7_cm4_dual.ld. It defines sections and locations in memory.

Copy interrupt vectors from flash to RAM:

From:

LONG (__Vectors) 
To:
LONG (__ram_vectors_start__) 
Size:
LONG (__Vectors_End - __Vectors) 
The vector table address (and the vector table itself) are defined in the assembler startup files (e.g. startup_psoc6_01_cm0plus.S and startup_psoc6_01_cm4.S). The code in these files copies the vector table from Flash to RAM.

ARM Compiler

The linker script file is ‘xx_yy.sct’, where ‘xx’ is the device family, and ‘yy’ is the target CPU; for example, cy8c6xx7_cm0plus.sct and cy8c6xx7_cm4_dual.sct. The linker script specifies that the vector table (RESET_RAM) shall be first in the RAM section.

RESET_RAM represents the vector table. It is defined in the assembler startup files (e.g. startup_psoc6_01_cm0plus.s and startup_psoc6_01_cm4.s). The code in these files copies the vector table from Flash to RAM.

IAR

The linker script file is ‘xx_yy.icf’, where ‘xx’ is the device family, and ‘yy’ is the target CPU; for example, cy8c6xx7_cm0plus.icf and cy8c6xx7_cm4_dual.icf. This file defines the .intvec_ram section and its location.

place at start of IRAM1_region  { readwrite section .intvec_ram}; 
The vector table address (and the vector table itself) are defined in the assembler startup files (e.g. startup_psoc6_01_cm0plus.s and startup_psoc6_01_cm4.s). The code in these files copies the vector table from Flash to RAM.

MISRA Compliance

MISRA Rule

Rule Class (Required/Advisory)

Rule Description

Description of Deviation(s)

2.3

R

The character sequence // shall not be used within a comment.

The comments provide a useful WEB link to the documentation.

Changelog

Version

Changes

Reason for Change

2.90.1

Updated ARM GCC section with the note on the dynamic memory allocation for ARM GCC.

Documentation update.

Updated system_psoc6.h to include custom CY_SYSTEM_PSOC6_CONFIG passed as compiler macro.

Improve configuration flexibility.

Updated attribute usage for the linker section placement in CM0+ startup code

Enhancement based on usability feedback.

Renamed the '.cy_xip' linker script region as 'cy_xip'

Enable access to the XIP region start/end addresses from the C code.

2.90

Updated linker scripts for PSoC 64 Secure MCU cyb06xx7 devices.

Flash allocation adjustment.

2.80

Updated linker scripts for PSoC 64 Secure MCU devices.

Updated FLASH and SRAM memory area definitions in cyb0xxx linker script templates in accordance with the PSoC 64 Secure Boot SDK policies.

Added Cy_PRA_Init() call to SystemInit() Cortex-M0+ and Cortex-M4 functions for PSoC 64 Secure MCU.

Updated PSoC 64 Secure MCU startup sequence to initialize the Protected Register Access driver.

2.70.1

Updated documentation for the better description of the existing startup implementation.

User experience enhancement.

2.70

Updated SystemCoreClockUpdate() implementation - The SysClk API is reused.

Code optimization.

Updated SystemInit() implementation - The IPC7 structure is initialized for both cores.

Provided support for SysPM driver updates.

Updated the linker scripts.

Reserved FLASH area for the MCU boot headers.

Added System Pipe initialization for all devices.

Improved PDL usability according to user experience.

Removed redundant legacy macros: CY_CLK_EXT_FREQ_HZ, CY_CLK_ECO_FREQ_HZ and CY_CLK_ALTHF_FREQ_HZ. Use Cy_SysClk_ExtClkSetFrequency, Cy_SysClk_EcoConfigure and Cy_BLE_EcoConfigure functions instead them.

Defect fixing.

2.60

Updated linker scripts.

Provided support for new devices, updated usage of CM0p prebuilt image.

2.50

Updated assembler files, C files, linker scripts.

Dynamic allocated HEAP size for Arm Compiler 6, IAR 8.

2.40

Updated assembler files, C files, linker scripts.

Added Arm Compiler 6 support.

2.30

Added assembler files, linker scripts for Mbed OS.

Added Arm Mbed OS embedded operating system support.

Updated linker scripts to extend the Flash and Ram memories size available for the CM4 core.

Enhanced PDL usability.

2.20

Moved the Cy_IPC_SystemSemaInit(), Cy_IPC_SystemPipeInit() functions implementation from IPC to Startup.

Changed the IPC driver configuration method from compile time to run time.

2.10

Added constructor attribute to SystemInit() function declaration for ARM MDK compiler.
Removed $Sub$$main symbol for ARM MDK compiler.

uVision Debugger support.

Updated description of the Startup behavior for Single-Core Devices.
Added note about WDT disabling by SystemInit() function.

Documentation improvement.

2.0

Added restoring of FLL registers to the default state in SystemInit() API for single core devices. Single core device support.

Added Normal Access Restrictions, Public Key, TOC part2 and TOC part2 copy to Supervisory flash linker memory regions.
Renamed 'wflash' memory region to 'em_eeprom'.

Linker scripts usability improvement.

Added Cy_IPC_SystemSemaInit(), Cy_IPC_SystemPipeInit(), Cy_Flash_Init() functions call to SystemInit() API.

Reserved system resources for internal operations.

Added clearing and releasing of IPC structure #7 (reserved for the Deep-Sleep operations) to SystemInit() API.

To avoid deadlocks in case of SW or WDT reset during Deep-Sleep entering.

1.0

Initial version