configs/metro-m4: Add an option to build the Metro M4 image to run out of SRAM. This ought to be a safer and quicker way to do the initial bring-up (having bricked the first Metro M4 due to a bad FLASH image).

This commit is contained in:
Gregory Nutt 2018-08-03 15:26:44 -06:00
parent bbee0d70de
commit 9b7e5ede0a
6 changed files with 207 additions and 8 deletions

View File

@ -271,7 +271,9 @@ static void go_os_start(void *pv, unsigned int nbytes)
void __start(void)
{
#if defined(CONFIG_BOOT_RUNFROMFLASH) || defined(CONFIG_ARCH_RAMFUNCS)
const uint32_t *src;
#endif
uint32_t *dest;
#ifdef CONFIG_ARMV7M_STACKCHECK
@ -289,6 +291,7 @@ void __start(void)
*dest++ = 0;
}
#ifdef CONFIG_BOOT_RUNFROMFLASH
/* Move the initialized data section from his temporary holding spot in
* FLASH into the correct place in SRAM. The correct place in SRAM is
* give by _sdata and _edata. The temporary location is in FLASH at the
@ -299,15 +302,16 @@ void __start(void)
{
*dest++ = *src++;
}
#endif
#ifdef CONFIG_ARCH_RAMFUNCS
/* Copy any necessary code sections from FLASH to RAM. The correct
* destination in SRAM is geive by _sramfuncs and _eramfuncs. The
* temporary location is in flash after the data initalization code
* destination in SRAM is given by _sramfuncs and _eramfuncs. The
* temporary location is in flash after the data initialization code
* at _framfuncs. This must be done before sam_clockconfig() can be
* called (at least for the SAM4L family).
*/
#ifdef CONFIG_ARCH_RAMFUNCS
for (src = &_framfuncs, dest = &_sramfuncs; dest < &_eramfuncs; )
{
*dest++ = *src++;
@ -333,7 +337,7 @@ void __start(void)
/* For the case of the separate user-/kernel-space build, perform whatever
* platform specific initialization of the user memory is required.
* Normally this just means initializing the user space .data and .bss
* segements.
* segments.
*/
#ifdef CONFIG_BUILD_PROTECTED

View File

@ -4,4 +4,29 @@
#
if ARCH_BOARD_METRO_M4
endif
choice
prompt "Execution memory"
default METRO_M4_RUNFROMFLASH
config METRO_M4_RUNFROMFLASH
bool "Run from FLASH"
select BOOT_RUNFROMFLASH
---help---
This is the normal configuration for building METRO M4 code.
config METRO_M4_RUNFROMSRAM
bool "Run from SRAM"
select BOOT_RUNFROMISRAM
---help---
During early bring-up, it is safer to execute entirely from
SRAM until you are confident in the initialization logic.
Then you can safely switch to FLASH.
REVISIT: This auto-selects CONFIG_BOOT_RUNFROMISRAM but I have
found, with some difficulty, that that choice still defaults to
CONFIG_BOOT_RUNFROMFLASH, causing link-time failures when running
from SRAM.
endchoice # Execution memory
endif # ARCH_BOARD_METRO_M4

View File

@ -18,6 +18,16 @@ README
o Built in crypto engines with AES (256 bit), true RNG, Pubkey controller
o 64 QFN
Contents
========
o STATUS
o Unlocking FLASH
o Serial Console
o LEDs
o Run from FLASH
o Configurations
STATUS
======
@ -47,9 +57,13 @@ STATUS
This is most likely a consequence of something happening in the NuttX
boot-up sequence that interferes with JTAG operation. When I continue
debugging in the future, I will put an infinitel loop, branch-on-self
debugging in the future, I will put an infinite loop, branch-on-self
at the code startup up (__start) so that I can attached the debugger
and step through the initial configuration.
2019-08-03: Added a configuration option to run out of SRAM vs FLASH.
This should be a safer way to do the initial board bring-up since
it does not modify the FLASH image nor does it require unlocking
the FLASH pages.
Unlocking FLASH
===============
@ -178,6 +192,38 @@ LEDs
------ ----------------- -----------
D13 PA16 GPIO output
Run from FLASH
==============
I bricked my first Metro M4 board because there were problems in the
bring-up logic. These problems left the chip in a bad state that was
repeated on each reset because the code was written into FLASH and I was
unable to ever connect to it again via SWD.
To make the bring-up less risky, I added a configuration option to build
the code to execution entirely out of SRAM. By default, the setting
CONFIG_METRO_M4_RUNFROMFLASH=y is used and the code is built to run out of
FLASH. If CONFIG_METRO_M4_RUNFROMSRAM=y is selected instead, then the
code is built to run out of SRAM.
To use the code in this configuration, the program must be started a
little differently:
gdb> mon reset
gdb> mon halt
gdb> load nuttx << Load NuttX into SRAM
gdb> file nuttx << Assuming debug symbols are enabled
gdb> mon memu32 0x20000000 << Get the address of initial stack
gdb> mon reg sp 0x200161c4 << Set the initial stack pointer using this address
gdb> mon memu32 0x20000000 << Get the address of __start entry point
gdb> mon reg pc 0x20000264 << Set the PC using this address
gdb> si << Step in just to make sure everything is okay
gdb> [ set breakpoints ]
gdb> c << Then continue until you hit the breakpoint
Where 0x200161c4 and 0x20000264 are the values of the initial stack and
the __start entry point that I read from SRAM
Configurations
==============

View File

@ -37,7 +37,11 @@ include ${TOPDIR}/.config
include ${TOPDIR}/tools/Config.mk
include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
LDSCRIPT = flash.ld
ifeq ($(CONFIG_METRO_M4_RUNFROMFLASH),y)
LDSCRIPT = flash.ld
else ifeq ($(CONFIG_METRO_M4_RUNFROMSRAM),y)
LDSCRIPT = sram.ld
endif
ifeq ($(WINTOOL),y)
# Windows-native toolchains

View File

@ -1,5 +1,5 @@
/****************************************************************************
* configs/metro-m4/scripts/ld.script
* configs/metro-m4/scripts/flash.ld
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>

View File

@ -0,0 +1,120 @@
/****************************************************************************
* configs/metro-m4/scripts/sram.ld
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/* The ATSAMD51J19 has 512Kb of FLASH beginning at address 0x0000:0000 and
* 192Kb of SRAM at address 0x2000:0000. Only sram is used by this linker
* script.
*/
MEMORY
{
flash (rx) : ORIGIN = 0x00000000, LENGTH = 512K
sram (rwx) : ORIGIN = 0x20000000, LENGTH = 192K
}
OUTPUT_ARCH(arm)
ENTRY(_stext)
EXTERN(_vectors)
SECTIONS
{
.text :
{
_stext = ABSOLUTE(.);
*(.vectors)
*(.text .text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata .rodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.got)
*(.gcc_except_table)
*(.gnu.linkonce.r.*)
_etext = ABSOLUTE(.);
} > sram
.init_section :
{
_sinit = ABSOLUTE(.);
*(.init_array .init_array.*)
_einit = ABSOLUTE(.);
} > sram
.ARM.extab :
{
*(.ARM.extab*)
} > sram
__exidx_start = ABSOLUTE(.);
.ARM.exidx :
{
*(.ARM.exidx*)
} > sram
__exidx_end = ABSOLUTE(.);
.data :
{
_sdata = ABSOLUTE(.);
*(.data .data.*)
*(.gnu.linkonce.d.*)
CONSTRUCTORS
_edata = ABSOLUTE(.);
} > sram
.bss :
{
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
_ebss = ABSOLUTE(.);
} > sram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}