【问题标题】:External FLASH slow verification with STM32cubeProgrammer使用STM32cubeProgrammer进行外部FLASH慢速验证
【发布时间】:2023-03-21 05:23:02
【问题描述】:

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

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

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

有什么想法或提示吗?

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

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

外部加载器是一个 ELF 文件,重命名为“*.stldr”。编程工具查看调试信息以找到函数的位置。然后它设置寄存器来提供参数,PC 来运行函数,然后让它运行。有一些非常聪明的工作正在进行中来完成这项工作。程序员查看返回值 (R0) 以查看事情是否通过。它还可以判断该函数是否导致内核崩溃或超时。

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

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

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

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

我希望这对某人有帮助!

【问题讨论】:

    标签: external loader stm32cubeide


    【解决方案1】:

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

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

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

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


    【讨论】:

    • 加速初始化的好技巧。
    猜你喜欢
    • 2019-05-08
    • 2011-08-21
    • 1970-01-01
    • 2020-03-10
    • 2012-05-22
    • 1970-01-01
    • 2010-11-13
    • 2022-06-26
    • 2022-11-11
    相关资源
    最近更新 更多