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.

[参考译文] TMS570LS0914:在主存储体上进行写入和擦除时、代码在 Fapi_setActiveFlashBank () 处崩溃

Guru**** 3001220 points

Other Parts Discussed in Thread: TMS570LS0914, HALCOGEN

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1653033/tms570ls0914-code-crash-at-fapi_setactiveflashbank-while-write-and-erase-on-the-main-banks

器件型号: TMS570LS0914

您好:

我正在尝试将一些数据写入闪存。 但代码会在 Fapi_setActiveFlashBank (bank0) 处崩溃。

这种情况具体发生在 bank0 上。 在调用此函数之前、我已将代码从 falsh 复制到 ram。

为了写入闪存、我是否可以使用闪存存储体 1、或者只能从闪存存储体 0 开始写入?

写的压缩是:

  1. 检查地址范围是否在闪存内
  2. 迭代闪存中的组
  3. 检查地址是否位于存储体内
  4. 将组设置为运行状态
  5. 检索要启用的扇区列表
  6. 启用要写入的扇区
  7. 等待操作完成
  8. 迭代闪存组中的地址
  9. 设置下一个操作中要写入的字节数
  10. 写入闪存地址
  11. 等待操作完成
  12. 检查操作是否成功
  13. 更新缓冲区指针、闪存地址和剩余的用于下一个操作的字节数
  14. 控制转至步骤 8 并不断迭代、直到地址有效
  15. 完成迭代后、如果遇到错误或写入操作已完成、则退出步骤 2 的循环。

我的写入地址为 0x000E0000、要写入的数据为 0xAA。

