ARM Technical Support Knowledge Articles

Booting a Cortex-M7 system

Applies to: Cortex-M7

Answer

There are a number of different factors that influence how a Cortex-M7 system boots, for example:

Another important factor is the Cortex Microcontroller Software Interface Standard. CMSIS is the standard that makes it easier for silicon vendors, tool vendors and software developers to work with Cortex-M devices. CMSIS-CORE, which is one of the most important components of CMSIS, defines two startup files:

<device> is replaced with the name of the device, for example:

Cortex-M silicon vendors provide a basic implementation of these files that sets up the bare minimum functionality required to allow software developers to immediately get started with the Cortex-M device they are working with.

The assembly language file contains the vector table, code for stack and heap initialisation and a reset handler. The C file is very device specific and is where the clocks in the system are configured.

For more information, please see the following documentation:

http://www.keil.com/pack/doc/CMSIS/Core/html/startup_s_pg.html
http://www.keil.com/pack/doc/CMSIS/Core/html/system_c_pg.html

The minimum reset handler, which is given a standard function label of Reset_Handler, calls two functions:

SystemInit() - System and clock configuration, for example, configure XTAL frequency or PLL prescaler settings.
__main - an ARM Compiler library function similar to _start in GCC.

The __main function is responsible for setting up the C library appropriately and eventually ends up calling the main() function. Before branching to main() it also runs code that copies code/data, if necessary, to appropriate run-time locations. In ARM Compiler this process is known as "scatter-loading". A nice diagram that explains this is provided in the armlink User Guide.

Although this section of the document uses toolchain specific terms and syntax, the mechanism and the concept of "load" and "execution" views is similar for other toolchains.

Further information about __main is available in the ARM Compiler Software Development Guide.

Below are a few examples of what steps might be taken between resetting a Cortex-M7 system and the application reaching the main() function.


Example 1

ROM at address 0x0
RAM at address 0x20000000
Single binary image stored in ROM

  1. Processors boots from address 0x0 in Thread mode using the main stack by default.

  2. Processor loads:

    1. the main stack vector value at address 0x0 into the stack pointer (sp).
    2. the Reset vector value at address 0x4 into the program counter (pc).
  3. The program enters the Reset_Handler function.

  4. Subroutine call to SystemInit() - see description above.

  5. Direct branch to __main - see description above.

  6. Program enters main().


Example 2

TCM at address 0x00000000
ROM at address 0x10000000
RAM at address 0x20000000
Single binary image stored in ROM

  1. Processor boots from address 0x10000000 because the implementation is configured to use a different initial vector table address.

  2. Processor loads:

    1. the main stack vector value at address 0x10000000 into the stack pointer (sp).
    2. the Reset vector value at address 0x10000004 into the program counter (pc).
  3. Same as Example 1.

  4. Same as Example 1.

  5. Enable TCMs using code from the section titled "Enabling the TCM" from the Cortex-M7 TRM.

  6. Initiate transfer of a standalone "Main Application" stored somewhere in ROM to TCM memory, which has its own reset handler.

  7. Change the default vector table address to address 0x0, by writing to the Vector Table Offset Register (VTOR).

  8. Use code similar to the following to branch to the TCM code:

    #if defined ( __CC_ARM )
    /* ARM DS5 or Keil MDK */
    __asm void FlashLoader_ASM(void)
    {
      MOVS R0,#0
      LDR R1,[R0] ; Get initial MSP value
      MOV SP, R1
      LDR R1,[R0, #4] ; Get initial PC value
      BX R1
    }
    
    #else
    /* ARM GCC */
    void FlashLoader_ASM(void) __attribute__((naked));
    void FlashLoader_ASM(void)
    {
    __asm("movs r0,#0\n"
    "ldr r1,[r0]\n" /* Get initial MSP value */
    "mov sp, r1\n"
    "ldr r1,[r0, #4]\n" /* Get initial PC value */
    "bx r1\n");
    }
    #endif
  9. Main Application starts running - same as steps 1-6 from Example 1.


Example 3

TCM at address 0x00000000
ROM at address 0x10000000
Single binary image stored in ROM
TCM interfaces enabled at reset by an external signal on the processor

  1. Processors boots from address 0x0

  2. The CPUWAIT signal is HIGH out of reset, which keeps the processor from initiating its usual hardware boot-up routine.

  3. System hardware, e.g., a DMA controller, loads the TCMs with the binary image stored in ROM via the processor’s AHBS (AHB slave) port whilst CPUWAIT is asserted.

  4. Once TCM loading is complete the CPUWAIT signal is de-asserted to allow the processor to boot-up from TCM.

  5. Same as steps 1-6 from Example 1.


There are lots of other ways a system might boot. It might make use of some kind of remap controller to remap ROM to RAM dynamically at run-time. Also, there might be more than one type of ROM, for example, a small ROM where a bootloader is located and a larger flash memory that provides a location for standalone user applications. 

Also, there are many other tasks that a reset handler may need to perform, for example:

Most often these tasks execute within SystemInit().

If TCMs are implemented and DMA controller is integrated into the system, Example 3 could be the most efficient way for the system to start up, but obviously this will depend entirely on the application and system it is controlling.  Also, the sizes of the TCMs are device-dependent and often limited.  Therefore, a boot sequence may only be able to copy critical code and data such as the interrupt handler routines and the vector table into the TCMs. 

If you are interested to see what existing example startup code looks like on other Cortex-M devices, it is recommended to install MDK-ARM Microcontroller Development Kit from the Keil website. The evaluation version is free of charge. Once you have downloaded and installed the tools, you can install software packages (known as "packs") for different devices. Each pack contains example startup code for different Cortex-M processors and devices. For example, after installing the LPC1768 pack, seven examples are available in the following directory:

C:\Keil_v5\ARM\Pack\Keil\LPC1700_DFP\2.0.0\Boards\Keil\MCB1700

Also, there is a CMSIS "pack" that contains basic startup code for different Cortex-M processors, which should end up in a directory similar to:

C:\Keil_v5\ARM\Pack\ARM\CMSIS\4.3.0\Device\ARM\ARMCM7\Source

The examples work with the ARM Compiler, IAR and GCC toolchains. For further information about the software packs, please see the following pages of the Keil website:

http://www.keil.com/support/man/docs/uv4/uv4_ca_packinstaller.htm
http://www.keil.com/support/man/docs/uv4/uv4_ca_packinst_examples.htm

Article last edited on: 2015-07-31 15:17:05

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential