【问题标题】:S32K146EVB Read Collision when erasing/writing flashS32K146 EVB Red Collision 擦/写flash
【发布时间】:2019-04-04 15:23:26
【问题描述】:

当我尝试擦除或写入我的 S32K146 EVB 上的程序闪存时,我在 FTFC 应该执行命令的那一刻遇到了故障。 FTFC_STAT 寄存器中的 RDCOLLERR 位也被设置。这是来自 S32DS 的错误:

BusFault:发生精确(同步)数据访问错误。可能的位置:0x00000BA0。

PC 在 0xb8a 处停止。

这是反汇编:

11          while ((FTFC->FSTAT & FTFC_FSTAT_CCIF_MASK) == 0);
00000b88:   nop     
00000b8a:   ldr     r3, [pc, #20]   ; (0xba0 <execute_command+44>)
00000b8c:   ldrb    r3, [r3, #0]
00000b8e:   uxtb    r3, r3
00000b90:   sxtb    r3, r3
00000b92:   cmp     r3, #0
00000b94:   bge.n   0xb8a <execute_command+22>
12          return;
00000b96:   nop     
13        }
00000b98:   mov     sp, r7
00000b9a:   pop     {r7}
00000b9c:   bx      lr
00000b9e:   nop     
00000ba0:   movs    r0, r0
00000ba2:   ands    r2, r0

奇怪的是,当我逐行执行程序时,这不会发生。然后闪存被正确编程。

这是我擦除闪存扇区的例程:

void flash_erase_section(unsigned int addr)
{
    // wrong address
    if ((addr > FLASH_END_ADDRESS && addr < FLEXNVM_START_ADDRESS) || addr > FLEXNVM_END_ADDRESS){
        return;
    }

    asm volatile("cpsid i");
    // wait if operation in progress
    while ((FTFC->FSTAT & FTFC_FSTAT_CCIF_MASK) == 0);

    // clear flags
    FTFC->FSTAT = FTFC_FSTAT_ACCERR_MASK | FTFC_FSTAT_FPVIOL_MASK;

    FTFC->FCCOB[3] = 0x09;                  // erase flash section command
    FTFC->FCCOB[2] = (addr >> 16) & 0xFF;   // address[23:16]
    FTFC->FCCOB[1] = (addr >> 8) & 0xFF;    // address[15:8]
    FTFC->FCCOB[0] = addr & 0xF0;           // address[7:0] 128 bit aligned
    execute_command();
    asm volatile("cpsie i");
    return;
}

错误发生在execute_command():

void execute_command()
{
    FTFC->FSTAT |= FTFC_FSTAT_CCIF_MASK;
    while ((FTFC->FSTAT & FTFC_FSTAT_CCIF_MASK) == 0);
}

如前所述,只有在不逐步调试时才会发生这种情况。我怀疑这与闪光灯忙碌有关,但我没有找到任何可以帮助我理解的内容。

感谢您的帮助。

【问题讨论】:

  • 你的权利 FLASH 正忙。那么代码需要测试哪个位(在一个循环中)等待FLASH不忙?
  • 这就是重点。我找不到一个。有关问题的可能原因,请参阅下面的答案。
  • 所需的位将在fstat 寄存器中找到。建议阅读手册了解该寄存器的详细信息

标签: c cortex-m nxp-microcontroller


【解决方案1】:

我找到了解决方法。似乎 MCU 引发了总线故障,因为通过访问闪存,缓存的指令变得无效。通过写入LMEM-&gt;PCCRMR = 0; 禁用缓存解决了这个问题。

不过,如果有一个解决方案不包括完全禁用缓存,那将会很有趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 2021-10-20
    • 2021-02-11
    • 1970-01-01
    • 1970-01-01
    • 2017-07-17
    • 2017-07-14
    相关资源
    最近更新 更多