【MCAL】TC397+EB-tresos之存储器驱动配置- (Fls_17_Dmu/FlsLoader)

本篇文章首先从理论讲起,基于《MC-ISAR_TC3xx_UM_Fls_17_Dmu.pdf》与《MC-ISAR_TC3xx_UM_FlsLoader.pdf》介绍了Fls_17_Dmu与FlsLoader这两个存储器驱动模块的理论知识,然后详细介绍了在TC397平台使用EB-tresos对Fls_17_Dmu与FlsLoader这两个驱动模块进行配置与调试的实战过程,帮助第一次接触这个模块的读者能够更快的上手来实现符合自己项目要求的开发工作,完成对存储器的擦除、读、写等操作。文章介绍了项目常用的Fls_17_Dmu与FlsLoader这两个模块,前者与AUTOSAR基础软件存储栈配合共同为应用层提供运行时参数的读写服务(运行时DFlash操作),而后者常常用于BootLoader,完成程序的刷写升级功能(运行时PFlash操作)。

目录

概要

Fls_17_Dmu

文件结构

集成要点

FlsLoader

集成要点

环境与目标 

EB tresos配置

Fls_17_Dmu

FlsConfigSet

FlsGeneral

FlsSector

FlsLoader

General

FlsLoaderPFLASHConfig 

FlsLoaderDFLASHConfig 

存储器驱动调试

Fls_17_Dmu测试代码及结果

FlsLoader测试代码及结果


概要

Fls_17_Dmu

Fls_17_Dmu模块提供了根据AUTOSAR规范定义的配置和标准服务,用于初始化、读取、写入和擦除DFlash0。除此之外,还有一些非AUTOSAR规范定义的服务,例如Fls_17_Dmu_CompareWordsSync,Fls_17_Dmu_CancelNonEraseJobs,Fls_17_Dmu_VerifyErase,Fls_17_Dmu_VerifySectorErase,Fls_17_Dmu_GetNotifcaller等。用户通过FLS驱动模块封装的函数获得对底层 DFlash0的访问。FLS驱动程序的范围仅限于DFlash0。下图展示了FLS模块与其余模块的软硬件接口。

它主要的硬件外设为DMU - DFlash0,FLS驱动程序使用DMU进行读取、写入、暂停、恢复、用户内容计数(硬件实现)和擦除DFlash0等操作。FLS驱动程序使用DMU的主要硬件功能特性是:

  • 支持DFlash0的Single ended sensing mode。
  • 写入和擦除DFlash0。
    • 8字节page编程和32字节burst编程。
    • 支持多扇区擦除命令。

FLSLOADER和FLS驱动程序都会使用DMU。对DMU寄存器的访问不是并发的,所以FLS应在App运行时使用,FLSLOADER在Boot中使用。SFR标记通知的下列硬件事件在FLS驱动程序中使用:

  • 在编程、擦除、读取或擦除暂停/恢复操作时发生错误时,将设置错误标记。
  • 擦除验证错误(EVER):当擦除验证错误时,将设置此标志。
  • 编程验证错误(PVER):当编程验证错误时,将设置此标志。
  • 保护错误(PROER):此标志由硬件在受保护的内存区执行写入或擦除命令时设置。
  • 操作错误(OPER):当Flash标准接口(FSI)遇到任何错误时,此标志由硬件设置。
  • 序列错误(SQER):当执行不正确的DMU命令序列时,此标志由硬件设置。
  • 忙碌终止(EOBM):此标志允许在DMU忙碌结束之后触发中断进行擦除和编程等操作序列。

FLS还依赖于FSI,FSI支持以下功能:

  • FSI提供于DMU命令接口,用于所有闪存操作。
  • 用户内容计数结果由FSI作为在所选参考电流下所选页面中的logic 1 bits来给出。

FLS驱动程序使用来自FSI的硬件事件进行固化(用户内容计数)检查操作。

FLS依赖于SCU提供的时钟,ENDINIT和复位功能。驱动器需要Fsri、Ffsi和Fspb时钟信号才能正常工作。用户需要通过MCU模块设置系统时钟。

