Hard Bus Fault i.MX RT1051

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Hard Bus Fault i.MX RT1051

2,217 Views
evelynsabbag
Contributor II

Hoping someone can help me with a Hard Bus Fault.

I’m running firmware on proprietary hardware with the NXP i.MX RT1051 as the MCU. The code is developed with MCUXpresso, gcc compiler and was extracted from the SDK examples created for the EVKB1050 eval board.  The memory map is as follows:

Type

Name

Alias

Location

Size

Driver

Flash

BOARD_FLASH

Flash

0x0

0x4000000

MIMXRT1050_SFDP_QSPI.cfx

RAM

SRAM_DTC

RAM

0x20000000

0x20000

 

RAM

SRAM_ITC

RAM2

0x4000000

0x20000

 

RAM

SRAM_OC

RAM3

0x20200000

0x40000

 

RAM

BOARD_SDRAM

RAM4

0x80000000

0x2000000

 

The System Control block Configuration and Control Register (SCB->CCR) is 0x070200 and the Memory Protection Unit is enabled.

The program uses FreeRTOS and LPUART4 (RS232), LWIP/Ethernet, and I2C1 (talks to a USB driver) and initially runs without error and indefinitely.

The problem comes in when the program code exceeds 128kB (131070). During the data_init routine, as soon as the code attempts to copy from a FLASH location > 128k, a Hard Bus Fault occurs.

A screen capture shows the register contents and assembler code when stepping into data_init. From this information, as soon as the ldr.w r4, [r0], #4 is executed where r0 = 0x20014, the Hard Bus Fault occurs. The registers after the Hard bus fault is provided in the attached screen shot.

Note that the Auxiliary Bus Fault Status Register (ABFSR) reports an Asynchronous fault on ITCM interface. According to various write-ups, an asynchronous fault is an Imprecise fault, not a Precise data bus error as reported by the Bus Fault Status register (BFSR), but this is the information I have.

 

As a side note, the same code runs without error on the Eval board, with the following memory map:

Type

Name

Alias

Location

Size

Driver

Flash

BOARD_FLASH

Flash

0x60000000

0x4000000

MIMXRT1050-EVK_S26KS512S.cfx

RAM

SRAM_DTC

RAM

0x20000000

0x20000

 

RAM

SRAM_ITC

RAM2

0x0

0x20000

 

RAM

SRAM_OC

RAM3

0x20200000

0x40000

 

RAM

BOARD_SDRAM

RAM4

0x80000000

0x2000000

 

I don't want to derail this discussion, but, as an added symptom, once the fault occurs, the debugger no longer works. If it's of any value, I will add that information as well.  

5 Replies

2,015 Views
evelynsabbag
Contributor II

Tech support at PEMicro solved the issue with enabling the external QSPI flash. One of the Boot Configuration resisters was incorrect and the boot block (posted previously in this thread), required 6 wait states instead of 4.

Thank you to everyone who responded to my question

2,015 Views
dmarks_ls
Senior Contributor I

Uhm, I'm a little confused.  You say you were able to duplicate your issue on the EVKB "by switching from the external flash (HYPERFLASH) to the internal flash (QSPI)".  Problem is, both of those are external flash devices; the RT1050 doesn't have any internal program flash memory.  What the RT1050 does have at address 0000_0000h is 128 KB of Instruction Tightly Coupled Memory (ITCM).  This is SRAM that, as far as I can tell, is intended to accelerate operation of certain program functions by allowing pieces of code to be copied into and executed from SRAM, or possibly provide a complete shadow of a program for sufficiently small programs (< 128 KB).  But it is not non-volatile flash memory.

Modifying your memory map to try to locate board flash at 0000_0000h won't work; SRAM_ITC lives there, it can't be reassigned.  I'm not sure what you're doing changing the address of SRAM_ITC to 0400_0000h; that's a reserved memory location.  See the RT1050 Reference Manual, chapter 2 "Memory Maps", table 2-1 "System memory map".  I'm guessing that what you're actually doing is downloading your program into SRAM_ITC at address 0000_0000h using your debug probe and running directly out of RAM.  I'm also guessing that if you then remove power from your board, then power it up again, nothing runs, because SRAM_ITC is volatile memory.  I'm also guessing this is why your program craps out if it's bigger than 128 KB and also why your debug probe craps out; it's trying to access memory that just isn't there.

HyperFlash (octal SPI memory) and QSPI (quad SPI memory) are just two different external memory devices on the EVKB.  The EVKB code examples assume that you're using HyperFlash as your program memory.  The HyperFlash (S26K512S) and QSPI (IS25WP064A) flash devices are connected to the same FlexSPI bus pins on the EVKB; the QSPI device is by default completely disconnected from the processor (see the EVKB schematics, page 11, "1V8 QSPI Flash").  To use it, you have to install the six 0402 jumpers indicated and also remove (at a minimum) the CS1*/SS0 jumper to the HyperFlash.  You would also need to change the bootstrap jumper settings.  But I'm guessing you may not want to go through the trouble.  (FWIW, I do have an RT1050 and QSPI flash working on a custom board.)

 

