This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM6442:闪存打开失败

Guru**** 2434370 points
Other Parts Discussed in Thread: AM6442, SYSCONFIG

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1535663/am6442-flash-open-fails

器件型号:AM6442
主题: SysConfig 中讨论的其他器件

工具/软件:

我尝试从 AM6442 的 R5F0-0 内核打开闪存、但 Board_driversOpen 函数未成功完成。

请就如何解决问题提供一些建议。

背景

首先、我使用调试器来查找故障发生的位置。

结果、我发现 FLASH_nor_ospi.c 的第 151 行上的 Flash_norOspiCmdRead 出现故障、并且程序正在等待超时。

在 SysConfig 设置中选中 Skip HW Init、可解决此非终止状态。

但是、似乎闪存打开本身已失败、UART 的调试输出显示“闪存打开失败、例如 0!!!“。

在搜索故障发生的位置后、我在 flash_nor_ospi.c 的第 901 行上找到了“status = SystemP_Failure“

发生故障的原因是读取的 ManufacturerId 和 deviceId 与​​SysConfig 中设置的值不同。

​​读出的 ID 值如下:ManufacturerId = 0xFF deviceId = oxFFFF

注释

-闪存型号: MT25QL01GBB8E12_0SIT (Micron )

-使用一个名为“xxx"的“的 RTOS。

-使用的开发环境与 RTOS 相匹配。