FLS依赖于SRC。SRC根据EOBM(繁忙结束)的结束来向CPU提出中断,EOBM指示硬件中正在进行的擦除或写入作业的结束或完成。SRC由IRQ驱动程序或用户软件配置。当FLS与Infineon FEE一起使时,中断模式不可用。

SRC引发的中断事件由CPU 处理。FLS驱动程序提供中断处理程序作为软件接口,其必须从ISR 中调用。以下硬件事件/中断通知DMU DFlash0:

  • 通过繁忙结束完成编程(EOB)。
  • 通过繁忙结束擦除完成(EOB)。

文件结构

模块涉及的C文件众多,这里就不一一赘述了,有兴趣的读者可以在《MC-ISAR_TC3xx_Config_Verification_Manual_Fls_17_Dmu.pdf》中获取介绍并在实际的代码研读中了解它的结构,我们这里介绍一下FLS模块生成的plugin文件,包含如下图所示部分。

  • Fls_17_Dmu.bmd:AUTOSAR格式的模块XML数据schema文件。
  • Fls_17_Dmu.xdm:Tresos格式的模块XML数据schema文件。
  • Fls_17_Dmu_Bswmd.arxml:AUTOSAR格式的模块描述文件。
  • Fls_17_Dmu_Catalog.xml:AUTOSAR格式的catalog文件。
  • MANIFEST.MF:包含FLS驱动元数据的Tresos插件支持文件。
  • anchors.xml:FLS驱动的Tresos anchors支持文件。
  • ant_generator.xml:当使用可变指针时,产生和重命名多个post-build配置的Tresos支持文件。
  • plugin.properties:Tresos插件支持文件。
  • plugin.xml:Tresos插件支持文件。

集成要点

模块与EcuM、DET、DEM、SchM等基础软件模块以及Memory mapping,Safety error,Notifications and callbacks和Operating system(OS)等相关集成没有什么特殊之处,这里就不再赘述了。我们这里简单介绍以下模块的中断连接。

以下事件可以触发对中断路由器(IR)的中断服务请求:

  • BUSY结束(EOB):如果DMU_HF_EER.EOBM=1B,且其中一个DMU_HF_STATUS标志 DOBUSY,D1BUSY或 PFlash标志从1切换到0,则触发中断服务请求(例如唤醒、擦除序列或程序序列)。
  • 操作错误(OPER):如果DMU_HF_EER.OPERM=1B且DMU_HF_ERRSR.OPER标志被设置
  • 保护错误(PROER):如果DMU_HF_EER.PROERM=1B且DMU_HF_ERRSR.PROER标志被设置。
  • 序列错误(SQER):如果DMU_HF_EER.SQERM=1B且DMU_HF_ERRSR.SQER标志被设置。
  • 编程验证错误(PVER):DMU_HF_EER.PVERM = 1B并且DMU_HF_ERRSR.PVER被置位。
  • 擦除验证错误(EVER):DMU_HF_EER.EVERM = 1B并且DMU_HF_ERRSR.EVER被置位。

触发中断的事件可以从DMU_HF_STATUS和DMU_HF_ERRSR寄存器中确定。当事件再次出现并且相应的状态标志仍然被设置时,必须触发中断事件。FLS驱动程序仅启用和使用EOB中断。FLS驱动程序不使用其他中断。在启动完成后,才产生BUSY结束中断。下图显示了DMU的中断连接:

驱动程序提供的中断处理程序的调用必须由用户完成(中断向量表或者OS),FLS驱动程序中断处理程序的示例如下:

ISR(DMUHOST_ISR)
/* Enable Global Interrupts */
{
ENABLE();
/* Call to Flash Interrupt function */
Fls_17_Dmu_Isr();
}

驱动程序的配置涉及以下步骤:

  • 系统时钟Fsys的配置。此配置是使用MCU模块完成的。
  • FLS驱动程序的配置:FLS驱动程序配置是作为post-build,扇区的配置应在FlsSectorList容器中完成。

