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.

[参考译文] RM48L940:FreeRTOS 预取中止

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/718536/rm48l940-freertos-prefetch-abort

器件型号:RM48L940

我正在尝试在我的定制 RM48板上运行 FreeRTOS、并已按照 TI 推荐的说明执行此操作。 但是、在创建操作系统任务时、我收到预取中止错误。 具体而言、我在执行下面突出显示的此行后立即获取预取中止。

;恢复第一个任务的上下文。

公共 vPortStartFirstTask

vPortStartFirstTask
CPS #0x13
portRESTORE_CONTEXT 

当我进入这个宏时、它看起来会正常操作寄存器、直到在某个时候、我的寄存器看起来是这样的:

当我退出   portRESTORE_CONTEXT 宏时 、我的寄存器如下所示:

从这里开始下一条指令是预取中止。 如何找出导致中止的原因?

我的链接文件如下所示:

/*------------------ *
定义大小为4G 的存储器内存内存;

define region vectors = mem:[来自0x00000000大小0x00000020];
定义区域内核=内存:[0x00000020大小0x00008000];
定义区闪存=内存:[来自0x00008020大小0x00177FE0]
| mem:[来自0x00180000大小0x00180000];
define region stack = mem:[来自0x08000000大小0x00002500];
定义区域 Kram = mem:[来自0x08002500大小0x00000800];
定义区域 RAM =内存:[从(0x08002500+0x00000800)大小(0x0003F800 - 0x00000800)];
定义块堆、大小= 0x800、对齐= 8{};

通过副本{readwrite}进行初始化;
不初始化{section.noinit};

放入向量{readonly section .intvecs};
放入内核{readonly section .kernelTEXT};
置于闪存{readonly}中;
放入 RAM{readwrite section .kernelHEAP};
放入 Kram{readwrite section .kernelBSS};
放入 RAM{readwrite};
放入 RAM{block heap};
/*------------------ *

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    引起问题的代码行是下面代码段中的 portRESTORE_CONTEXT。 初始帖子添加了标记、而不是显示突出显示的文本。

    ;/*----- *
    ;恢复第一个任务的上下文。

    公共 vPortStartFirstTask

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

    预取中止是一种精确的中止、因此应用程序可以识别导致中止的指令。 您能否检查反汇编窗口以确定要提取下一条指令的地址? 从上面的日志来看、它似乎是0xBD3C。 这是一个有效地址、因此它可以是这个地址之后导致中止的指令。

    您可以检查 CPU 的指令故障状态和地址寄存器、以确定确切的地址和中止的原因(双位 ECC 错误、MPU 配置)。

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

    感谢您的回复。 0x0D3C 地址在调用 portRESTOR_Context 之前加载到 LR 中。 该地址处的指令是我用黑体字标出的 vPortSWI 标签中的最后一条指令。

    ;------------------------------------------------------------------
    ; SWI 处理程序,保护模式函数的接口

    公共 vPortSWI

    vPortSWI
    stmfd sp!、{r11、r12、lr}
    R12夫人、spsr
    数 R12、R12、#0x20
    ldrbne R12、[LR、#-2]
    ldrbeq R12、[LR、#-4]
    LDR r14、表
    LDR R12、[r14、R12、LSL #2]
    Blx R12
    mfldd sp!、{r11、r12、pc}^


    DCD 跳线表

    跳线表
    DCD swiPortYield;0- vPortYieldProcessor
    DCD swiRaisePrivilege;1-提升 Priviledge
    DCD swiPortEnterCritical;2- vPortEnterCritical
    DCD swiPortExitCritical;3- vPortExitCritical
    DCD swiPortTaskUsesFPU;4- vPortTaskUsesFPU
    DCD swiPortDisableInterrupts;5- vPortDisableInterrupts
    DCD swiPortEnableInterrupts;6- vPortEnableInterrupts

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

    请查看 CPU 故障状态和地址寄存器、以识别导致中止的被访问地址。 这个看起来是链路寄存器损坏、导致返回指令从无效地址中获取。 该地址将在指令故障地址寄存器(IFAR)中捕获。 有关 IFAR 的更多信息、请参阅 Cortex-R4F TRM 修订版本 r1p3的第133页。

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

    谢谢。 IFAR 在 LR 中包含相同的无效地址(请参阅下文)、因此我不确定要做什么。 DFSR 是否指示这是"同步奇偶校验/ECC 错误"

    该项目 在裸机上运行良好、因此我认为添加 FreeRTOS 是一个很好的方法。 这是否与 MPU 的设置方式有关? 我正在使用 FreeRTOS 中的默认 MPU 设置、如下所示。

    在 prvSetupDefaultMPU( void )函数中,闪存大小低于4MB,SRAM 为512K,但 RM48具有3MB 闪存和256K RAM。 是否可以按原样使用此函数? 我尝试更改大小以匹配3MB 和256K、但这未修复预取中止错误。

    /*------------------ *
    定义大小为4G 的存储器内存内存;

    define region vectors  = mem:[来自0x00000000大小0x00000020];
    定义区域内核   =内存:[0x00000020大小0x00008000];
    定义区闪    存=内存:[来自0x00008020大小0x00177FE0]
                           | mem:[来自0x00180000大小0x00180000];
    define region stack    = mem:[来自0x08000000大小0x00002500];
    定义区域 Kram     = mem:[来自0x08002500大小0x00000800];
    定义区域 RAM      =内存:[从(0x08002500+0x00000800)大小(0x0003F800 - 0x00000800)];
    定义块堆、大小= 0x800、对齐= 8{};

    通过副本{readwrite}进行初始化;
    不初始 化{section.noinit};

    放入向量{readonly section .intvecs};
    放入内核 {readonly section .kernelTEXT};
    置于闪存  {readonly}中;
    放入 RAM    {readwrite section .kernelHEAP};
    放入 Kram   {readwrite section .kernelBSS};
    放入 RAM    {readwrite};
    放入 RAM    {block heap};
    /*------------------ *

    static void prvSetupDefaultMPU( void )
    {//
    确保 MPU 已禁用*/
    prvMpuDisable();
    
    //首先将整个闪存设置为非特权只读访问。 //
    prvMpuSetRegion (portUNPRIVILEGED_FLASH_REGION、0x00000000、portMPU_SIZE _4MB | portMPU_REGION_ENABLE、portMPU_PRIV_RO_USER_RO_EXEC | portMPU_NORY_OINOWT_SHARED);
    
    //设置前32K 仅用于特权访问。 这是内核代码
    的放置位置。 /prvMpuSetRegion
    (portPRIVILEGED_FLASH_REGION、0x00000000、portMPU_SIZE_32KB | portMPU_REGION_ENABLE、portMPU_PRIV_ROP_USER_NA_EXEC | portMPU_NORY_OINOWT_SHARED);
    
    //设置整个 RAM 区域的特权级读取
    、仅限 portMPU_REGISTE_RE_REGION | portMPU_REGION
    
    /*默认外设设置*/
    prvMpuSetRegion (portGENERAL_PERIPS_REGION、0xF0000000、
    portMPU_SIZE_256MB | portMPU_REGION_ENABLE | portMPU_REGION_1_DISABLE | portMPU_REGION_2_DISABLE | portMPU_REGION
    
    
    
    
    
    
    
    | portMPU_REGION | portMPU_REGION_ENTRU_ENTRU_ENTRU*、portMPU_ENTRU_ENTRU_ENTRU*、portMPU_ENTRU_ENTRU_ENTRU_ENTRU*、portMPU_ENTRU_ENTRU_ENTRU*、portMPU_ENTRU_ENTRU_ENTRU_ENTRU_ENTRU*、portMPU_ENTRU_ENTRU_ENTRU*、portMP_ENTRU_ENTRU_ENTRU_ENTRU_ENTRU_ENTRU*、portMP_ENTRU_ENTR 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    遗憾的是、您为 IFAR 和 DFAR 上传的图像没有通过。 这似乎是 MPU 设置的问题。 请根据 RM48x 上的可用闪存和 RAM 更正存储器大小。 此外、检查所定义区域的权限:允许或不允许用户模式访问。

    您可以通过辅助指令故障状态寄存器获取有关 MPU 检测到的故障(背景、对齐或权限)的更多信息。 位域说明位于 CPU TRM 的第129页。

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

    我先前更改了存储器大小以匹配、但这没有帮助。 我已重新附加了 IFAR 和 DFAR 内容

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

    我已向您发送"朋友请求"。 这样、您就可以向我发送您的代码项目、而无需将其上传到论坛。

    您是否看到 CPU 的预取中止(矢量地址0xC)响应或数据中止(矢量地址0x10)? DFSR 显示来自位置0x08000018的 ECC 错误。 是否在读取此位置而不先初始化?

    此致、
    Sunil
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢。 我接受了请求。
    位置0x08000018为堆栈空间。 我使用内存初始化 RAM (0x1U)。 明天我将详细介绍。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我的问题还没有解决、但现在已经解决了。 我将返回查找根本原因、并在需要时联系我们。
    解决方法:禁用所有 SafeTI 测试、无预取中止。 我怀疑其中一项测试导致内存损坏。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    某些 SafeTI 诊断确实会导致故意数据中止。 数据中止处理程序将其标识为故意导致的数据中止、并以与实际数据中止不同的方式对其进行管理。

    此致、
    Sunil