MPC5744 烧录一直停留在 98% 的解决方法

关键字 :NXPMPC5744

1. 目的

         本人在调试一块主控为 MPC5744 的板子时 ,有时候在烧录时 ,发现烧录总是停在 98% ,卡在 CRC 这里 ,在查找和看资料之后 ,发现了几种解决方法 :

  1. 使用 pemicro progpcz tool 清除 flash
  2. 使用 progpcnexus 清除 flash
  3. 在 S32DS 中 ,通过程序在 RAM 运行清除 flash

这里重点讲第三种方法 。

2.Flash 介绍

2.1 Flash简介

         在 MPC5744 中 ,flash 共有 2.5MB ,分为了 7 个 partition (以下用分区表示) 20 block (以下用块表示) :

  1. 2 x 16KB ,分区为 0 (起始地址 :0x800000 ,是 data flash ,可用作 EEPROM 仿真)
  2. 2 x 32KB ,分区为 2 和 3 (起始地址 :0x808000 ,是 data flash ,可用作 EEPROM 仿真)
  3. 2 x 16KB ,分区为 1 (起始地址 :0xF98000)
  4. 6 x 64KB ,分区为 4 和 5 (起始地址 :0xFA0000)
  5. 8 x 256KB ,分区为 6 和 7 (起始地址 :0x1000000)

如图 1 ,详细记录了每个块的分区 、容量和地址 ,这里的 flash 支持在其中一个分区写入时 ,

在另外一个分区读取数据 ,但需要注意的是 ,不可以在同一个分区的边写边读 。

       在手册中将这些块按容量分成 4 部分 :

  1. Low address space :分区 0 和 1
  2. Mid address space :分区 2 和 3
  3. High address space :分区 4 和 5
  4. 256KB address space :分区 6 和 7

         在 flash 中 ,一个页 (page) 是256 bit (32 byte) ,在编程中可以以 32 bit 或 64 bit 间隔寻址 ,一次性写入最大的数量为 1024 bit (128 byte) ,并且每次读取返回 256 bit (32 byte ,但这是从 flash 里面读出来的 ,若我们是间接在寄存器读取数据 ,则只能读取到 32 bit) 。但需要注意的是 ,flash 支持 ECC 即检验数据的功能 ,分为单位校验和双位校验 ,每当 flash 编程时 ,对应的 ECC 位也是被编程 ,且 ECC 是 64 bit 对齐的 ,所以导致了每次编程最小 64 bit ,即写入的编程地址要 8 字节对齐 。若是不 8 字节对齐 ,例如 :在某一地址 adr 编程时 ,ECC 同样被编程 ,且是对应的 64 bit 编程 ,若是以这个地址 adr + 4 继续编程 ,由于对应的 ECC 已经编程 ,会导致此次编程出错 。

         需要注意的是 ,对 flash 写入有两种方法 ,一种是擦除 ,只能将 flash 内容变为逻辑 1 ,另一种是编程 ,只能将对应内容由 1 变为 0 ,而不能由 0 变为 1 。所以如果已经编程 flash ,需要重新修改时 ,需要先擦除再编程 ,防止出错 。需要注意的是 ,擦除是直接擦除一整个块 ,即这个块有多大 ,就擦除多大的区域 。
 

                                                     图 1 flash 地址映射与分区

Flash 可处于三种模式中 ,分别是使用模式 ,低功耗模式和 UTest 模式 。

  1. 使用模式 :可对 flash 进行编程 ,擦除和读取等正常操作 ,一般运行时处于此模式
  2. 低功耗模式 :处于此模式之间 ,先确保对 flash 的所有操作已经结束 ,进入此模式后 ,不可在操作此模式
  3. UTest 模式 :检测 flash 完整性的一种模式 。

在此芯片中 ,有一个 flash 存储控制器 ,如图 2 ,这里有缓冲器 ,64 指 64 bit 总线 ,每个 entry

可存储 256 bit ,即一个页 ,而这里总共有 2 x 4 x entry ,图 3 是说明 flash 可以配置重映射 片上 RAM ,用于校准数据 。

                                                             图 2 flash 控制器框图

                                         图 3 以平台为中心的简单框图与闪存控制器