FlsSectorList容器中的FlsSector需要以下参数:FlsNumberOfSectors(扇区数)FlsSectorSize(扇区大小)和FlsSectorStartAddress(扇区的开始/开始地址)。

Fls17_Dmu_MainFunction()是FLS驱动程序提供的唯一周期调度函数。该函数应定期调用,以便其可以在没有硬件中断支持的情况下处理作业。此API是用于提供Flash读、写、擦除和比较作业的处理的服务。擦除或写操作的超时监控是基于硬件(STM)定时器或者Fls17_Dmu_MainFunction调用周期。由于读时间非常小,无法通过Fls17_Dmu_MainFunction调用周期数进行监控,因此不进行读或比较的超时监控。用户可以通过Fls_17_Dmu_ControlTimeoutDet()来禁用超时监控。


FlsLoader

在第二代AURIX(TC3xx)微控制器中实例化了两种类型的非易失性存储器(NVM)。

  • 程序Flash(PFlash)存储程序代码和常量数据。
  • 数据闪存(DFlash)存储应用程序特定的数据。

FlsLoader驱动程序提供以下服务:

  • Flash的初始化和解初始化。
  • 将程序和数据写入Flash。
  • 清除Flash的内容。
  • 锁定和解锁Flash。

FlsLoader驱动程序的这些服务可在DFlash0和微控制器的所有PFlash存储器上运行。下图展示了FlsLoader模块与其余模块的软硬件接口。

它主要的硬件外设为DMU,FLSLOADER驱动程序使用DMU在PFlash/DFlash存储器上进行各种操作。该驱动程序使用的主要硬件功能特性是:

  • 针对PFlash进行擦除和写入操作。
    • 32bytes页写和256bytes的burst写。
    • 通过多扇区命令的擦除操作。
  • 针对DFlash0和UCB进行擦除和写入操作。
    • 8bytes页写和32bytes的burst写。
    • 通过多扇区命令的擦除操作。
  • 针对DFlash0的Single ended mode。
  • 通过UCB对PFlash/DFlash0的Bank进行基于密码的保护。

它基于的DMU硬件事件与FLS一致,这里就不再赘述了。它依赖的片内外设仅有SCU。文件结构这里也不再赘述了,有需要的小伙伴可以结合具体生成的文件和《MC-ISAR_TC3xx_UM_FlsLoader.pdf》进行深入了解。


集成要点

完整的驱动程序代码或写入和擦除API应该避免放到Flash中,可以放在RAM中,在boot升级流程中由上位机发送给ECU,这样可以保证在程序跑飞等异常情况下不会误用到写入和擦除API。模块与EcuM、DET、DEM、SchM等基础软件模块以及Memory mapping,Safety error,Operating system (OS),Notifications and callbacks等相关集成没有什么特殊之处,这里就不再赘述了。这里主要说一下模块涉及的Callout。

FlsLoader驱动程序,在写入和擦除操作期间循环判断繁忙状态,为应用程序提供可选的Callout功能。若要启用Callout函数,用户应使用FlsLoaderCallOutFunction配置Callout函数名称,并使用FlsLoaderCallOutTime配置定义超时间隔。如果启用,则在FlsLoader写入和擦除操作期间,将在配置的超时到时调用Callout函数。应用程序应在应用软件中定义Callout函数。下面的序列图显示了擦除操作时的Callout功能。同样,驱动程序在写入操作时也可以使用Callout功能。

驱动程序APIs被设计为非可重入的,这意味着如果正在进行Flash操作,然后发生中断或驱动程序调用其调用功能(如果启用),则在此调用功能或中断上下文中不应再次调用驱动程序APIS。FLSLOADER驱动程序的配置涉及以下步骤:

  • 配置以生成模块所需频率的系统时钟。此配置是使用MCU模块完成的。
  • 配置 FlsLoader驱动程序的一般准则:
    • 锁定检查是用于擦除和写入API的可选功能,可以关闭。驱动程序为擦除和写入API提供了可选的锁检查功能,启用该功能后,将检查当前擦除或写入请求下的扇区或内存是否受保护,如果发现扇区或内存受保护,则安全退出API,配置项为FlsLoaderEnableLockCheck。
    • 对于Flash的写入和擦除,可以配置不带DET、Deinit、Lock和Unlock的配置。