The external flash memory is mapped to region 6000_0000h, whether it's HyperFlash or QSPI flash.  There is 128 KB of SRAM_ITCM at 0000_0000h.  Don't confuse the two.

David R.

0 Kudos

2,015 Views
dmarks_ls
Senior Contributor I

Hi Evelyn,

Did this address your issue?

David R.

0 Kudos

2,015 Views
evelynsabbag
Contributor II

I was able to get the QSPI working on the eval board, but not the proprietary PCB; the trouble is worth it as the proprietary board has a QSPI memory (different manufacturer/size than the eval) on it and it streamlines the development to compare similar circuits. The modification to the code (evkbimxrt1050_flexspi_nor_config.c) is as follows (with the appropriate defines):

/*
* Copyright 2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

#include "evkbimxrt1050_flexspi_nor_config.h"

#define EvalBoard 1
#define HyperFlash 0

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.xip_board"
#endif

/*******************************************************************************
* Code
******************************************************************************/
#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1)
#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__)
__attribute__((section(".boot_hdr.conf")))
#elif defined(__ICCARM__)
#pragma location = ".boot_hdr.conf"
#endif
#if HyperFlash
const flexspi_nor_config_t hyperflash_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_ExternalInputFromDqsPad,
.csHoldTime = 3u,
.csSetupTime = 3u,
.columnAddressWidth = 3u,
// Enable DDR mode, Wordaddassable, Safe configuration, Differential clock
.controllerMiscOption =
(1u << kFlexSpiMiscOffset_DdrModeEnable) | (1u << kFlexSpiMiscOffset_WordAddressableEnable) |
(1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DiffClkEnable),
.sflashPadType = kSerialFlash_8Pads,
.serialClkFreq = kFlexSpiSerialClk_133MHz,
.sflashA1Size = 64u * 1024u * 1024u,
.dataValidTime = {16u, 16u},
.lookupTable =
{
// Read LUTs
FLEXSPI_LUT_SEQ(CMD_DDR, FLEXSPI_8PAD, 0xA0, RADDR_DDR, FLEXSPI_8PAD, 0x18),
FLEXSPI_LUT_SEQ(CADDR_DDR, FLEXSPI_8PAD, 0x10, DUMMY_DDR, FLEXSPI_8PAD, 0x06),
FLEXSPI_LUT_SEQ(READ_DDR, FLEXSPI_8PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),
},
},
.pageSize = 512u,
.sectorSize = 256u * 1024u,
.blockSize = 256u * 1024u,
.isUniformBlockSize = true,
};
#else
const flexspi_nor_config_t qspiflash_config = {
.memConfig =
{
.tag = FLEXSPI_CFG_BLK_TAG,
.version = FLEXSPI_CFG_BLK_VERSION,
.readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
.csHoldTime = 3u,
.csSetupTime = 3u,
// Enable DDR mode, Wordaddassable, Safe configuration, Differential clock
.sflashPadType = kSerialFlash_4Pads,
.serialClkFreq = kFlexSpiSerialClk_100MHz,
.sflashA1Size = 8u * 1024u * 1024u,
// .sflashA1Size = 64u * 256u * 1024u,
.lookupTable =
{
// Read LUTs
#if EvalBoard
//IS25WP064A
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
#else
//W25Q32
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x04, READ_SDR, FLEXSPI_4PAD, 0x04),
#endif //EvalBoard

},
},
.pageSize = 256u,
#if EvalBoard
//IS25WP064A
.sectorSize = 4u * 1024u,
.blockSize = 256u * 1024u,
#else
//W25Q32
.sectorSize = 16u * 256u, // 16 pages = sector
.blockSize = 128u * 256u, // 128 pages = block
#endif //EvalBoard
.isUniformBlockSize = false,
};
#endif //HyperFlash
#endif /* XIP_BOOT_HEADER_ENABLE */

0 Kudos

2,015 Views
evelynsabbag
Contributor II

This fault originally occurred on proprietary hardware, but I was able to duplicate it on the IMXRT1050-EVKB eval board by switching from the external flash (HYPERFLASH) to the internal flash (QSPI). By starting with the evkbimxrt1050_freertos_hello example (only peripheral is the UART) and increasing the code to over 128kB (added in PRINTF statements - brought code size to 131076B), the debugger faults out and the program won't run. The error message is that the Load failed. Just under (tweaked it to 131068 bytes) and the code runs without error.