2.2 Flash 编程

         对于 Flash 的编程 ,首先被锁或禁用的块是不能被编程的 ,需要以下步骤 :

  1. MCR[PGM] 由 0->1 ,即 Flash 能执行一个编程序列 。
  2. 从编程起始地址写入数据 ,但记住 ,这个地址是 64 位对齐的 ,而写入的数据至少 32 位 。
  3. 如果超过一个字或双字要被编程 ,写入一个字或双字分别对应不同地址 。
  4. MCR[EHV] 由 0->1 ,开启执行编程序列 。
  5. 等待 MCR[DONE] = 1 。
  6. 验证 MCR[PEG] = 1 ,表明编程成功 。
  7. MCR[EHV] 由 1->0 。
  8. 有更多地址需要编程 ,返回步骤 2 。
  9. MCR[PGM] 由 1->0 ,即 Flash 不能执行一个编程序列 。

          为了读取 Flash ,编程序列能够被挂起 ,但在挂起期间不能执行擦除和编程操作 。但是 ,挂起期间 (无论是挂起擦除序列或编程序列) , 如果读取的编程挂起或擦除挂起的块的数据的 ,返回的是不确定的值 ,这不可取 。当然 ,如果是在不同分区 ,可以边读边写 。

         当 MCR[PGM] 、MCR[DONE] 和 MCR[EHV] 是 1 ,可以将 MCR[PSUS] 由 0->1 将编程序列任务挂起 ,在 MCR[EHV] = 1 时可以将 MCR[PSUS] 由 1->0 将编程序列任务恢复运行 。

         注意 Flash 操作是有超时的 ,所以不能频繁将编程序列任务挂起 。

         Flash 编程可以启用过编程 ,启用的块已经被编程的 64 位将无法再次编程 ,而不影响擦除操作 。尝试过编程 MCR[PEG] 将指示编程失败 。

2.3 擦除

被锁和禁用的块的不可以进行擦除操作的 ,步骤如下 :

  1. MCR[ERS] 由 0->1 ,即 Flash 能执行一个擦除序列 。
  2. 通过寄存器 SEL0 、SEL1 、SEL2 和 SEL3 选择要进行擦除的块 ,
  3. 向 Flash 写入数据 ,这是与擦除内锁写有关 。
  4. MCR[EHV] 由 0->1 ,开启执行擦除序列 。
  5. 等待 MCR[DONE] = 1 。
  6. 验证 MCR[PEG] = 1 ,表明擦除成功 。
  7. MCR[EHV] 由 1->0 。
  8. 有更多块要被擦除 ,返回步骤 2 。
  9. MCR[PGM] 由 1->0 ,即 Flash 不能执行一个擦除序列 。

          如果 MCR[DONE]=1 、MCR[EHV]=1 、MCR[ESUS]=1 ,则将 MCR[EHV] 由 1->0 将中止擦除操作 ,直接到步骤 8 ,并且MCR[PEG]=0 指示擦除失败 。注意如果擦除序列挂起时 ,不能中止擦除序列 。

         为了读取 Flash 或编程 Flash(擦除挂起编程) ,擦除序列能够被挂起 ,期间不能再挂起擦除序列 , 然后这个在擦除挂起期间的编程序列同样可以被挂起 , 只允许一次挂起一个编程序列和擦除序列 。当然 ,如果是在不同分区 ,可以边读边擦除 。

         当 MCR[ERS] 、MCR[DONE] 和 MCR[EHV] 是 1 ,MCR[PGM]=0 ,可以将 MCR[ESUS] 由 0->1 将擦除序列任务挂起 ,此时要开始编程序列需要先将 MCR[EHV]=0 。在 MCR[EHV] = 1 和 MCR[PGM]=0 时可以将 MCR[ESUS] 由 1->0 将擦除序列任务恢复运行 。

3. 代码编写

         在这里使用的开发软件为 S32DS V2.1 ,使用官方 SDK 。

首先在 Processor Expert 添加 flash_c55 ,生成代码后 ,直接使用 API 写代码 。这里仅仅写有关 flash 的部分 。

图 4 Processor Expert 配置

status_t ret = STATUS_SUCCESS;    // 操作状态变量

uint32_t buffer[1024];             // 缓存数组