DFlash0保护可在Bank级配置。DFlash0支持的保护是读取和写入保护。PFlash保护可在扇区级配置。支持的PFlash保护有写保护、一次写保护(WOP)、一次可编程(OTP)保护。在执行锁定API之后,需要进行控制器复位,以使已配置的保护措施在硬件中生效。下面我们实现以下的保护配置。

  • 针对PFlash1的sector 0的bank 1写保护。
  • 针对PFlash2的sector 0的bank 2配置OTP保护。
  • 针对PFlash3的sector 0的bank 3配置WOP保护。
  • 针对DFlash bank 0配置写保护。

首先配置FlsLoaderPFlash1ProtConfig~FlsLoaderPFlash2ProtConfig如下。

选择PFlash 1、PFlash2、PFlash 3 的0扇区Banks作为写入、OTP和WOP保护。

然后设置Pflash访问密码。

最后设置DFlash的访问密码,配置为写入保护。

下面是描述锁操作的示例代码。

/* FlsLoader_Lock execution starts.. */
retval = FlsLoader_Lock();
/*Lock executed successfully*/
if(retval == FLSLOADER_E_OK)
{
/* FlsLoader_Lock Execution Passed */
/* Trigger controller reset for HW to install protections */
}
/* Following part should be executed after micro-controller reset */
/* Erasing the Sector-0 of PFlash Bank-1 where write Protection is enabled */
/*Address of Sector 0 of PFlash bank 1*/
FlsLoader_AddressType FlsLoader_Address = 0xA0300000U;
/*Number of sectors to be erased is 1*/
FlsLoader_LengthType Length = 1U;
retval = FlsLoader_Erase(FlsLoader_Address, Length);
/* Check if erase operation returned with FLSLOADER_E_LOCKED */
if (retval == FLSLOADER_E_LOCKED)
{
/* FlsLoader_Erase returned FLSLOADER_E_LOCKED. Sector is locked. */
}

解锁的示例代码如下:

/* FlsLoader_Unlock execution starts.. */
/* Unlocking the Write Protections installed for PFlash sectors.*/
/* PFLASH_ORIG ucb address*/
FlsLoader_AddressType FlsLoader_Address = 0xAF402000U;
FlsLoader_ValueType PfPassword[8];
/* PfPassword[8] is 8-word password for PFlash */
retval = FlsLoader_Unlock(FlsLoader_Address, &PfPassword[0]);
/* Check if PFlash Write protection Disabled */
if(retval == FLSLOADER_E_OK)
{
/* Write Protections installed for PFlash sectors are disabled*/
/* Erasing the Sector-0 of PFlash Bank-1 where write Protection is Disabled.*/
/*Address of Sector 0 of PFlash bank 1*/
FlsLoader_AddressType FlsLoader_Address = 0xA0300000U;
/*Number of sectors to be erased is 1*/
FlsLoader_LengthType Length = 1U;
retval = FlsLoader_Erase(FlsLoader_Address, Length);
/* Check if sector erased successfully */
if (retval == FLSLOADER_E_OK)
{
/* FlsLoader_Erase returned FLSLOADER_E_OK. Sector erased successfully.*/
}
}

在PFlash的擦除和写入命令执行时,驱动失能了Safety Endint protection,为了让我们的命令执行能够快速执行完已防止safety watchdog检测到驱动失能事件过长而导致的报警动作,我们需要实现以下四个函数,来关闭和打开中断。

void FlsLdr_ExclArea_PfProg_Enter(void)
{
SuspendAllInterrupts();
}
void FlsLdr_ExclArea_PfProg_Exit(void)
{
ResumeAllInterrupts();
}
void FlsLdr_ExclArea_PfErase_Enter(void)
{
SuspendAllInterrupts();
}
void FlsLdr_ExclArea_PfErase_Exit(void)
{
ResumeAllInterrupts();
}

