ハードウェア構成:
問題の説明: QSPI 内部メモリに単純なブートローダを実装し、SDRAM (32 MB) の FlexSpi インターフェイスを初期化し、XIP 実行のために外部 QSPI メモリに格納されたアプリケーションにジャンプすることに成功しました。この設定は、基本的な「hello world」アプリケーション(LEDの点滅とコンソール出力)で正しく機能します。
しかし、広範な C++ コードを含み、グラフィック コントローラーを使用するより複雑なアプリケーションを実行しようとすると、システムはすぐに一見ランダムなアドレスからのハード フォールトに遭遇します。同じアプリケーションが内部QSPIメモリで完全に動作します。
初期化に使用されるコード (sdk boards/evkmimxrt1064/driver_examples/flexspi/nor/polling_transfer の例polling_transferに基づく):
static void init_qspi_flash_on_front_panel(void)
{
SETUP(IOMUXC_GPIO_AD_B1_09_FLEXSPIA_DQS, 1, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
SETUP(IOMUXC_GPIO_AD_B1_10_FLEXSPIA_DATA03, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
SETUP(IOMUXC_GPIO_AD_B1_11_FLEXSPIA_DATA02, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
SETUP(IOMUXC_GPIO_AD_B1_12_FLEXSPIA_DATA01, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
SETUP(IOMUXC_GPIO_AD_B1_13_FLEXSPIA_DATA00, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
SETUP(IOMUXC_GPIO_AD_B1_14_FLEXSPIA_SCLK, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
SETUP(IOMUXC_GPIO_AD_B1_15_FLEXSPIA_SS0_B, 0, IOMUX_KEEPER_DOWN | IOMUX_SPD_MAX | IOMUX_DSE(6) | IOMUX_SLEW_FAST);
}void init_ext_flex_spi()
{
uint32_t i = 0;
status_t status;
uint8_t vendorID = 0;
flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
/* Get vendor ID. */
status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);
if (status != kStatus_Success)
{
LOG("FAIL flexspi_nor_get_vendor_id");
Q_ASSERT(false);
}
LOG("Vendor ID: 0x%x\r\n", vendorID);
/* Enter quad mode. */
status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
if (status != kStatus_Success)
{
LOG("FAIL flexspi_nor_enable_quad_mode");
Q_ASSERT(false);
}
}void flexspi_nor_flash_init(FLEXSPI_Type *base)
{
flexspi_config_t config;
#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
flexspi_cache_status_t cacheStatus;
flexspi_nor_disable_cache(&cacheStatus);
#endif
flexspi_clock_init();
/*Get FLEXSPI default settings and configure the flexspi. */
FLEXSPI_GetDefaultConfig(&config);
/*Set AHB buffer size for reading data through AHB bus. */
config.ahbConfig.enableAHBPrefetch = true;
config.ahbConfig.enableAHBBufferable = true;
config.ahbConfig.enableReadAddressOpt = true;
config.ahbConfig.enableAHBCachable = true;
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
FLEXSPI_Init(base, &config);
/* Configure flash settings according to serial flash feature. */
FLEXSPI_SetFlashConfig(base, &deviceconfig, FLASH_PORT);
/* Update LUT table. */
FLEXSPI_UpdateLUT(base, 0, customLUT, CUSTOM_LUT_LENGTH);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
#if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN
flexspi_nor_enable_cache(cacheStatus);
#endif
}flexspi_device_config_t deviceconfig = {
.flexspiRootClk = 120000000,
.flashSize = FLASH_SIZE,
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
.CSInterval = 2,
.CSHoldTime = 3,
.CSSetupTime = 3,
.dataValidTime = 0,
.columnspace = 0,
.enableWordAddress = 0,
.AWRSeqIndex = 0,
.AWRSeqNumber = 0,
.ARDSeqIndex = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD,
.ARDSeqNumber = 1,
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
.AHBWriteWaitInterval = 0,
};void flexspi_clock_init()
{
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24);
CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2); /* flexspi clock 120M. */
}FlexSpi クロックは 120MHz に設定されています。PLL2_PFD2を396MHzに設定し、FlexSpiディバイダーを3に設定して)132MHzに増やそうとしましたが、ベンダーIDの読み取りが正しく行われませんでした。
支援の要請:
ご協力いただきありがとうございます。
Michael