flash_block_select_t blockSelect; // 块选择

flash_state_t opResult;

 

// 禁用缓存

    DisableFlashControllerCache(FLASH_PFCR1, FLASH_FMC_BFEN_MASK, &pflash_pfcr1);

    DisableFlashControllerCache(FLASH_PFCR2, FLASH_FMC_BFEN_MASK, &pflash_pfcr2);

    // 初始化 Flash

    ret = FLASH_DRV_Init();

DEV_ASSERT(ret == STATUS_SUCCESS);

// 不对 UTEST 块进行操作 ,直接上锁

    ret = FLASH_DRV_SetLock(C55_BLOCK_UTEST, 0x1U);

    if (STATUS_SUCCESS != ret)

    {

        return ret;

    }

    // 对要擦除的块解锁

    ret = FLASH_DRV_SetLock(C55_BLOCK_LOW, 0x00);

    if (STATUS_SUCCESS != ret)

    {

        return ret;

    }

   

    ret = FLASH_DRV_SetLock(C55_BLOCK_MID, 0x00);

    if (STATUS_SUCCESS != ret)

    {

        return ret;

    }

   

    ret = FLASH_DRV_SetLock(C55_BLOCK_HIGH, 0x00);

    if (STATUS_SUCCESS != ret)

    {

        return ret;

    }

   

    ret = FLASH_DRV_SetLock(C55_BLOCK_256K_FIRST, 0x00);

    if (STATUS_SUCCESS != ret)

    {

        return ret;

    }

    ret = FLASH_DRV_SetLock(C55_BLOCK_256K_SECOND, 0x00);

    if (STATUS_SUCCESS != ret)

    {

        return ret;

     }

// 选择要擦除的块

// Low address space 是分区 0 和 1 ,共 4 块

blockSelect.lowBlockSelect = 0xFU;

// Mid address space 是分区 2 和 3 ,共 2 块

blockSelect.midBlockSelect = 0x2U;

// High address space 是分区 4 和 5 ,共 6 块

blockSelect.highBlockSelect = 0x3FU;

// 256KB address space 是分区 6 和 7 ,共 8 块

    blockSelect.first256KBlockSelect = 0xFFU;

    blockSelect.second256KBlockSelect = 0x0U;

    g_usrCnt = 0U;

    // 进行擦除操作

ret = FLASH_DRV_Erase(ERS_OPT_MAIN_SPACE, &blockSelect);

// 擦除指令操作成功 ,等待擦除完成

    if (STATUS_SUCCESS == ret)

{

        // 直到退出擦除正在进行才可以退出此循环

        do

        {

            // 检查此时 falsh 的擦除状态

            ret = FLASH_DRV_CheckEraseStatus(&opResult);

        }while(ret == STATUS_FLASH_INPROGRESS);

    }

    if (STATUS_SUCCESS != ret)

    {

        return ret;

    }

         记住 ,要将程序放在 RAM 里面运行 (此时 flash 也烧录不进去) ,这样所有 flash 擦除之后 ,就可以重新正常烧录 。


                                                                                                                                                                                   图 5 debug 配置

4. 参考资料

①  NXP 官网 :《MPC5744PRM》

下载链接 :

https://www.nxp.com/products/processors-and-microcontrollers/power-architecture/mpc55xx-5xxx-mcus/ultra-reliable-mpc57xx-mcus/ultra-reliable-mpc574xp-mcu-for-automotive-industrial-safety-applications:MPC574xP?tab=Documentation_Tab

 

  • NXP 社区 :《Unable to start debug session on MPC5748G board .download stops at 98%》

下载链接 :

https://community.nxp.com/t5/S32-Design-Studio/Unable-to-start-debug-session-on-MPC5748G-board-download-stops/m-p/880973?commentID=1108905&et=watches.email.thread#comment-1108905

 

  • NXP 社区 :《DEVKIT MPC5748G S32DS download problem ,blocking at Verifying object file CRC-16 to device ranges》

下载链接 :

https://community.nxp.com/t5/S32-Design-Studio/DEVKIT-MPC5748G-S32DS-download-problem-blocking-at-Verifying/m-p/789755

 

 

 

 

 

 

 

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论