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.

[参考译文] TMS570LC4357:HALCoGen FreeRTOS 端口会因动态 MPU 配置而导致预取或数据中止

Guru**** 2117280 points
Other Parts Discussed in Thread: TMS570LC4357, HALCOGEN
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/950626/tms570lc4357-halcogen-freertos-port-cause-prefetch-or-data-abort-due-to-dynamic-mpu-configuration

器件型号:TMS570LC4357
主题中讨论的其他器件: HALCOGEN

您好!

我们在 TMS570LC4357上运行的软件有时会出现预取/数据中止异常、分支到 HL_SYS_intvecs.asm 处的中断矢量。 但由于权限错误、它不会分支到函数_prefetch 或_dabort 函数。  

resetEntry
b _c_int00
b _undef
b vPortSWI
b 预取(_P)
b _dabort
b 相位中断
LDR PC、[PC、#-0x1b0]
LDR PC、[PC、#-0x1b0] 

经过一些调试后、我们认为这是由 MPU 配置问题引起的、因为  MPU 区基地址寄存器= 0x00000000总是会发生此问题、而  MPU 区大小和使能寄存   器以及 MPU 区访问控制寄存器是其他任务的动态 MPU 配置值。

  根据 TI 的 MPU 配置应用报告、应先禁用 MPU 区域、然后再更改配置、但在 HALCoGen 生成的 FreeRTOS 代码中找不到任何禁用可配置 MPU 区域的代码。

因此、我们在函数 portSAVE_Context 中添加了以下片段、以便在 portRESTORE_Context 更改 MPU 配置之前禁用可配置的 MPU 区域。 然后我们对其进行了测试、软件在没有预取/数据中止的情况下运行了一天。

;禁用所有可配置的 MPU 区
mov r0、#12
mcr P15、#0、r0、C6、C2、 0 ;选择区域
mov r0、#0
mcr P15、#0、r0、C6、C1、 2 ;禁用 MPU
mov r0,#13
mcr P15、#0、r0、C6、C2、 0 ;选择区域
mov r0、#0
mcr P15、#0、r0、C6、C1、 2 ;禁用 MPU
mov r0,#14
mcr P15、#0、r0、C6、C2、 0 ;选择区域
mov r0、#0
mcr P15、#0、r0、C6、C1、 2 ;禁用 MPU
mov r0,#15
mcr P15、#0、r0、C6、C2、 0 ;选择区域
mov r0、#0
mcr P15、#0、r0、C6、C1、 2 ;禁用 MPU 

因此,我们要问:

  1. 这是 HALCoGen 中的问题还是我们错误配置了 HALCoGen?
  2. 添加的代码片段是否足以涵盖上下文切换期间动态 MPU 配置的边缘情况?
  3. 是否有更好的方法来解决该问题?

我们使用了 HALCoGen 版本=04.07.01、项目器件=TMS570LC4357ZWT_FreeRTOS。 MPU 的 HALCoGen 配置如下所示:

谢谢

贾志。

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

    Jiazhi 您好、

    可以通过读取指令故障状态寄存器(IFSR)和指令故障地址寄存器(IFAR)来分析预取中止的原因。 IFAR 包含 CPU 试图从中提取指令的地址。 IFAR 的内容对于预取中止始终有效、因为所有预取中止都是同步的。

    如果根据 IFSR 状态发生了一个权限故障、则可能发生了以下情况之一:

    • 正在从设置了“从不执行”属性的位置(MPU 控制寄存器的 XN 位)提取指令。 必须读取从 IFAR 中读取地址所在的 MPU 区域。
    • 从 IFAR 读取的目标地址具有“Device”(设备)或“严格排序”存储器属性。 这意味着这些区域没有可执行代码
    • 目标处于用户模式、该模式无权从从从 IFAR 读取的地址执行代码

    MPU API 在 HALCOGen 生成的 sys_mpu.asm 中定义

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

    您好 QJ、

    ISFR 和 IFAR 如下所示:

    矢量表、显示地址0x0000000C 是分支到_prefetch abort 函数的指令

    和 MPU 配置寄存器的值如下:

    软件卡在中断矢量上、因为它在 CPU 尝试从该矢量执行时生成预取错误。 我们的任务的可配置 MPU 从未以这种方式进行配置、它是由 OS_portasm.asm 中 portRESTORE_CONTEXT 中的动态 MPU 配置引起的。

    我们知道 sys_mpu.asm 提供了用于配置 MPU 的 API、但在动态配置该区域之前没有禁用 MPU 区域、该区域应该是 OS_portasm.asm 的一部分? 我们没有移植 FreeRTOS 的经验、因此我们想知道是否有解决此问题的建议方法?

    此致、Jia Zhi

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

    Jiazhi 您好、

    您还可以查看此应用手册(以及包含的代码示例 CCS 项目):
    www.ti.com/.../spna177.pdf

    本文档中包含 CCS 工程的链接。

    请检查以下寄存器的值:

    • SPSR_ABT: 在异常中止发生之前保留 CPSR 的值。
    • R13_ABT: 是指向异常中断处理程序所使用的 CPU 内存中堆栈顶部的指针
    • R14_ABT: 是程序计数器(PC)的地址、指向导致中止的指令+ 8字节(由于 CPU 流水线)

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

    您好 QJ、

    感谢您参阅应用手册。

    从应用手册中、我认为我们需要按照"1.5.3区域设置优化版本"和"1.6 MPU 默认配置"一节进行操作、方法是将涵盖内核 RAM 和闪存的 MPU 设置为使用更高的区域编号、以防止 FreeRTOS 动态 MPU 区域覆盖内核的 MPU 设置。 在这种情况下、我不需要在 portSAVE_CONTEXT 中禁用动态 MPU 区域、这是正确的吗?

    由于闪存和内核闪存(区域1和区域2)的 HALCoGen MPU 配置不能更改(灰色框)、因此 HALCoGen 似乎建议使用低优先级 MPU 区域来覆盖闪存和内核闪存、这与应用手册中的建议相矛盾。

    SPRs_ABT 和 R14_ABT 的值表示预取中止是由 CPU 在 SYS 模式下尝试从中断矢量执行触发的。 软件在尝试从0x0000000C 执行时卡住、即使在 CCS 中使用"汇编步骤进入"、软件也会跳回0x0000000C。

    这是同一次运行中的指令故障寄存器和 MPU 寄存器、供您参考:

    此致、Jia Zhi。

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

    您好、JiaZhi、

    在 HALCoGen 生成的 FreeRTOS 示例中、使用_mpuInit_()函数配置 MPU。

    您可以使用以下命令启用 MPU: prvMpuEnable(),并使用 "prvMpuSetRegione()"设置 MPU 区、区、启用/禁用区

    如果要在启用 MPU 时更新某个区域的 MPU 设置、需要小心不要干扰代码当前正在执行的 MPU 区域。 您还需要在修改设置之前禁用该区域、就像 在 portSAVE_CONTEXT 宏中一样。