环境与目标 

本文使用的为英飞凌提供的开发板KIT_A2G_TC397XA_TFT。

涉及的软件如下:

涉及的参考文档如下表。

序号参考资料内容
1《Infineon-AURIX_TC39x-UserManual-v02_00-EN》英飞凌TC39x用户手册
2《ApplicationKitManual-TC3X7-ADAS-V21.pdf》开发板KIT_A2G_TC397XA_TFT说明
3《MC-ISAR_TC3xx_UM_Fls_17_Dmu.pdf》英飞凌提供的TC3xx芯片FLS用户手册
4《MC-ISAR_TC3xx_UM_FlsLoader.pdf》英飞凌提供的TC3xx芯片FlsLoader用户手册

配置目标如下: 

  1. FLS实现读写与擦除。
  2. FlsLoader实现对DF/PF的读写与擦除。

EB tresos配置

Fls_17_Dmu

FlsConfigSet

配置截图如下:

这个容器我们需要关注的参数如下:

  • FlsDefaultMode: 该参数为设备初始化后DFLASH0后的默认读取方式。假设以MEMIF_MODE_SLOW模式(32字节)读取对用户来说是合理的,则选择默认值。
    • MEMIF_MODE_FAST:驱动程序工作在快速(突发)模式。
    • MEMI_ MODE_SLOW:表示驱动工作在慢速模式。
  • FIsMaxReadFastMode:在快速模式下,FLS的作业处理功能在一个周期内读取或比较的最大字节数。注意:FlsMaxReadFastMode配置的值应该大于FIsMaxReadNormalMode配置的值。
  • FlsMaxReadNormalMode:在正常模式下,FLS的作业处理功能在一个周期内读取或比较的最大字节数。

FlsGeneral

配置截图如下:

这个容器涉及了FLS的一些功能开关,包括FlsInitCheckApi与FlsIfxFeeUse,还有FlsTotalSize表示可访问的DFlash0大小。


FlsSector

配置截图如下:

FlsSectorSize表示Sector大小,FlsSectorStartaddress表示基于0xAF000000的偏移地址。


FlsLoader

General

这边默认的配置基本不用动,把FlsLoaderDevErrorDetect勾选掉即可。


FlsLoaderPFLASHConfig 

配置截图如下。

因为我们不使用保护,这里的保护和后边的Sector配置均不用改动,有兴趣的读者可以参照前文涉及的保护实现说明来了解具体的配置方法。


FlsLoaderDFLASHConfig 

配置截图如下:

 因为我们不使用保护,这里的保护类型和密码我们都没有改动。


存储器驱动调试

Fls_17_Dmu测试代码及结果

下面是MCAL提供的示例例程。我们需要在工程中以一定的周期来运行Fls_DemoTest。

#include "Std_Types.h"
#include "Fls_17_Dmu.h"
#include "log.h"

#define FLS_BUF_SIZE    (512U)
#define CALL_CYCLE      (100U * 1000U)

#define Time_s(num)     (num*1000U)

void Fls_FillDataBuf(void);
Std_ReturnType Fls_WriteDateTest(void);
Std_ReturnType Fls_SetupDFlashTest(void);
void Fls_CallDmuMainFunction(void);
static uint8 g_dataBuffer[FLS_BUF_SIZE];


