Mbed OS 文档翻译 之 参考(贡献(移植目标(引导)))

引导

带来 CMSIS-Core 文件

要使用 Mbed OS,您需要为 CMSIS-Core 文档描述的设备实施 CMSIS-Core 支持。CMSIS-Core 文件通常位于 mbed-os\targets\TARGET_<VENDOR>\TARGET_MCU_<FAMILY>\TARGET_<MCUNAME>\device 目录中。

启动文件

启动文件包含中断向量和低级核心和平台初始化例程。您需要为每个 Mbed OS 支持的工具链提供此文件的版本。

有关启动文件的更多信息,请参阅 CMSIS 文档

链接器脚本

添加核心文件后,下一步是为 Mbed OS 添加链接描述文件。为此,您可以使用下面的链接描述文件并更改目标的定义,也可以修改现有链接描述文件以与 Mbed OS 兼容。您需要为每个 Mbed OS 支持的工具链提供一个链接描述文件的版本。

如果要更新自己的链接描述文件,则必须:

  • RAM 向量表的预留空间。
  • 定义堆的开头:
    • Arm - 堆在 RW_IRAM1 区域之后立即启动。
    • GCC_ARM - 堆从符号 __end__ 开始。
    • IAR - 堆是 HEAP 区域。
    • 为可重新定位的应用程序添加定义 - MBED_APP_START 和 MBED_APP_SIZE。
    • 添加预处理指令 #!armcc -E(仅限 ARM 编译器)。

如果您使用以下链接描述文件,则需要更新目标的 /* 设备特定值 */ 部分中的所有定义。

Arm 链接器脚本模板:

#! armcc -E

/* Device specific values */

#define ROM_START   0x08000000
#define ROM_SIZE    0x200000
#define RAM_START   0x20000000
#define RAM_SIZE    0x30000
#define VECTORS     107   /* This value must match NVIC_NUM_VECTORS */

/* Common - Do not change */

#if !defined(MBED_APP_START)
  #define MBED_APP_START ROM_START
#endif

#if !defined(MBED_APP_SIZE)
  #define MBED_APP_SIZE ROM_SIZE
#endif

/* Round up VECTORS_SIZE to 8 bytes */
#define VECTORS_SIZE (((VECTORS * 4) + 7) & ~7)

LR_IROM1 MBED_APP_START MBED_APP_SIZE  {

  ER_IROM1 MBED_APP_START MBED_APP_SIZE  {
    *.o (RESET, +First)
    *(InRoot$$Sections)
    .ANY (+RO)
  }

  RW_IRAM1 (RAM_START + VECTORS_SIZE) (RAM_SIZE - VECTORS_SIZE)  {  ; RW data
    .ANY (+RW +ZI)
  }
}

IAR 链接器脚本模板:

/* Device specific values */

define symbol ROM_START   = 0x08000000;
define symbol ROM_SIZE    = 0x200000;
define symbol RAM_START   = 0x20000000;
define symbol RAM_SIZE    = 0x30000;
define symbol VECTORS     = 107; /* This value must match NVIC_NUM_VECTORS */
define symbol HEAP_SIZE   = 0x10000;

/* Common - Do not change */

if (!isdefinedsymbol(MBED_APP_START)) {
    define symbol MBED_APP_START = ROM_START;
}

if (!isdefinedsymbol(MBED_APP_SIZE)) {
    define symbol MBED_APP_SIZE = ROM_SIZE;
}

/* Round up VECTORS_SIZE to 8 bytes */
define symbol VECTORS_SIZE = ((VECTORS * 4) + 7) & ~7;
define symbol RAM_REGION_START = RAM_START + VECTORS_SIZE;
define symbol RAM_REGION_SIZE = RAM_SIZE - VECTORS_SIZE;
define symbol ISR_STACK_SIZE = 0x400;

define memory mem with size = 4G;
define region ROM_region = mem:[from MBED_APP_START size MBED_APP_SIZE];
define region RAM_region = mem:[from RAM_REGION_START size RAM_REGION_SIZE];

define block CSTACK    with alignment = 8, size = ISR_STACK_SIZE   { };
define block HEAP      with alignment = 8, size = HEAP_SIZE     { };

initialize by copy { readwrite };
do not initialize  { section .noinit };

place at address mem: MBED_APP_START { readonly section .intvec };

place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };

GCC 链接器脚本模板:

/* Device specific values */

#define ROM_START   0x08000000
#define ROM_SIZE    0x200000
#define RAM_START   0x20000000
#define RAM_SIZE    0x30000
#define VECTORS     107   /* This value must match NVIC_NUM_VECTORS */

/* Common - Do not change */

