主题中讨论的其他器件:SEGGER
工具与软件:
你好
我根据 TI 的应用手册实施了一个运行良好的仿真 EEPROM。 在链接器文件中、我 为仿真 EEPROM 保留了一个存储器区域。 由于较低的32kB 闪存地址空间支持较高的擦除/编程耐久性、 我将仿真 EEPROM 放置在闪存基址(0x0000.0000)、而主程序放置在闪存地址0x0000.1400。当调试器被连接时、这运行正常。 如果没有连接调试器、主程序将无法启动。
经过一些研究,我发现,调试器的设置或更精确的调试软件(SEGGER Ozone )处理矢量表的重定位,并正确设置程序计数器。
为解决此问题、我添加了一个具有引导加载程序堆栈的存储器区域、该堆栈中包含一个带有堆栈指针和复位处理程序的小矢量表。 然后、该复位处理程序执行到主应用程序复位处理程序的跳转。 这按预期运行。 正如我理解的那样、控制器默认期望在闪存基址上有一个带有堆栈指针和复位处理程序的矢量表。
由于仿真 EEPROM 的起始地址需要位于某个页地址、因此我为引导加载程序凸点保留了一个完整的闪存页、尽管它不需要那么多的闪存。
我宁愿仅为引导加载程序建立额外的存储器部分、并且具有自己的引导矢量表、而只具有基于地址0x0000.0000的主矢量表。 还有什么其他解决方案、那么我目前正在使用的解决方案吗? 我可以在两个非连续闪存区域之间以某种方式拆分我的主程序吗?
我的链接器文件:
/* Generate a link error if heap and stack don't fit into RAM */
_Min_Heap_Size = 0; /* required amount of heap */
_Min_Stack_Size = 0x80; /* required amount of stack */
/* Specify the memory areas */
MEMORY
{
FLASH_BOOT (RX) : ORIGIN = 0x00000000, LENGTH = 1K
EMULATED_EEPROM (RW) : ORIGIN = 0x00000400, LENGTH = 4K
FLASH (RX) : ORIGIN = 0x00001400, LENGTH = 123K
SRAM (RWX) : ORIGIN = 0x20200000, LENGTH = 32K
BCR_CONFIG (R) : ORIGIN = 0x41C00000, LENGTH = 0x00000080
BSL_CONFIG (R) : ORIGIN = 0x41C00100, LENGTH = 0x00000080
}
/* Note: SRAM length must match MPPC/MEMSS config! Please edit it manually. */
REGION_ALIAS("REGION_TEXT", FLASH);
REGION_ALIAS("REGION_PREINIT_ARRAY", FLASH);
REGION_ALIAS("REGION_INIT_ARRAY", FLASH);
REGION_ALIAS("REGION_FINI_ARRAY", FLASH);
REGION_ALIAS("REGION_BSS", SRAM);
REGION_ALIAS("REGION_NOINIT", SRAM);
REGION_ALIAS("REGION_DATA", SRAM);
REGION_ALIAS("REGION_STACK", SRAM);
REGION_ALIAS("REGION_HEAP", SRAM);
REGION_ALIAS("REGION_TEXT_RAM", SRAM);
REGION_ALIAS("REGION_ARM_EXIDX", FLASH);
REGION_ALIAS("REGION_ARM_EXTAB", FLASH);
/* Define output sections */
SECTIONS
{
/* section for the boot interrupt vector area */
PROVIDE (_intvecs_boot_base_address =
DEFINED(_intvecs_boot_base_address) ? _intvecs_boot_base_address : 0x00000000);
.intvecs_boot (_intvecs_boot_base_address) : AT (_intvecs_boot_base_address) {
. = ALIGN(0x4);
KEEP (*(.intvecs_boot))
. = ALIGN(0x4);
} > FLASH_BOOT
__emulated_eeprom_base_address = ORIGIN(EMULATED_EEPROM);
.emulated_eeprom : {
. = ALIGN(0x8);
KEEP (*(.emulated_eeprom))
. = ALIGN(0x8);
} > EMULATED_EEPROM
__program_base_address = ORIGIN(FLASH);
/* section for the interrupt vector area */
PROVIDE (_intvecs_base_address =
DEFINED(_intvecs_base_address) ? _intvecs_base_address : __program_base_address);
.intvecs (_intvecs_base_address) : AT (_intvecs_base_address) {
KEEP (*(.intvecs))
} > REGION_TEXT
PROVIDE (_vtable_base_address =
DEFINED(_vtable_base_address) ? _vtable_base_address : 0x20200000);
.vtable (_vtable_base_address) : AT (_vtable_base_address) {
KEEP (*(.vtable))
} > REGION_DATA
.text : {
CREATE_OBJECT_SYMBOLS
KEEP (*(.text))
. = ALIGN(0x8);
*(.text.*)
. = ALIGN(0x8);
KEEP (*(.ctors))
. = ALIGN(0x8);
KEEP (*(.dtors))
. = ALIGN(0x8);
KEEP (*(.init))
. = ALIGN(0x8);
KEEP (*(.fini*))
. = ALIGN(0x8);
} > REGION_TEXT AT> REGION_TEXT
.ramfunc : {
__ramfunct_load__ = LOADADDR (.ramfunc);
__ramfunct_start__ = .;
*(.ramfunc)
. = ALIGN(0x8);
__ramfunct_end__ = .;
} > REGION_TEXT_RAM AT> REGION_TEXT
.rodata : {
*(.rodata)
. = ALIGN(0x8);
*(.rodata.*)
. = ALIGN(0x8);
} > REGION_TEXT AT> REGION_TEXT
.preinit_array : {
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array*));
PROVIDE_HIDDEN (__preinit_array_end = .);
} > REGION_PREINIT_ARRAY AT> REGION_TEXT
.init_array : {
. = ALIGN(0x8);
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array*))
PROVIDE_HIDDEN (__init_array_end = .);
} > REGION_INIT_ARRAY AT> REGION_TEXT
.fini_array : {
. = ALIGN(0x8);
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array*))
PROVIDE_HIDDEN (__fini_array_end = .);
} > REGION_FINI_ARRAY AT> REGION_TEXT
.ARM.exidx : {
. = ALIGN(0x8);
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
. = ALIGN(0x8);
__exidx_end = .;
} > REGION_ARM_EXIDX AT> REGION_ARM_EXIDX
.ARM.extab : {
KEEP (*(.ARM.extab* .gnu.linkonce.armextab.*))
. = ALIGN(0x8);
} > REGION_ARM_EXTAB AT> REGION_ARM_EXTAB
__etext = .;
.data : {
__data_load__ = LOADADDR (.data);
__data_start__ = .;
KEEP (*(.data))
KEEP (*(.data*))
. = ALIGN (8);
__data_end__ = .;
} > REGION_DATA AT> REGION_TEXT
.bss : {
__bss_start__ = .;
*(.shbss)
KEEP (*(.bss))
*(.bss.*)
*(COMMON)
. = ALIGN (8);
__bss_end__ = .;
} > REGION_BSS AT> REGION_BSS
.noinit : {
/* place all symbols in input sections that start with .noinit */
KEEP(*(*.noinit*))
. = ALIGN (8);
} > REGION_NOINIT AT> REGION_NOINIT
.heap : {
__heap_start__ = .;
end = __heap_start__;
_end = end;
__end = end;
KEEP (*(.heap))
__heap_end__ = .;
__HeapLimit = __heap_end__;
} > REGION_HEAP AT> REGION_HEAP
.stack (NOLOAD) : ALIGN(0x8) {
_stack = .;
KEEP(*(.stack))
} > REGION_STACK AT> REGION_STACK
.BCRConfig :
{
KEEP(*(.BCRConfig))
} > BCR_CONFIG
.BSLConfig :
{
KEEP(*(.BSLConfig))
} > BSL_CONFIG
__StackTop = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK);
PROVIDE(__stack = __StackTop);
}