使用STM32cubeProgrammer进行外部FLASH缓慢验证

问题描述

我正在使用带有Micron MT25Q Quad_SPI Flash的STM32F469芯片。要对Flash进行编程,需要开发一个外部加载程序。都可以,但是问题在于QSPI Flash的验证非常慢。

查看日志文件,它表明Flash正在以150K字节块进行编程。但是,验证是在1K字节块中完成的。此外,在每次块检查之前都要重新初始化芯片。我已经通过STM32cubeIDE和直接在STM32cubeProgrammer中进行了尝试。

外部编程器程序包括正确的芯片配置信息,并指定64K页面大小。我看不到如何使程序员使用更大的块大小。看起来好像了解使用了SRAM的哪一部分,并且正在使用板载SRAM中256K的余量来对QSPI Flash进行编程。它可以使用相同的大小来读取数据,也可以使用外部加载器中的Verify()函数。它先调用Read(),然后检查数据本身。

有什么想法或提示吗?

让我添加一些有关创建新的外部加载程序的意见。第一个观察结果是“不要”。如果您可以选择受支持的外部芯片并将其固定以使用现有的加载器,则可以这样做。 STM仅提供4个示例程序,但它们必须具有50个外部加载程序。如果硬件设计复制了具有外部加载器的演示板的原理图,那应该没事,不要进行开发工作。

外部加载器不是完整的可执行文件。它提供了一组执行基本操作的函数,例如Init(),Erase(),Read()和Write()。诀窍在于,程序启动时没有main()并且没有运行启动代码

外部加载器是一个ELF文件重命名为“ * .stldr”。编程工具查看调试信息以查找功能的位置。然后,它设置寄存器以提供参数,由PC来运行该功能,然后让它运行。有一些超级聪明的工作正在继续进行。程序员查看返回的值(R0)以查看是否通过。它还可以确定函数是否使内核崩溃或超时。

使外部超级脚本有趣的是调试器正在运行该程序,因此没有可用的调试器来查看代码在做什么。我决定在被调用函数的return()上输出错误和编码信息,以提示正在发生的事情。

外部加载程序不是“完整”程序。没有启动代码,将无法设置许多片上内容,而有些则无法使用。至少我无法弄清楚。我不确定它是否配置不正确或调试器是否阻止了它的使用。查看示例外部加载程序,它们以非常简单的方式编写,并且不调用HAL或使用中断。您需要提供核心设置功能来配置时钟链。由于计时器和/或中断不起作用,该Hal_Delay()方法将永远不会返回。我永远无法让它们正常工作,并且怀疑NVIC是否因某种原因而被禁用。我最终用基于内核时钟频率和每个循环的指令周期旋转的for循环替换了HAL_delay()函数

该应用笔记建议开发一个独立的程序来调试基本功能。这是一个好主意,但又是一个挑战。在启动外部加载程序之前,我让QSPI进行了所需的操作,但是从C ++应用程序调用了HAL。从中创建一个外部加载程序是剥离和替换功能的一项长期工作。提示是示例是在寄存器级别编写的。我不能同时直接处理QuadSPI外设和芯片的指令集。

消除了程序的正常启动。在调用main()之前完成的所有工作(例如,在startup_stm32f469nihx.s中)由您决定。这包括设置时钟链以提升核心时钟并使外围总线正常工作。该程序在片上SRAM中运行,因此所有初始化变量均正确加载。不需要移动数据,但是堆栈和未初始化的数据区域可以/应该仍为零。

我希望这对某人有帮助!

解决方法

今天我遇到了同样的问题。

我可以通过两个简单的步骤提高验证速度,但验证仍然比编程慢得多,这很奇怪...... 如果有人找到一种方法来更改 STM32CubeProgrammer 的 1KB 块读取,我想知道 =)。 遵循我所做的更改以稍微提高性能。

  1. 在Init函数中添加一种锁,避免多次初始化。这是最重要的变化,因为我正在我的初始化过程中检查 Flash ID。其他方法可能更安全,但这个简单的代码片段对我有用。

    int Init(void)
    {
        static uint32_t lock;
    
        if(lock != 0x43213CA5)
        {
            lock = 0x43213CA5;
    
            /* Init procedure goes here */
    
        }    
        return(1);
    }
    
  2. 缓存一个页面,而不是为每次调用读取外部存储器。如果您的外部存储器页面读取开销太大,这将更有帮助,否则这个想法不会给出相关结果。