/*******************************************************************************
** Traceability   : [cover parentID= ]                                        **
**                                                                            **
** Syntax         : void Fls_17_Dmu_Demo(void)                                **
**                                                                            **
** Description    : Calls data flash driver APIs for demo                     **
**                                                                            **
** [/cover]                                                                   **
**                                                                            **
** Service ID:    : NA                                                        **
**                                                                            **
** Sync/Async:    : Synchronous                                               **
**                                                                            **
** Reentrancy:    : Non Reentrant                                             **
**                                                                            **
** Parameters(in) : None                                                      **
**                                                                            **
** Parameters(out): None                                                      **
**                                                                            **
** Return value   : None                                                      **
**                                                                            **
*******************************************************************************/
void Fls_DemoTest(void)
{
  volatile uint32 delay = 0U;
  Std_ReturnType ret;
  
  log_trace("---------------  Start of FLS driver demo ---------------\r\n");

  static uint8 ulFlsInit = 0;
  if (ulFlsInit == 0) {
    /* Initialize FLS driver if not already done */
    Fls_17_Dmu_Init(&Fls_17_Dmu_Config);
    ulFlsInit = 1;
  }
  
  /* Clear the DFlash to start the FLS Demo */
  ret = Fls_SetupDFlashTest();
  if( ret == E_OK) {
    log_trace("1.Write Blk1 with data :  \r\n");
    /* 1. Fill buffer with 12345... data */
    Fls_FillDataBuf();
    ret = Fls_WriteDateTest();
    if(ret == E_OK) {
      log_trace("Result = Pass;\r\n");
    }
  }

  if( ret != E_OK) {
    log_error("Result = Fail;\r\n");
  }

  log_trace("---------------  End of FLS driver demo ---------------\r\n");
}


void Fls_FillDataBuf(void)
{
  uint16 i;
  for (i = 0; i < FLS_BUF_SIZE; i++) {
    g_dataBuffer[i] = (uint8)i;
    // log_trace(" %x ", g_dataBuffer[i]);
  }
}

Std_ReturnType Fls_WriteDateTest(void)
{
  Std_ReturnType ret;

  uint32 WriteSize;
  uint32 WriteAddr;
  volatile uint32 count = 0U;

  WriteSize = FLS_BUF_SIZE * 5U;
  WriteAddr = 0U;
  do {
    ret = Fls_17_Dmu_Write(WriteAddr, g_dataBuffer, FLS_BUF_SIZE);

    if(ret == E_OK) {
      while((Fls_17_Dmu_GetStatus() != MEMIF_IDLE) && (count < Time_s(2U)))
      {
        /* Wait till Job is finished */
        count++;
        Fls_lCallMain();
      }

      if( (Fls_17_Dmu_GetStatus() != MEMIF_IDLE) || (Fls_17_Dmu_GetJobResult() != MEMIF_JOB_OK)) {
        ret = E_NOT_OK;
      } else {
        ret = Fls_17_Dmu_Compare(WriteAddr, g_dataBuffer, FLS_BUF_SIZE);
        if(ret == E_OK) {
          count = 0U;
          while((Fls_17_Dmu_GetStatus() != MEMIF_IDLE) && (count < Time_s(1))) {
            /* Wait till Job is finished */
            count++;
            Fls_lCallMain();
          }
          if( (Fls_17_Dmu_GetStatus() != MEMIF_IDLE) || (Fls_17_Dmu_GetJobResult() != MEMIF_JOB_OK)) {
            ret = E_NOT_OK;
            log_error("compare data failed at: 0x%x \r\n", WriteAddr);
          }
        }

        log_trace("Written and compared data at: 0x%x \r\n", WriteAddr);

        if(ret == E_OK) {
          WriteSize -= FLS_BUF_SIZE ;
          WriteAddr += FLS_BUF_SIZE ;
        }
      }
    }
  } while((WriteSize > 0U) && (ret == E_OK));

  return(ret);
}


Std_ReturnType Fls_SetupDFlashTest(void)
{
  Std_ReturnType ret;

  volatile uint32 count = 0U;

  /* Clear the entire DFlash */
  log_trace("Erasing Flash... Please wait... \r\n");
  ret = Fls_17_Dmu_Erase(0, 0x100000);

  if(ret == E_OK) {
    while((Fls_17_Dmu_GetStatus() != MEMIF_IDLE) && (count < Time_s(2U))) {
      /* Wait till Erase completed */
      count++;
      Fls_lCallMain();
    }

    if( (Fls_17_Dmu_GetStatus() != MEMIF_IDLE) || (Fls_17_Dmu_GetJobResult() != MEMIF_JOB_OK)) {
      ret = E_NOT_OK;
    }
  }

  return(ret);
}


