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.

[参考译文] AM263P4-Q1:有关在启用缓存的情况下写入闪存区域的信息

Guru**** 2957970 points

Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1645809/am263p4-q1-regarding-writing-to-a-flash-region-with-cache-enabled

器件型号: AM263P4-Q1
主题: SysConfig 中讨论的其他器件

启用缓存后、使用 Flash_eraseSector () 和 Flash_write () 擦除和写入闪存区域是否安全?

在执行擦除/写入操作之前、是否需要使用 CacheP_disable() 之类的函数禁用缓存?

预期响应日期:2026/5/17

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

    你好、Imaoka、

    请注意、TI 将尽最大努力在您原始发布时间的 24 小时内在 E2E 论坛上为您提供初步回复。 希望这有助于节省一些时间在您的线程张贴,而无需指定一个专门的期望的响应日期。

    否、在标准配置中启用高速缓存的情况下擦除和写入闪存是不安全的。 您需要考虑高速缓存和 ECC 交互、尽管该解决方案不一定 CacheP_disable() 在调用—问题在于架构、而不是纯粹的高速缓存一致性问题。


    AM263Px 有两种关键机制发挥作用:

    1. RL2 缓存写入行为

    用于外部闪存 (XIP) 的 RL2(远程 L2)高速缓存 在设计上为只读。 该文件明确指出:

    “写入可缓存范围将禁用 RL2 缓存... 当设置了任何位时、位于可缓存【范围】内的写入命令将设置中断原始状态寄存器中的 wr_hit 错误位…… RL2 缓存处于逻辑禁用状态。“ [1]

    这意味着对缓存闪存区域的写入会触发错误条件并禁用缓存 — 它不会缓慢地传递写入。

    2. ECCM(ECC 内存)约束

    AM263Px OptiFlash 子系统不支持在启用 ECCM 的情况下通过正常 Flash_write() 调用写入闪存。 MPU 中配置为“正常和缓存“的闪存区域的 ECC 保护处于活动状态、并且在标准写入操作期间硬件无法内联计算 ECC [2]。 建议的方法是:

    • 通过闪存操作调度器硬件 (FLSOPSKD) 进行预计算 ECC 和写入[2]
    • 通过 未启用 ECC 的非缓存、旁路 MPU 区域进行写入

    3.修改后高速缓存一致性

    即使成功写入闪存、该区域中之前缓存的任何数据也将过时。 除非缓存被正确失效、否则 CPU 可以执行旧的缓存指令或读取旧数据。


    CacheP_disable() 请考虑以下序列、而不是简单地在擦除/写入之前调用:

    1. 确保通过非缓存的 MPU 配置 (旁路区域)访问要修改的闪存区域以进行写入操作
    2. 使用 Flash_eraseSector() 和 Flash_write() 通过此非缓存路径执行擦除/写入
    3. 在恢复缓存访问之前、使修改后的闪存区域的任何缓存条目失效
    4. 或者、使用 FLSOPSKD 硬件调度器 [3]、该调度器专门设计用于通过调度事务并确定读取优先级来处理并发 XIP 读取和闪存写入/擦除操作
    CacheP_disable()“那又怎么样?

    CacheP_disable() 仅调用 不足以 确保闪存写入安全—它解决了缓存一致性方面的问题、但不能解析 ECCM 约束。 正确的解决方案取决于您的 MPU 和闪存子系统配置。 如果您的闪存区域启用了 ECCM(缓存的闪存区域默认启用)、则必须使用硬件辅助 ECC 计算路径或配置旁路区域进行写入[2]。


    为了帮助完善这项建议、了解以下信息会有所帮助:

    • 您的应用是否从闪存 (XIP) 执行代码、同时还需要在运行时擦除/写入其他闪存扇区
    • 您的闪存区域当前是否配置为在 MPU 设置中启用 ECCM
    • 旁路区域配置是否可用于您的用例
    • 无论您是有权访问还是熟悉 SDK 中的 FLSOPSKD(闪存操作调度器)硬件

    资源:

    1. AM263Px 技术参考手册 — RL2 高速缓存分配
    2. MCU+ SDK AM263Px—OptiFlash ECCM 文档
    3. MCU+ SDK AM263Px—FLSOPSKD(闪存操作调度器)
    此致、
    Zackary Fleenor
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Fleenor:

    对[1. RL2 高速缓存写入行为]的响应
    -我们可能会使用 XIP、但我们不打算使用 RL2。 如果未使用 RL2、则假设不需要考虑 RL2 是否正确?

    对[2. ECCM(ECC 存储器)约束的响应]
    -闪存区域在 sysconfig 中配置为“缓存“。 这是否对应于“正常和缓存“?
    -我们使用的是 SDK 版本 09_02_00_56。 该版本是否支持 FLSOPSKD?
    -是否有办法动态禁用 ECCM(例如,仅在闪存更新模式期间禁用 ECCM)?
    -如果在 ECCM 保持启用时更新闪存,会出现什么问题? (如果检测到错误但被忽略,是否仍然可以继续处理?)

    对[3.修改后高速缓存一致性的响应]
    -如果 ECCM 不能动态禁用,错误不能被忽略,你能解释如何实现如下所述的方法:
    “确保要修改的闪存区域可以通过用于写入操作的非缓存(旁路)MPU 配置进行访问“至
    “在恢复缓存访问之前、使修改后的闪存区域的任何缓存条目失效“?
    -我们希望以最简单的方式处理这个问题。 我们将单独确认是否可以使用 FLSOPSKD。

    对【为了帮助完善这项建议,了解以下情况会有所帮助:】
    -我们的应用程序在通过 XIP 执行代码时不执行闪存擦除/写入操作。 闪存擦除/更新所需的程序和数据被放置在 OCSRAM 中。 更新闪存后、在重新启动之前、我们不会再次执行 XIP。
    -在 Sysconfig 中,闪存区域被配置为“缓存“(在本例中,是否启用了 ECCM ?)。
    -“旁路区域配置“具体指什么?
    -我们不熟悉 FLSOPSKD。 请确认 SDK 版本 09_02_00_56 是否支持该功能。
    -请告诉我们如何验证硬件是否支持此功能 (FLSOPSKD 部分指出:“FLSOPSKD 是指定的 8051 控制器的名称、该控制器靠近外部闪存控制器(OSPI 控制器)并监控数据总线上的流量。 当 OSPI 数据总线上没有流量时、8051 将在总线上发出闪存命令。“)。

    预期响应日期:2026/5/20

    此致、Imaoka。

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

    尊敬的 Imaoka-San:

    感谢您提供详细的后续问题。 我将系统地讨论您的每个要点。

    对[1. RL2 高速缓存写入行为]的响应

    没错。 如果您不使用 RL2(远程 L2 缓存)、则 RL2 写入行为不适用于您的系统。 RL2 是软件可配置的功能、必须显式启用。 每个 R5F 内核都有一个集成的 RL2 控制器、该控制器可以从 L2 SRAM 保留系统存储器、用于缓存 1-16MB 的目标闪存空间。 如果您的应用程序未启用 RL2 缓存、您可以忽略我之前响应中提到的 RL2 写入限制。

    对[2. ECCM(ECC 存储器)约束的响应]

    Q1:SysConfig 中的“缓存“是否对应于“正常和缓存“?

    是的。 在 SysConfig 中将闪存区域配置为“缓存“时、它通常会映射到 FSS 区域 0 或区域 1、这两者都支持 OTFA(加密/身份验证)和 ECCM(ECC 保护)。 FSS 存储器区域的组织方式如下:

    -区域 0 (0x60000000 - 0x67FFFFFF):支持 OTFA + ECC
    -区域 1 (0x80000000 - 0x87FFFFFF ):支持 OTFA + ECC 和地址重映射能力(引导空间)
    -区域 3 (0x88000000 - 0x8FFFFFFF):无 OTFA +无 ECC(旁路区域)

    如果您的闪存区域配置为“缓存“、则默认情况下启用 ECCM。

    问题 2:SDK 版本 09_02_00_56 是否支持 FLSOPSKD?

    AM263Px 硬件包括一项称为“FOTA 硬件引擎“(固件无线硬件引擎)的功能、该功能可能与 FLSOPSKD 有关。 FOTA 硬件引擎支持 XIP 读取、同时 FOTA 更新在后台进行、这是实现并发 XIP 和闪存更新的硬件机制。

    要在 SDK 09_02_00_56 中验证 FLSOPSKD/FOTA 支持、请执行以下操作:
    -查看 SDK 发行说明中的“FOTA 硬件引擎“或“闪存操作计划程序“
    -在 SDK 中查找 Opti-Flash 示例(这些示例应包括 FLC、RL2、RAT 示例)
    -在 SDK 闪存驱动程序文档中检查与 FOTA 相关的 API

    但是、根据您的用例说明(闪存更新期间无 XIP,更新后重新启动)、您的应用不需要 FLSOPSKD。

    问题 3:是否有办法动态禁用 ECCM(例如,仅在闪存更新模式期间禁用 ECCM)?

    否、ECCM 无法在运行时动态禁用。 ECCM 在每个 FSS 存储器区域进行配置、并在系统初始化期间进行设置。 FSS 提供可为 ECCM 配置的 4 个区域、此配置是 FSS 区域设置的一部分。

    但是、您可以通过不同的存储器区域访问相同的物理闪存位置。 所有 FSS 区域 (0、1、3) 都映射到闪存中的相同物理位置。 您可以通过未启用 ECCM 的区域 3(旁路区域)写入闪存。 这是闪存更新的推荐方法。

    问题 4:如果在 ECCM 保持启用状态的情况下更新闪存、会出现什么问题?

    对启用 ECCM 的区域的闪存写入有严格的对齐要求:

    -对 ECCM 区域的写入必须是 32 字节对齐的,并且大小是 32 字节倍数
    -如果不满足这些条件中的任何一个、将发出错误中断
    - FSS 不支持读取 — 修改-写入 ECCM 区域
    -不支持用于 ECCM 的可变块大小(仅支持 32 字节块大小)

    如果忽略该错误、闪存写入可能会失败或产生损坏的数据。 ECC 保护要求使用正确的 ECC 代码写入数据、该代码在标准 Flash_write () 操作期间无法内联计算。

    对[3.修改后高速缓存一致性的响应]

    问:如何实施旁路区域方法?

    使用 FSS 区域 3(旁路区域)进行闪存写入、然后重新启动。 以下是针对您的用例建议的顺序:

    // Calculate bypass address from cached address
    #define FLASH_REGION0_BASE   0x60000000  // Cached region
    #define FLASH_BYPASS_BASE    0x88000000  // Bypass region
    
    // Convert cached address to bypass address
    uint32_t cachedAddr = 0x60100000;  // Your target flash address
    uint32_t bypassAddr = FLASH_BYPASS_BASE + (cachedAddr - FLASH_REGION0_BASE);
    // Result: bypassAddr = 0x88100000
    
    // Perform erase and write through bypass region
    Flash_eraseSector(bypassAddr, sectorSize);
    Flash_write(bypassAddr, dataBuffer, dataSize);
    
    // Reboot after update
    // Cache invalidation handled automatically by reboot

    要点:
    1.所有 FSS 区域映射到相同的物理闪存位置、因此对 0x88100000(区域 3)的写入将更新与 0x60100000(区域 0)相同的闪存单元
    2.区域 3(旁路)没有 ECCM,因此可以执行标准 Flash_eraseSector () 和 Flash_write (),无需 32 字节对齐约束或 ECC 计算
    3.无需禁用缓存 — 您只需通过绕过 ECCM 的不同内存区域访问闪存
    4.由于刷新更新后重新引导、因此重新引导会自动处理缓存失效

    对【帮助完善此建议】的回应

    Q1:我们的应用在通过 XIP 执行代码时不执行闪存擦除/写入。 程序和数据位于 OCSRAM 中。 更新闪存后、我们会重新启动。

    太棒了。 这是理想情况和最简单的方法:

    1.闪存更新期间无 XIP 可消除执行过时缓存代码的风险
    2. OCSRAM 中的更新代码可确保所有更新操作从 RAM 运行
    3.更新后重新启动会自动使所有缓存无效

    推荐方法:
    -为 Flash_eraseSector () 和 Flash_write () 使用 FSS 区域 3(旁路区域)地址
    -无需调用 CacheP_disable ()
    -无需手动使缓存失效(重新引导处理此问题)

    问题 2:在 SysConfig 中将闪存区域配置为“缓存“。 ECCM 是否已启用?

    是、已为“缓存“区域启用 ECCM。 如前所述、“缓存“区域映射到 FSS 区域 0 或区域 1、这两个区域都启用了 ECCM。

    要在系统中进行验证:
    -检查您的 SysConfig“缓存“设置映射到的 FSS 区域地址范围
    -如果是 0x60000000-0x67FFFFFF(区域 0)或 0x80000000-0x87FFFFFF(区域 1)、则启用 ECCM

    问题 3:“旁路区域配置“具体指什么?

    “旁路区域“指 FSS 区域 3:

    - SoC 地址范围:0x88000000 - 0x8FFFFFFF
    -大小:128 MB
    -特点:无 OTFA +无 ECC
    -说明:外部存储空间 — 旁路区域

    主要功能:
    -绕过 ECC 和 OTFA 处理
    -使用预先验证和 ECCM 保护的数据实现直接闪存编程
    -支持纠错(清理)操作

    用法:在闪存写入/擦除操作期间、通过区域 3 地址而不是区域 0/1 地址访问相同的物理闪存。

    问题 4:在 SDK 版本 09_02_00_56 中是否支持 FLSOPSKD? 如何验证硬件支持?

    要在 SDK 09_02_00_56 中验证 FLSOPSKD/FOTA 硬件引擎支持、请执行以下操作:
    1.查看 SDK 发行说明中的“FOTA 硬件引擎“或“闪存操作调度程序“
    2.在 SDK 中查找 Opti-Flash 示例
    3.检查 SDK 闪存驱动程序文档中与 FOTA 相关的 API

    FOTA 硬件引擎是 AM263Px FSS 子系统的硬件功能、具有 2KB 内部程序存储器和 256 字节数据存储器、并生成 FOTA 完成和错误中断。 查看器件型号文档、确认存在 FOTA 硬件引擎。

    但是、对于您的用例(闪存更新期间无 XIP,更新后重新启动)、FLSOPSKD 不是必需的。 FLSOPSKD 专为并发 XIP 读取和闪存写入而设计、您明确指出不需要。

    总结和建议解决方案

    鉴于您的特定要求(闪存更新期间无 XIP、更新代码从 OCSRAM 运行,闪存更新后重新启动)、我建议使用以下方法:

    使用 FSS 区域 3(旁路区域)进行闪存写入/擦除操作

    这种方法提供:
    1.无需禁用缓存 (CacheP_disable() 不需要)
    2.无 ECCM 限制(区域 3 绕过 ECCM)
    3.写入无 32 字节对齐要求
    4.无需手动使缓存失效(重启即可处理它)
    5.最简单的实现方式
    6.不依赖 FLSOPSKD(您的用例不需要)

    实施步骤:
    1.通过将缓存地址的偏移量加到旁路基址 (0x88000000 ) 来计算旁路区域地址。
    2.在 Flash_eraseSector () 和 Flash_write () 调用中使用旁路地址
    3.刷新更新完成后重新启动

    直接回答您的原始问题:是的,只要您通过 FSS 区域 3(旁路区域)地址访问闪存,就可以使用 Flash_eraseSector () 和 Flash_write () 安全地擦除和写入闪存区域。 使用旁路区域方法时、在闪存操作之前不需要调用 CacheP_disable ()。

    如果您需要任何澄清或有其他问题、请告诉我。

    此致、
    Zackary Fleenor

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

    尊敬的 Fleenor:

    感谢您的答复。
    SDK 09_02_00_56 的发行说明中并未提及“FOTA 硬件引擎“或“闪存操作调度器“。
    因此、我们将在不使用 FLSOPSKD 的情况下继续。

    尽管不使用 XIP、但在重新启动之前、我们会对写入的数据进行验证。
    当通过区域 3 更新闪存时、我们预计闪存(区域 0)内容和高速缓存之间会存在差异。
    您能否提供有关如何解决此问题的建议?
    调用 CacheP_DISABLE (CacheP_TYPE_ALL) 是否足够?
    重新启用时、我们是否应该调用 CacheP_ENABLE (CacheP_TYPE_ALL)?
    如果这种方法不合适、是否可以通过区域 3 进行验证?
    (我们倾向于将区域 3 的使用限制为仅使用闪存更新操作。)

    关于区域 3 (0x88000000 - 0x8FFFFFFF) 的 SysConfig MPU 设置、
    将区域属性配置为“非缓存“是否正确?
    如果没有、请指定适当的配置。

    最后、您能否确认以下写入旁路区域 (FSS 区域 3) 的地址计算是否正确?
    写入目标旁路区域地址 (FSS 区域 3)=写入目标地址 (FSS 区域 1)- FSS 区域 1 基地址 (0x60000000)+ FSS 区域 3 基地址 (0x88000000)

    预期响应日期:2026/5/21

    此致、Imaoka。

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

    尊敬的 Fleenor:

    感谢您的答复。

    由于实施过程中的限制、我们决定继续执行“选项 B:通过区域 3 进行验证“。
    (这仅供您参考,而不是问题。)

    下面列出了我们使用的闪存 API (SDK 版本 09_02_00_56)。
    闪存地址指定为偏移量。
    您能否建议如何使用以下 API 访问 FSS 区域 3?

    - int32_t Flash_read (Flash_Handle 句柄、uint32_t 偏移、uint8_t *buf、uint32_t len)
    - int32_t Flash_write (Flash_Handle 句柄、uint32_t 偏移、uint8_t *buf、uint32_t len)
    - int32_t Flash_offsetToSectorPage(Flash_Handle 句柄、uint32_t 偏移、uint32_t *扇区、uint32_t *页面)
    - int32_t Flash_eraseSector (Flash_Handle 句柄、uint32_t sectorNum)
    - Flash_Attrs * Flash_getAttrs(uint32_t instanceId)

    请求的响应日期: 2026年5月23日

    此致、Imaoka。

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

    您好、

    该专家目前已离职。 请预计响应会延迟、直到他们下周返回。  

    此致、
    Aj Favela.  

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

    尊敬的 Fleenor:

    我无法在 SysConfig 中找到创建第二个闪存实例的过程。
    您能否提供进行配置所需的步骤?

    请求的响应日期: 2026年5月29日

    此致、Imaoka。

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

    *我代表客户 Imaoka-San 发帖。 E2E 上似乎存在问题。  

    (来自客户的消息)

    尊敬的 Fleenor:

    只是为了确认:
    关于关键点 1、我们知道为闪存实例 (CONFIG_FLASH0)(区域 0)启用了 ECC。
    我们还获悉、对支持 ECC 的区域的闪存写入有严格的对齐要求(参考:对支持 ECCM 的区域的闪存写入有严格的对齐要求)。
    在这些情况下,我们可以假设 Flash_eraseSector () 和 Flash_write () 在内部处理这些要求并正确执行擦除/写入操作吗?
    或者、应用程序是否需要确保符合这些对齐要求?

    请求的响应日期: 2026年6月2日

    此致伊毛冈。

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

    尊敬的 Fleenor:

    我们似乎误解了如何使用以前提供的 flashUpdateAndVerify () 函数。

    例如,如果我们要写入地址 0x60280000 ,我们是否应该指定以下值作为 Flash_write () 的偏移?

    FSS 区域 0:
    0x00280000 (= 0x60280000 - 0x60000000)<-在这种情况下不使用

    FSS 区域 3:
    0x280000 (= 0x60280000 - 0x60000000 + 0x88000000 - 0x60000000)

    请求的响应日期: 2026年6月5日

    此致、Imaoka。

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

    尊敬的 Fleenor:

    当我调用 Flash_read () 并将偏移设置为从 0x28000000 开始的地址时、会发生以下错误:

    C:\ti\mcu_plus_sdk_am263px_09_02_00_56\source\board\flash\ospi\flash_nor_ospi.c
    Flash_norOspiRead ()
    ...
    /*验证地址输入*/
    如果 (((offset + len)>(attrs->flashSize))
    {
    状态= SystemP_FAILURE;
    }
    ...

    为避免上述错误、我尝试在 SysConfig 中将闪存大小设置为 0x28000000 或更高、但我只能将其设置为 256KB。

    如何避免此错误?

    请求的响应日期: 2026年6月16日

    此致、Imaoka。

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

    尊敬的 Fleenor:

    我想分享解决方案 A(直接访问区域 3)的验证结果。
    我根据您共享的代码/策略更新了实现、但此时仍然无法按预期工作。
    实现细节

    Erase:flash_eraseSector ()(不变)
    写入:而不是 Flash_write (),直接访问 Region3
    memcpy ((uint8_t *) Region3_base + offset、buf、len)
    读取:使用 memcpy () 通过 Region3 指针读取,而不是 Flash_read ()


    当前配置
    Region0 (0x60xxxxxx):启用高速缓存
    Region3 (0x88xxxxxx):非高速缓存
    OSPI:DAC 已启用

    发现问题
    使用 memcpy 写入 Region3 时、目标处的数据会变得不正确。
    例如、我将 128KB 的 0x0 数据写入 0x88620000。


    为了检查大小相关性、我还将写入拆分为 256 字节的块(假设页面大小)、但数据仍然不正确。
    根据上述情况、我怀疑这可能与闪存编程序列/约束有关。

    问题
    将 Region3 地址传递到 Flash_write () 时、由于以下检查、操作失败:
    然而,作为一个实验,我禁用了此检查并针对 Region3 执行了 Flash_write (),并且写入似乎正确完成。

    /*验证地址输入*/
    如果 (((offset + len)>(attrs->flashSize))
    {
    状态= SystemP_FAILURE;
    }

    是否可以在取消此检查的情况下操作?
    如果不建议这样做、您能否建议一种推荐的替代方法?

    另外、关于解决方案 B:由于 Region0 启用了缓存、因此我们希望继续使用假定通过 Region3 进行访问的方法。

    请求的响应日期: 2026年6月19日

    此致、Imaoka