-其他功能,如 GPIO 和 UART 已确认可正常工作。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    我看到您使用的闪存是: 闪存型号:MT25QL01GBBB8E12_0SIT (Micron)

    我希望您首先运行 OSPI 闪存诊断以获取闪存配置:  software-dl.ti.com/.../CUSTOM_FLASH_SUPPORT_GUIDE.html

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    ​​读出的 ID 值如下:ManufacturerId = 0xFF deviceId = oxFFFF

    制造和器件 ID 错误打印的原因是 SysConfig 中的闪存配置不正确。

    接下来、您检查应用程序的 SysConfig 文件、即 example.syscfg

    使用该选项卡后、您可以打开 GUI、然后会看到 OSPI 和闪存部分。

    我们需要转到“Flash"部分“部分、然后直接填充获得的值。

    请参阅: https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/11_00_00_15/exports/docs/api_guide_am64x/CUSTOM_FLASH_SUPPORT_GUIDE.html#autotoc_md681

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    按照引用 URL 中的方法、我将“JSON Data for the flash“后续的信息保存到 JSON 文件中、并使用“load from JSON“按钮将其加载到 Sysconfig 中。

    ti_board_open_close.c 的内容发生了变化、因此我替换了源代码并再次运行、但结果没有变化。

    ManufacturerId 和 deviceId 变为无效值​​、闪存打开失败。

    我应该检查什么?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    修改值后、请继续运行 OSPI 闪存 IO 应用。

    如果这导致制造和器件 ID 读取失败、请继续并向我发送 SysConfig 和 OSPI 设置中闪存设置的屏幕截图。

    此致、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是 ID 读取失败时的 SysConfig 屏幕截图。

    ospi 设置

    闪存设置

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    谢谢、我现在将这些值与数据表进行了比较。 我将向您介绍进一步的调查结果。

    此致、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    以下是我的想法:

    1. 我看到您使用的闪存没有 DQS 行。 因此、 可以在 OSPI 部分的 SysConfig 中取消选中此引脚 N19。 我要参考以下数据表: https://mm.digikey.com/Volume0/opasdata/d220001/medias/docus/2293/MT25QU01GBBB_DS.pdf、 如果不是这一个、我应该使用哪一个作为参考?
    2. 删除了闪存部分中的 Quirks 功能选项。
    3. 在 FLASH 部分、
      1. 将读取命令从 0x6C 设置为 0x6B
      2. 将写入/页面编程命令从 0x34 设置为 0x32
      3. 取消选中“Enable 4 byte addressing“选项

    这里的目标是首先使闪存在 3 字节寻址模式下运行、然后我们可以稍后寻找 4 字节寻址模式。

    如果您在读取制造商和器件 ID 时仍然遇到问题、那么我可以建议使用下一组调试步骤。

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    执行 2. 意思是“将 Quirks 函数选项字段留空“? 如果 quirks function options 字段留空、则会发生错误、构建将不会继续。

    我执行了 1 次测试。 和 3. 而且已经建成、但状态没有变化。 两个 ID 未正确读取、闪存打开失败。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    does 2. 意思是“将 Quirks 函数选项字段留空“? 如果 quirks function options 字段留空、则会发生错误、构建将不会继续。

    将此值设置为 NULL

    i 执行了 1. 和 3. 而且已经建成、但状态没有变化。 两个 ID 未正确读取、闪存打开失败。

    请阅读以下指南:尽管对于 AM243、但也可以遵循对于 AM64x。

    从获取闪存的 OSPI 闪存诊断开始、这是一个很好的开端。  

    现在、我们需要通过以下方式开始验证:

    1. 运行 OSPI 闪存 IO 应用:
      1. 在 1s-1s-1s 模式中、首先确保与闪存的连接有效并且闪存实际正在运行。
      2. 在 1s 到 1s 模式下进行验证后、我们需要使用您所选的协议(闪存支持该协议)重新运行该应用程序。
    2. 如果客户在以 1-1s-1s 模式运行 OSPI 闪存 IO 时遇到问题、则可以在此处通过 e2e 报告确切的故障点、然后提供更多详细信息。
    3. 如何运行第一步:OSPI 闪存 IO 应用?
      1. 下载 Tera Term 软件。
      2. 打开 Tera Term 软件并为 AM243 打开 UART 的 COM 端口 X。
      3. 将电路板设置为 UART 引导模式。
      4. 以以下方式发送 SBL NULL 释放 HS FS 文件[为了知道是否需要刷写 HS FS 或 GP 映像、请通读此内容来检查器件类型: https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1228618/faq-am6xx-how-to-check-if-device-type-is-hs-se-hs-fs-or-gp  ]


        注意:  您需要发送一次、然后再发送一次、因为这样会克服热复位勘误表。 因此、基本上、逐个发送同一个 SBL NULL 版本 HS FS 文件两次。

      5. 完成后、内核将初始化、之后您可以打开 CCS 并从目标配置创建 AM243 .ccxml 文件。
      6. 连接到 CCS 中的内核、并根据您找到的 OSPI 闪存诊断日志加载修改后的 OSPI 闪存 IO。 从此处开始尝试步骤 1。

    如果需要进一步说明、请告诉我。

    注意:  请确保如果您遇到错误、请逐行调试并告诉我确切的一点、以便我可以更好地解决问题。

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    将“NULL"输入“输入到 quirks 函数选项中时、构建通过。

    即使满足所有三个条件、状态也不会发生变化。

    当协议更改为“1s-1s-1s"时“时也会发生同样的情况、并且使用“load from JSON“按钮反映设置。

    但是、此时使用了“topper RTOS + RTOS Debugger“环境。 它尚未在“CCS + XDS200“环境中运行。

    检查执行环境时、发现了几个可能与此问题相关的项目。

    如果其中有任何错误用法、请告知我们。

    -引导模式设置为 OSPI 引导模式。

    -尝试使用用应用程序写入的 SBL 打开闪存。

    -使用了基于示例代码“sbl_null"的“的 SBL ,但 OSPI 和闪存设置尚未添加到 sysconfig

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在 quirks 函数选项中输入“NULL"时“时传递的构建。

    感谢您的确认。

    引导模式设置为 OSPI 引导模式

    如果引导模式设置为 OSPI 引导模式、这将不起作用、因为您有 QSPI 闪存。

    我想请您阅读以下答复:  

    一种很好的方法是读取引导在特定引导模式中的发生方式。

    例如:

    SPI 引导模式:发出 1s-11-1s 运行和 0x3 命令、后跟 24 位地址和 0 个虚拟周期。

    xSPI 引导模式:1s-1s-1s 运行和 0xB(快速读取)命令是发出的、后跟 24 位地址和 8 个虚拟周期。

    现在回到闪存数据表:

    对于 SPI 引导模式、TRM 中的说明与闪存数据表中提到的内容相匹配:

    对于 xSPI 引导模式、该说明也与 TRM 匹配:

    因此、是的、在 SPI 和 xSPI(1S-1S-1s 快速读取)中引导是可以的。

    让我们在 QSPI 引导模式及其运行方式上放置一些石灰光。

    您看到、在上述闪存数据表说明中提到发出 0x6B + 24 位地址+ 8 个虚拟时钟

    AM64x 的 TRM 中也提到了同样的情况:  发出 0x6B + 24 位地址+ 8 个虚拟时钟

    但从闪存数据表中可以看出、一件事非常重要:

    “需要发出四路模式命令 35h、以进入四路输入/输出模式、从而从 QSPI BOOTMODE 引导“

    目前、ROM 本身不支持发送四路模式使能命令。

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我检查了直到现在所使用的引导模式。

    正如您所指出的、OSPI 引导模式不正确。我使用的是 QSPI 引导模式。

    我还确认在更改为 OSPI 引导模式并启动时它是有效的。

    在此状态下运行时、我无法确认来自 UART 的 SBL_NULL 调试输出。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、

    正如您所指出的、OSPI 引导模式不正确。我使用的是 QSPI 引导模式。

    感谢您的感谢。

    我还确认了在更改为 OSPI 引导模式并启动时它是有效的。

    是否要在此处写入 QSPI 引导模式而不是 OSPI 引导模式、请重新确认?

    在此状态下运行时、我无法确认来自 UART 的 SBL_NULL 调试输出。

    请进一步澄清这一个。

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不知道如何引用注释、因此我使用>符号。

    >是否要在此处写入 QSPI 引导模式而不是 OSPI 引导模式、请重新确认?

    我确认当设置为 OSPI 引导模式时、它无法正常工作。 “OPSI"不“不是一个拼写错误。

    >请进一步澄清这一问题。

    我尝试确认是否混合了引导模式设置 OSPI 和 QSPI。

    我可以使用万亿次方程检查 UART 的输出、并为 AM6442 提供电源。

    当我在 QSPI 引导模式下执行此操作时、我能够看到以万亿个术语开头的显示、以“Starting NULL Bootloader...“开头。

    当我在 OSPI 引导模式下执行此操作时、Tera Term 上不会显示任何内容。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Hi Takeshi、

    [报价 userid=“656475" url="“ url="~“~/support/processors-group/processors/f/processors-forum/1535663/am6442-flash-open-fails/5923976

    当我在 QSPI 引导模式下执行此操作时、我能够看到以万亿个术语开头的显示、以“Starting NULL Bootloader...“开头。

    当我在 OSPI 引导模式下执行此操作时、Tera Term 上不会显示任何内容。

    [/报价]

    因此、您使用的闪存将不支持以 OSPI 引导模式进行引导、因为闪存本身不支持该引导模式。

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    由于在“topper OS IDE +专用调试器“环境中闪存打开失败、因此在“CCS+XDS200"环境“环境中运行了以下测试代码。

    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <string.h>
    
    #define APP_OSPI_FLASH_OFFSET_BASE  (0x200000U)
    
    #define APP_OSPI_DATA_SIZE (2048)
    uint8_t gOspiTxBuf[APP_OSPI_DATA_SIZE];
    /* read buffer MUST be cache line aligned when using DMA, we aligned to 128B though 32B is enough */
    uint8_t gOspiRxBuf[APP_OSPI_DATA_SIZE] __attribute__((aligned(128U)));
    
    void ospi_flash_io_fill_buffers(void);
    int32_t ospi_flash_io_compare_buffers(void);
    
    void ospi_flash_io_main(void *args)
    {
        int32_t status = SystemP_SUCCESS;
        uint32_t offset;
        uint32_t blk, page;
        Flash_Attrs *flashAttrs;
        char stepflag[80];
    
        /* Open OSPI Driver, among others */
        Drivers_open();
        /* Open Flash drivers with OSPI instance as input */
        status = Board_driversOpen();
        DebugP_assert(status==SystemP_SUCCESS);
    
        flashAttrs = Flash_getAttrs(CONFIG_FLASH0);
    
        DebugP_log("Execute step by step?(y = step by step):");
        DebugP_scanf("%s", &stepflag);
    
        /* Fill buffers with known data,
         * find block number from offset,
         * erase block, write the data, read back from a specific offset
         * and finally compare the results.
         */
    
        offset = APP_OSPI_FLASH_OFFSET_BASE;
        ospi_flash_io_fill_buffers();
        status = OSPI_enableDacMode(gOspiHandle[CONFIG_FLASH0]);
        if(strcmp(stepflag, "y") == 0)
        {
            do
            {
                stepflag[0] = '\0';
                DebugP_log("Continue?(y = Continue):");
                DebugP_scanf("%s", &stepflag);
            }while(strcmp(stepflag, "y") != 0);
        }
    
        Flash_offsetToBlkPage(gFlashHandle[CONFIG_FLASH0], offset, &blk, &page);
        status = Flash_eraseBlk(gFlashHandle[CONFIG_FLASH0], blk);
    
        if(status == SystemP_SUCCESS)
        {
            DebugP_log("Block Erase of %d bytes Success at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
        }
        else
        {
            DebugP_log("Block Erase of %d bytes Fail at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
        }
        if(SystemP_SUCCESS == status)
        {
            if(strcmp(stepflag, "y") == 0)
            {
                do
                {
                    stepflag[0] = '\0';
                    DebugP_log("Continue?(y = Continue):");
                    DebugP_scanf("%s", &stepflag);
                }while(strcmp(stepflag, "y") != 0);
            }
    
            status = Flash_write(gFlashHandle[CONFIG_FLASH0], offset, gOspiTxBuf, APP_OSPI_DATA_SIZE);
            if(status == SystemP_SUCCESS)
            {
                DebugP_log("Flash Write of %d bytes Success at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
            }
            else
            {
                DebugP_log("Flash Write of %d bytes Fail at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
            }
        }
        if(SystemP_SUCCESS == status)
        {
            if(strcmp(stepflag, "y") == 0)
            {
                do
                {
                    stepflag[0] = '\0';
                    DebugP_log("Continue?(y = Continue):");
                    DebugP_scanf("%s", &stepflag);
                }while(strcmp(stepflag, "y") != 0);
            }
    
            status = OSPI_enableDacMode(gOspiHandle[CONFIG_FLASH0]);
            status = Flash_read(gFlashHandle[CONFIG_FLASH0], offset, gOspiRxBuf, APP_OSPI_DATA_SIZE);
            if(status == SystemP_SUCCESS)
            {
                DebugP_log("Flash Read of %d bytes Success at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
            }
            else
            {
                DebugP_log("Flash Read of %d bytes Fail at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
            }
        }
        if(SystemP_SUCCESS == status)
        {
            status |= ospi_flash_io_compare_buffers();
        }
    
        offset = APP_OSPI_FLASH_OFFSET_BASE + (flashAttrs->blockSize*2);
        ospi_flash_io_fill_buffers();
    
        if(strcmp(stepflag, "y") == 0)
        {
            do
            {
                stepflag[0] = '\0';
                DebugP_log("Continue?(y = Continue):");
                DebugP_scanf("%s", &stepflag);
            }while(strcmp(stepflag, "y") != 0);
        }
    
        Flash_offsetToBlkPage(gFlashHandle[CONFIG_FLASH0], offset, &blk, &page);
        status = Flash_eraseBlk(gFlashHandle[CONFIG_FLASH0], blk);
    
        if(status == SystemP_SUCCESS)
        {
            DebugP_log("Block Erase of %d bytes Success at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
        }
        else
        {
            DebugP_log("Block Erase of %d bytes Fail at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
        }
        if(SystemP_SUCCESS == status)
        {
            if(strcmp(stepflag, "y") == 0)
            {
                do
                {
                    stepflag[0] = '\0';
                    DebugP_log("Continue?(y = Continue):");
                    DebugP_scanf("%s", &stepflag);
                }while(strcmp(stepflag, "y") != 0);
            }
    
            status = Flash_write(gFlashHandle[CONFIG_FLASH0], offset, gOspiTxBuf, APP_OSPI_DATA_SIZE);
            if(status == SystemP_SUCCESS)
            {
                DebugP_log("Flash Write of %d bytes Success at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
            }
            else
            {
                DebugP_log("Flash Write of %d bytes Fail at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
            }
        }
        if(SystemP_SUCCESS == status)
        {
            if(strcmp(stepflag, "y") == 0)
            {
                do
                {
                    stepflag[0] = '\0';
                    DebugP_log("Continue?(y = Continue):");
                    DebugP_scanf("%s", &stepflag);
                }while(strcmp(stepflag, "y") != 0);
            }
    
            status = Flash_read(gFlashHandle[CONFIG_FLASH0], offset, gOspiRxBuf, APP_OSPI_DATA_SIZE);
            if(status == SystemP_SUCCESS)
            {
                DebugP_log("Flash Read of %d bytes Success at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
            }
            else
            {
                DebugP_log("Flash Read of %d bytes Fail at 0x%X offset !!!\r\n", APP_OSPI_DATA_SIZE, offset);
            }
        }
        if(SystemP_SUCCESS == status)
        {
            status |= ospi_flash_io_compare_buffers();
        }
    
        if(SystemP_SUCCESS == status)
        {
            DebugP_log("All tests have passed!!\r\n");
        }
        else
        {
            DebugP_log("Some tests have failed!!\r\n");
        }
    
        Board_driversClose();
        Drivers_close();
    }
    
    void ospi_flash_io_fill_buffers(void)
    {
        uint32_t i;
    
        for(i = 0U; i < APP_OSPI_DATA_SIZE; i++)
        {
            gOspiTxBuf[i] = i % 256;
            gOspiRxBuf[i] = 0U;
        }
    }
    
    int32_t ospi_flash_io_compare_buffers(void)
    {
        int32_t status = SystemP_SUCCESS;
        uint32_t i;
    
        for(i = 0U; i < APP_OSPI_DATA_SIZE; i++)
        {
            if(gOspiTxBuf[i] != gOspiRxBuf[i])
            {
                status = SystemP_FAILURE;
                DebugP_logError("OSPI read data mismatch !!!\r\n");
                break;
            }
        }
        if(SystemP_SUCCESS == status)
        {
            DebugP_log("OSPI read data match !!!\r\n");
        }
        return status;
    }
    

    SysConfig 中的 OSPI 和闪存设置如下面的屏幕截图所示。

    执行产生的调试输出如图所示。
    如果执行环境发生更改、闪存打开本身就会成功。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的更新。

    因此、将环境更改为 CCS + XDS 200 调试器可使应用程序运行、而对于顶部操作系统 IDE +另一个调试器、同一应用程序出现故障。  
    请告诉我我的理解是否正确、然后我可以继续强调是否存在任何环境依赖性。

    期待您的答复。

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    >So 将环境更改为 CCS + XDS 200 调试器、使应用程序运行、而对于 topper OS IDE +另一个调试器、同一应用程序发生故障。  

    正确。
    这就是调试和运行测试代码的方法。

    https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/11_00_00_15/exports/docs/api_guide_am64x/CCS_LAUNCH_PAGE.html

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Hi Takeshi、

    感谢您的确认。

    CCS + XDS 200 调试器

    您是计划坚持使用此环境进行进一步开发、还是要坚持使用“topper OS IDE +另一个调试器

    请告诉我。

    谢谢、

    Vaibhav

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们计划使用“topper OS IDE +另一个调试器“进行未来的开发。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我们发现了闪存无法正常打开的原因。

    与闪存相关的 GPIO 的默认值设置为复位闪存、从而使其无响应。

    通过更改 SysConfig 的默认 GPIO 值、我们能够检查闪存的运行情况。