void Fls_CallDmuMainFunction(void)
{
  volatile uint32 callCycleTime;
  callCycleTime = 0U;

  while(callCycleTime <= CALL_CYCLE) {
    callCycleTime++;
  }

  Fls_17_Dmu_MainFunction();
}

我们可以将串口转USB的线连接开发板和PC,打开调试助手,会打印我们测试代码的执行结果。

TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:117: ---------------  Start of FLS driver demo ---------------
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:598: Erasing Flash... Please wait...
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:131: 1.Write Blk1 with data :
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:555: Written and compared data at: 0x700394d0
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:555: Written and compared data at: 0x700394d0
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:555: Written and compared data at: 0x700394d0
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:555: Written and compared data at: 0x700394d0
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:555: Written and compared data at: 0x700394d0
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:198: Result = Pass;
TRACE ../Srval/Demo/Demo_Fls_17_Dmu/Fls_17_Dmu_Demo.c:211: ---------------  End of FLS driver demo ---------------


FlsLoader测试代码及结果

下面的代码为Fls_17_Dmu的完成测试代码,包括了PFlash的擦、写、读和DFlash的擦、写、读。读取没有专门的API,直接访问地址即可。

 
volatile uint8 FlsLoader_DemoStateFlag = 0;
uint32  FlsLoaderDF_Address = 0xAF000000;
uint32  FlsLoaderPF_Address = 0x800F8000;
uint8   FlsLoader_WriteBuffer0[32] = {0xAA,0xBB,0xCC,0xDD,0xFF,0xEE,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xFF};
static uint32 DPbuffer[16] ={0x11,0x00,0x00};
void FlsLoader_DemoFunction(void)
{
	uint32 *SourcePtr;
	uint32 LoopCount;
	FlsLoader_Init(NULL_PTR);
 
	if(FlsLoader_DemoStateFlag == 1)
	{
		FlsLoader_Write((uint32)FlsLoaderDF_Address, 16, &FlsLoader_WriteBuffer0[0]);
		FlsLoader_DemoStateFlag = 10;
	}
	if(FlsLoader_DemoStateFlag == 2)
	{
		FlsLoader_Erase((uint32)FlsLoaderDF_Address, 1);
		FlsLoader_DemoStateFlag = 20;
	}
	if(FlsLoader_DemoStateFlag == 3)
	{
		FlsLoader_Write((uint32)FlsLoaderPF_Address, 32, &FlsLoader_WriteBuffer0[0]);
		FlsLoader_DemoStateFlag = 30;
	}
	if(FlsLoader_DemoStateFlag == 4)
	{
		FlsLoader_Erase((uint32)FlsLoaderPF_Address, 1);
		FlsLoader_DemoStateFlag = 40;
	}
	if(FlsLoader_DemoStateFlag == 5)
	{
		SourcePtr = (uint32*)FlsLoaderDF_Address;
        for(LoopCount = 0; LoopCount < 4;LoopCount++)
        {
        	DPbuffer[LoopCount] = *(SourcePtr + LoopCount);
        }
		FlsLoader_DemoStateFlag = 50;
	}
	if(FlsLoader_DemoStateFlag == 6)
	{
		SourcePtr = (uint32*)FlsLoaderPF_Address;
        for(LoopCount = 0; LoopCount < 4;LoopCount++)
        {
        	DPbuffer[LoopCount] = *(SourcePtr + LoopCount);
        }
		FlsLoader_DemoStateFlag = 60;
	}
}
			

下图是PFlash的擦除结果。

下图为PFlash的写入结果。


十六宿舍 原创作品,转载必须标注原文链接。

©2023 Yang Li. All rights reserved.

欢迎关注 『十六宿舍』,大家喜欢的话,给个👍,更多关于嵌入式相关技术的内容持续更新中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值