#if !defined(MBED_APP_START)
  #define MBED_APP_START ROM_START
#endif

#if !defined(MBED_APP_SIZE)
  #define MBED_APP_SIZE ROM_SIZE
#endif

/* Round up VECTORS_SIZE to 8 bytes */
#define VECTORS_SIZE (((VECTORS * 4) + 7) & 0xFFFFFFF8)

MEMORY
{
    FLASH (rx)   : ORIGIN = MBED_APP_START, LENGTH = MBED_APP_SIZE
    RAM (rwx)    : ORIGIN = RAM_START + VECTORS_SIZE, LENGTH = RAM_SIZE - VECTORS_SIZE
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __exidx_start
 *   __exidx_end
 *   __etext
 *   __data_start__
 *   __preinit_array_start
 *   __preinit_array_end
 *   __init_array_start
 *   __init_array_end
 *   __fini_array_start
 *   __fini_array_end
 *   __data_end__
 *   __bss_start__
 *   __bss_end__
 *   __end__
 *   end
 *   __HeapLimit
 *   __StackLimit
 *   __StackTop
 *   __stack
 */
ENTRY(Reset_Handler)

SECTIONS
{
    .text :
    {
        KEEP(*(.isr_vector))
        *(.text*)

        KEEP(*(.init))
        KEEP(*(.fini))

        /* .ctors */
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)

        /* .dtors */
         *crtbegin.o(.dtors)
         *crtbegin?.o(.dtors)
         *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
         *(SORT(.dtors.*))
         *(.dtors)

        *(.rodata*)

        KEEP(*(.eh_frame*))
    } > FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;

    /* Location counter can end up 2byte aligned with narrow Thumb code but
       __etext is assumed by startup code to be the LMA of a section in RAM
       which must be 4byte aligned */
    __etext = ALIGN (4);

    .data : AT (__etext)
    {
        __data_start__ = .;
        *(vtable)
        *(.data*)

        . = ALIGN(4);
        /* preinit data */
        PROVIDE_HIDDEN (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE_HIDDEN (__preinit_array_end = .);

        . = ALIGN(4);
        /* init data */
        PROVIDE_HIDDEN (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE_HIDDEN (__init_array_end = .);


        . = ALIGN(4);
        /* finit data */
        PROVIDE_HIDDEN (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE_HIDDEN (__fini_array_end = .);

        KEEP(*(.jcr*))
        . = ALIGN(4);
        /* All data end */
        __data_end__ = .;

    } > RAM

    .bss :
    {
        . = ALIGN(4);
        __bss_start__ = .;
        *(.bss*)
        *(COMMON)
        . = ALIGN(4);
        __bss_end__ = .;
    } > RAM

    .heap (COPY):
    {
        __end__ = .;
        PROVIDE(end = .);
        *(.heap*)
        __HeapLimit = .;
    } > RAM

    /* .stack_dummy section doesn't contains any symbols. It is only
     * used for linker to calculate size of stack sections, and assign
     * values to stack symbols later */
    .stack_dummy (COPY):
    {
        *(.stack*)
    } > RAM

    /* Set stack top to end of RAM, and stack limit move down by
     * size of stack_dummy section */
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    __StackLimit = __StackTop - SIZEOF(.stack_dummy);
    PROVIDE(__stack = __StackTop);

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

其他所需文件

  • 确保您的 CMSIS-Core 实现包含 device.h
  • 通过添加文件 mbed-os\targets\TARGET_VENDOR\TARGET_MCUNAME\cmsis.h 来扩展 CMSIS-Core。此头文件包含包含 CMSIS-Core 的特定于设备的标头。它还必须包括 cmsic_nvic.h。
  • 添加 mbed-os\targets\TARGET_VENDOR\TARGET_MCUNAME\cmsis_nvic.h 头文件。这包含定义 NVIC_NUM_VECTORS,它是设备具有的向量数,以及 NVIC_RAM_VECTOR_ADDRESS,它是 RAM 向量表的地址。 Mbed OS 将向量从 ROM 中的初始位置重新定位到 RAM 中提供的地址,并更新 VTOR 寄存器。注意:对于没有 VTOR 寄存器的器件,在执行到达 main 函数之前,需要确保向量在读写存储器中。在这种情况下,您可能还需要提供 NVIC 访问功能的可视化。有关详细信息,请参阅 CMSIS NVIC 文档
  • 在 mbed_rtx.h 中定义初始栈指针 INITIAL_SP。此文件通常位于 mbed-os\targets\TARGET_VENDOR\mbed_rtx.h 中。

猜你喜欢

转载自blog.csdn.net/u012325601/article/details/82216858
今日推荐