请帮助我解决这个问题。

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

    尊敬的 Prajakta:

    您的 UNDEF 中断崩溃 Fapi_setActiveFlashBank() 是 TMS570LS0914 上的一个有详细记录的问题。 根本原因是 F021 闪存 API 在尝试修改同一闪存存储体 [1][2]时仍在从闪存执行。

    TMS570LS0914 是一个单存储体器件 — 所有闪存 (0x00000000 至 0x000FFFFF) 都位于存储体 0。 这意味着:

    “F021 闪存 API 库无法从为 API 命令运行所选择的活动组所在的同一组执行。 在单组器件上、必须从 RAM 执行 F021 闪存 API。“ [1]

    您提到将代码从闪存复制到 RAM、但崩溃表明 并非所有 F021 API 函数实际上都是从 RAM 执行的。 仅仅复制应用程序代码是不够的、必须链接整个 F021 库和所有相关的目标文件才能从 RAM 运行。

    修复

    1.修改链接器命令文件 、将所有 F021 API 代码放入单独的加载(闪存)和运行 (RAM) 地址[3]:

    flashAPI:
    {
        Fapi_UserDefinedFunctions.obj (.text, .data)
        bl_flash.obj (.text, .data)
        --library= F021_API_CortexR4_BE_V3D16.lib (.text, .data)
    } palign=8 load = FLASH0, run = SRAM, LOAD_START(apiLoadStart), RUN_START(apiRunStart), SIZE(apiLoadSize)

    2.在调用任何闪存函数之前将 API 复制到 RAM [1]:

    extern unsigned int apiLoadStart;
    extern unsigned int apiRunStart;
    extern unsigned int apiLoadSize;
    
    memcpy(&apiRunStart, &apiLoadStart, (uint32)&apiLoadSize);

    3.关键细节: 包括 .text .data 所有相关目标文件(包括)的两个和部分 bl_flash.obj。 .text 任何此类对象中缺失都会导致代码保留在闪存中并触发 UNDEF 异常[4]。


    所需额外经费

    • 权限模式: F021 API 必须在管理员/权限模式(非用户模式)下运行才能访问闪存控制器寄存器[5]。
    • HCLK 频率: 确保 Fapi_initializeFlashBanks() 接收到正确的 HCLK 值 — TMS570LS0914PGE 的 160MHz [5]。
    • 在闪存操作期间禁用中断[5]。
    • 闪存等待状态 (RWAIT): 必须在闪存操作之前为您的工作频率正确配置[6]。

    关于您的银行问题

    您的写入地址 0x000E0000 位于组 0 的扇区 13、该扇区有效[7]。 由于 TMS570LS0914 是单存储体器件、因此必须使用存储体 0—没有单独的存储体 1 可用于数据存储。 您不需要以任何特定顺序“从 bank0“;您只需要从 RAM 运行的 API、以便它可以在 bank 0 上安全运行。


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

    • 您当前的链接器命令文件配置(验证 RAM 执行部分中是否有所有 F021 对象)
    • 以及要传递到的 HCLK 频率 Fapi_initializeFlashBanks()
    • 发生崩溃时、您的应用程序是在管理员模式还是用户模式下运行
    • 无论使用的是_BE与构建配置相匹配的 F021 库的大端字节序 () 还是小端字节序变体

    1. TMS570LS0914:TMS570LS0914PGE 上的 F021 API - TI E2E
    2. F021 闪存 API 参考 — SPNU501
    3. TMS570LS0914 CAN 引导加载程序问题 — TI E2E
    4. TMS570LS0914 CAN 引导加载程序 — 缺少.text 修复
    5. Hercules 引导加载程序应用手册 — SPNA241
    6. TMS570LS0x 技术参考手册 — SPNU607A
    7. TMS570LS0914:Uniflash 闪存映射

    此致、

    Zackary Fleenor

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

    您好: Zackary Fleenor、

    感谢您的答复。

    我已经浏览过你给出的解释。 我仍然对链接器 cmd 文件感到困惑。 我附带了链接器 cmd 文件和闪存接口文件。 请您浏览一下这两个问题、并向我建议我应该做些什么更改。

    谢谢、

    Prajakta.

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

       e2e.ti.com/.../1682.Linker_5F00_cmd.txt

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

    e2e.ti.com/.../FlashIntf.c

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

    e2e.ti.com/.../FlashToRam.c

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

    您好 Zackary Fleenor、

    非常感谢您的支持。  

    我现在很清楚地了解这些问题。

    1.我按照建议更改了链接器命令文件。 但是在 Ram_Copy ();函数之后代码会崩溃。 它转到 prefetchEntry。 当我注释两个目标文件时、代码会顺利执行。

    2. FLASH_MOVE_TO_RAM 这个宏是在 FlashIntf.h 中定义的,但没有与您共享。

    3. HCLK_FREQ = 160、 FLASH_RWAIT = 3、 FLASH_EWAIT = 9

    4. 权限模式: 如何确认代码是否在管理员 模式下运行?

    5.库字节序配置为大端字节序。

    6.启动呼叫顺序与您提到的相同。

    谢谢、

    Prajakta.

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

    除了以上调试外、

    1.我还发现注释  FlashToRam.obj (.text、.data) 也是有效的。

    2.如果我取消评论,代码会被错误地执行。  完成执行 FlashTo.code() 后、该控件跳转到 SysUtil_flushPipel() 行 no 75 Ram_Copy。

    3.代码开始执行 SysUtil_flushPipel()、之后将进行反汇编。  

    4.刷写完成后,我没有一步一步调试,只需运行代码,然后代码在 prefetchEntry 卡住 。

    因此、可疑 Ram_Copy 函数是 FlashTo-Code() 函数或与此相关的函数。

    请帮我解决这个问题。

    谢谢、

    Prajakta.

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

    尊敬的 Prajakta:

    您的新崩溃是与原始 UNDEF 中断不同的问题 — 修复非常简单。

    FlashToRam.obj .TI.ramfunc 完全从部分中删除。 仅 FlashIntf.obj 应在该处放置 F021 库。

    原因: FlashToRam_CopyCode() 是 执行 从闪存复制到 RAM 的函数。 如果您包含 FlashToRam.obj 在中 .TI.ramfunc、链接器会 在 RAM 中为其分配一个运行地址 — 但此函数必须在复制发生之前执行,同时仍在闪存中实际驻留。 您正在创建循环依赖项:负责将自身复制到 RAM 的代码无法从 RAM 执行、因为它尚未被复制[1][2]。

    FlashToRam_CopyCode() 完成 memcpy 并执行流水线刷新(中的 DSB + ISB)后 SysUtil_flushPipeline()、CPU 尝试从链接器分配的 RAM 运行地址中提取下一条指令—但由于函数已经从闪存执行、程序计数器跳转到无效位置、导致预取中止[3][4]。

    更正了“链接器 .TI.ramfunc 部分

    您的 .TI.ramfunc 部分应如下所示:

    .TI.ramfunc align(32) :
    {
        FlashIntf.obj (.text, .data)
        -l F021_API_CortexR4_BE_V3D16.lib (.text, .data)
    }
    LOAD = FLASH0, RUN = RAM,
    LOAD_START(RamfuncsLoadStart),
    RUN_START(RamfuncsRunStart),
    SIZE(RamfuncsLoadSize)

    不包括 — 它必须保留在通用段中,以便从闪存执行,并可以安全地将其他对象复制到 FlashToRam.obj .text : {} > FLASH0 RAM。

    为什么这样有效

    物体
    在哪里执行
    为什么
    FlashToRam.obj
    闪存中
    它执行 RAM 复制—必须在复制完成之前运行
    FlashIntf.obj
    RAM
    它调用在闪存上运行的 F021 API 函数
    F021_API_CortexR4_BE_V3D16.lib
    RAM
    无法从修改[1]的同一存储体执行

    关于特权模式

    要确认您处于管理员模式、请读取调试器中 CPSR 寄存器的模式位[4:0]。 在您呼叫的时候 FlashIntf_Init():

    • 0x13 =监控器模式✓
    • 0x10 =用户模式✗(将失败)

    如果您使用的是 HALCoGen 生成的启动代码而没有操作系统、则默认情况下您可能已处于管理员模式。

    行动摘要

    1. FlashToRam.obj (.text, .data) 从中删除 .TI.ramfunc
    2. FlashIntf.obj (.text, .data) 在中保留 F021 库 .TI.ramfunc
    3. HCLK_FREQ = 160、FLASH_RWAIT = 3、FLASH_EWAIT = 9、值对于 160MHz 是正确的
    4. FLASH_MOVE_TO_RAM 已确认已定义—没有问题
    5. 已确认启动顺序正确

    这应该能解决预取中止和原始 UNDEF 中断问题。


    1. TMS570LS0914:TMS570LS0914PGE 上的 F021 API - TI E2E
    2. TMS570LS0914:CAN 引导加载程序问题 — TI E2E
    3. TMS570LS0x 技术参考手册 — 预取中止 (SPNU607A)
    4. Hercules ARM Cortex-R 异常处理 (SPNA236)

    此致、

    Zackary Fleenor

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

    感谢您的支持