引导
带来 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 中。