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.

[参考译文] RM48L952:无法写入闪存组0上的闪存扇区0至4

Guru**** 2478765 points
Other Parts Discussed in Thread: RM48L952, SEGGER

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/688348/rm48l952-unable-to-write-to-flash-sectors-0-through-4-on-flash-bank-0

器件型号:RM48L952
主题中讨论的其他器件: SEGGER

您好!

我正在尝试创建一个应用程序来改变引导加载程序、该引导加载程序存储在闪存组0的闪存扇区0到4中(地址从0x00000000开始)。
我当前无法始终如一地将字节写入 RM48L952芯片闪存组0中的闪存扇区0至4。
我已经制作了写入扇区5、6和7的测试代码、没有任何问题、但是在写入扇区0至4时、我的程序间歇性挂起、尤其是在扇区4的开始。
目前、此代码将只清除扇区0、但不写入任何内容。 当我在 while 循环的末尾添加了 xTaskDelay (1)时(将线程延迟1ms)、开始在扇区0到3中写入、但仍会在扇区4的开头挂起。
此外、我偶尔会得到 0x10的 Fapi_status、这毫无意义、因为 status enum 中没有相应的值。
我知道循环有几个令人厌烦的无限循环、但我在调试时保留断点、它们仅在 Fapi_status 为0x10时导致挂起。 我认为我在 Fapi_issueProgrammingCommand 中导致了错误、但我不确定是什么。
扇区0到4有什么特别的吗?
有人告诉我嵌入不正确的代码可能会有问题、因此 TI 帮助台人员会将我的代码片段附加到此帖子。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    来自 Matt 的代码:

    而(bytes_left > 0){

     

                   if (isSectorStart ((uint32_t) flash_address)))

                   {

     

                       taskENTER_critical ();

                       //在发出擦除命令之前确保 FSM 不忙。

                       while (FAPI_CHECK_FSM_READY_BUSY = Fapi_Status_FsmBusy);

     

                       //数据在 bank1开始时首先将其擦除

                       Fapi_status = Fapi_issueODE19 CommandWithAddress (Fapi_EraseSector、(uint32_t *) flash_address);

                       while (FAPI_CHECK_FSM_READY_BUSY = Fapi_Status_FsmBusy);

                       Fapi_status =(Fapi_StatusType) FAPI_GET_FSM_STATUS;

                       if (fapi_status!= fapi_Status_Success){

                           //HealthMonitor::SetFault (flash_programming_failure);

                           BootMonitor::Set_ddownload_state (flash_failure);

                           适用于(;);

                       }

                       taskEXIT_critical ();

                   }

     

                   /*如果要使用 Fapi_AutoEccGeneration 选项,则必须设置要编程的数据大小

                    * 8或16字节、因为 ECC 是基于64位(8字节)计算的。 *

                   uint32_t write_bytes =(bytes_left > flash_page_size? flash_page_size:bytes_left);

     

                   taskENTER_critical ();

     

                   Fapi_status = Fapi_issueProgrammingCommand ((uint32_t *) flash_address、

                           source_ptr、

                           Write_Bytes、

                           0、

                           0、

                           Fapi_AutoEccGeneration);

                   flashLoader.num_Bytes_write= write_bytes;

     

                   while (FAPI_CHECK_FSM_READY_BUSY = Fapi_Status_FsmBusy);

                   Fapi_status =(Fapi_StatusType) FAPI_GET_FSM_STATUS;

     

                   if (fapi_status!= fapi_Status_Success){

                       //HealthMonitor::SetFault (flash_programming_failure);

                       BootMonitor::Set_ddownload_state (flash_failure);

                       适用于(;);

                   }

     

                   taskEXIT_critical ();

     

                   bytes_left -= FLASH_PAGE_SIZE;

                   FLASH_ADDRESS += FLASH_PAGE_SIZE;

                   source_ptr += flash_page_size;

                   

                   if (bytes_left <=(byte_printion_count -(16 * 1024))

                   {

                     _debug.Syslog (log_info、"在地址%d 中刷写%d 个字节 %d 字节剩余"、WRITE_Bytes、FLASH_ADDRESS、bytes_left);

                     xTaskDelay (10);

                     byte_prints_count = bytes_left;

                   }       

                   //xTaskDelay (1);

     

               }

     

     

    bool FlashLoader:isSectorStart (uint32_t 地址)



     uint32_t sec_size = 0x020000;

     uint32_t small_sec_size = 0x08000;

     

     if (地址> 0x0001FFFF)

     {

         if (address % sec_size = 0)

         {

           返回 true;

         }

     }

     其他

     {

         if (address % small_sec_size = 0)

         {

           返回 true;

         }

     }

     

     返回 false;




    谢谢、

    Gabe Garza

    TI 支持

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

    您执行闪存操作(擦除/编程)的代码在哪里? 如果代码(文本)位于 sector0~4中、则无法擦除此区域。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    我正在执行的代码不在组1中、因此我不认为存在冲突。

    我已从我的映射文件中附加一个图像、以向您显示 Fapi 代码的位置。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我更多次使用 Fapi、并且能够擦除引导加载程序所在的每个相关扇区(我已经使用 Segger JFlash 验证了这一点)。 写入第一行字节的行为似乎会导致问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Matthew、您好!

    中断矢量位于0x00至0x20之间。 如果扇区0被擦除、任何异常(数据中止、预取等)都会导致问题。 您是否尝试仅擦除扇区4、并将扇区0的内容保留在此处? 我从未尝试从应用程序更新引导加载程序。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我刚刚尝试从扇区4 (地址0x20000)开始写入数据。 我能够擦除该扇区、但未对其进行编程。 该程序刚刚开始从引导加载程序中执行某些操作、并在部分擦除后挂起。 我在处理中止的代码部分有断点、因此据我所知、没有发生异常。

    此后、我立即尝试从扇区5 (地址0x40000)开始执行相同的测试、没有问题。 所有信息均已正确刷写。

    我不知道这些地址有什么不同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为只有 bank1中的应用程序代码被执行、并且只有 bank0中使用的代码是中断矢量(0x0~0x20)。 如果 bank0中的代码正在运行、则在您尝试擦除此区域时会导致问题。

    您是否将 MPU 配置为防止闪存扇区被擦除?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我的代码中有时会出现故障情况、导致电路板重启并输入引导加载程序代码(正在覆盖)。 如果挂起时间过长、则主板将重新启动。 基本上、当我的程序开始在 Bank0中执行时、出现了可怕的错误、电路板已复位。

    因此、在正常情况下、该代码(引导加载程序)不会从组0执行、直到所有代码都已成功刷写并且电路板已上电。

    很抱歉、这很模糊、我正在处理一个背景知识很少的遗留项目。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、再说一次、

    我已经与一些同事交谈过、并查看了您的答案以及其他用户的帖子。 我认为我的问题是我没有禁用中断。

    这是否可能是我的问题的根源(我正在擦除0x00至0x20、这似乎就是这样)?

    我已经浏览过一些文档、但我不确定如何禁用中断? 您能否向我展示一个示例或相关文档来帮助解决此问题?

    谢谢、

    Matt

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

    您可以通过设置 CPSR 寄存器的 I 位和 F 位来禁用 IRQ 和 FIQ。 sys_core、asm 中的两个函数可用于禁用 IRQ 和 FIQ。

    ;------------------------------------------------------------------
    ;禁用 FIQ 中断
    .def _disable_FIQ_interrupt_
    asmfunc
    _disable_FIQ_interrupt_
    CPsid f
    BX LR
    endasmfunc

    ;------------------------------------------------------------------
    ;禁用 FIQ 中断
    .def _disable_IRQ_interrupt_
    asmfunc
    _disable_IRQ_interrupt_
    CPsid I
    BX LR
    endasmfunc

    其他异常(UNDEF、预取、数据中止)不能被禁用。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。


    此时、我使用的是 BL_FLASH.c 中的示例代码、但未进行任何修改、因此我非常确信闪存代码正常(它仍可在不包含引导加载程序的其他地址工作)。

    我尝试禁用中断、但遇到了阻碍

    我注意 到、尽管调用_disable_FIQ_interrupt_、但 CPSR 中的相关位并未更改。 我进行了一些挖掘、由于 SCTLR 寄存器中的 NMFI 位置位、它看起来无法通过软件进行更改。 该位似乎是通过硬件置位的、不能简单地通过代码进行更改。

    您是否知道禁用快速中断的任何其他方法? 计时器中断是否计为快速中断?

    此外、我在异常矢量中放置了断点、以查看我获得的异常类型(这是在它们被擦除之后、因此在这里它将持续失败)。

    它在0x0C 处停止、此地址为预取中止地址。 我尝试禁用中止只是为了查看发生了什么、但也无法像 FIQ 位那样更改 CPSR 中的 ABORT 位。

    是否可以禁用中止? 我应该如何处理这一问题?

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

    有一个称为预取中止(IFAR)的故障地址寄存器。 这表示导致故障的存储器访问地址。 IFAR 寄存器列在"Registers"视图窗口中。

    当系统控制寄存器中的 NMFI 被置位时、FIQ 不能被软件屏蔽。