完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、介绍 为了便于进一步了解C90TFS驱动在kinetis芯片中的实现情况,本文以测试平台TWR-KL25Z48M为例,集合C90TFS驱动中的demo_normal工程具体讲解如何使用C90TFS flash驱动实现kinetis 芯片的flash操作。 C90TFS FLASH下载链接: http://cache.freescale.com/files/32bit/software/C90TFS_FLASH_DRIVER.exe?fromsite=zh-Hans 二、前提准备 本章节主要讲解C90TFS中,关于KL25的例程工程构成,配置文件情况,要讲解的例程选择以及测试平台的选择等,为后续的详细代码讲解以及验证做一个准备。 1、C90TFS flash KL25例程工程构成 安装好C90TFS flash之后,可以从如下的路径找到KL25的相关代码。 安装路径Standard Sotfware Driverv101C90TFSDemosbuildMKL25Z128xxx4 可以看到,供有两种编译器的代码,分别为IAR以及CW10.4, CW10.4 的工程可以用CW10.4及其以后的版本打开。IAR的工程可以使用IAR embedded workbench for ARM 6.4.2之后的版本打开。 打开路径下IAR的工程,可以看到C90TFS具体包含的KL25flash例程情况,如下图: 从上图中可以看到,一共具有4个例程, 具体例程的功能已经在图中标出。本次例程讲解使用demo_normal例程,旨在让大家熟悉C90TFS flashAPI函数的使用。 2、 C90TFS flash例程配置文件情况 这里以demo_normal 工程为例,讲解配置文件。程序一共有两种运行方式, 分别为从RAM运行,以及从Flash运行。通过配置相应的.icf文件(IAR)或者.ld文件(CW 10.x)实现。 IAR中,.icf文件可以打开project后在link_file文件夹下找到。 CW中,.ld 文件可以打开project后在project_settings->linker_files文件夹下找到。 这里以CW工程为例讲解,IAR的情况也类似,主要是空间的起始结束地址,以及堆栈分配,中断向量的分配等。 (1) CW16KB_Ram.ld (2) CW128KB_Pflash.ld 3. 测试平台 CW10.6 以及TWR-KL25Z48M。 选择使用CW10.6,是因为,测试的时候,可以直接看出哪些代码在编译范围内,便于查看代码,如下图: 三、代码讲解及测试 通过实例的代码讲解即测试,进一步了解flash驱动的API函数使用。 1:KL25的结构体定义 原FLASH_SSD_CONFIG结构体定义: typedef struct _ssd_config { UINT32 ftfxRegBase; UINT32 PFlashBlockBase; UINT32 PFlashBlockSize; UINT32 DFlashBlockBase; UINT32 DFlashBlockSize; UINT32 EERAMBlockBase; UINT32 EEEBlockSize; BOOL DebugEnable; PCALLBACK CallBack; } FLASH_SSD_CONFIG, *PFLASH_SSD_CONFIG; 其中: ftfxRegBase,UINT32 , flash模块基地址 PFlashBlockBase ,UINT32,Pflash块的基地址 PFlashBlockSize,UINT32,Pflash块的大小 DFlashBlockBase,UINT32,FlexNVM区中划分为Dflash的基地址。无FlexNVM则无用 DFlashBlockSize,UINT32,FlexNVM区中划分为Dflash的块大小 EERAMBlockBase,UINT32,flexRAM的基地址。 EEEBlockSize,UINT32,EEPROM的大小(flexRAM)中 DebugEnable,BOOL,后台调试模式,TRUE:使能调试模式;FALSE:禁止调试模式 CallBack,函数指针,回调函数用于时间要求高的事件 KL25变量声明: FLASH_SSD_CONFIG flashSSDConfig= { FTFx_REG_BASE, /* FTFx controlregister base */ PFLASH_BLOCK_BASE, /* base address ofPFlash block */ PBLOCK_SIZE, /* size of PFlashblock */ DEFLASH_BLOCK_BASE, /* base address ofDFlash block */ 0, /* size of DFlashblock */ EERAM_BLOCK_BASE, /* base address ofEERAM block */ 0, /* size of EEEblock */ DEBUGENABLE, /* background debugmode enable bit */ NULL_CALLBACK /* pointer to callbackfunction */ }; 其中: FTFx_REG_BASE = 0x40020000 PFLASH_BLOCK_BASE 0x00000000 DEFLASH_BLOCK_BASE 0xFFFFFFFF PBLOCK_SIZE 0x00020000 /* 128KB size */ EERAM_BLOCK_SIZE 0x00000000 DEBUGENABLE 0x00 NULL_CALLBACK ((PCALLBACK)0xFFFFFFFF) FTFx_REG_BASE的基地址,可以从用户手册中查看 2, flash初始化 /************************************************************************** * FlashInit() ***************************************************************************/ ret = FlashInit(&flashSSDConfig); if (FTFx_OK != ret) { ErrorTrap(ret); } 初始化API函数,保护清楚错误状态标志位,设置内存的Dflash以及EEPROM大小等情况,由于KL25没有flexNVM以及flexRAM,所以这部分只是设置了Dflash以及EEPROM大小为0. 3,擦除整个flash ret = FlashEraseAllBlock(&flashSSDConfig, FlashCommandSequence); if (FTFx_OK != ret) { ErrorTrap(ret); } 查看API函数FlashEraseAllBlock,会发现其实执行的就是flash全片擦除指令 UINT32 FlashEraseAllBlock (PFLASH_SSD_CONFIG pSSDConfig, pFLASHCOMMANDSEQUENCEpFlashCommandSequence) { UINT32 ret; /* return code variable */ /*clear RDCOLERR & ACCERR & FPVIOL flag in flash status register. Write 1to clear*/ REG_WRITE(pSSDConfig->ftfxRegBase +FTFx_SSD_FSTAT_OFFSET,FTFx_SSD_FSTAT_ERROR_BITS); /*passing parameter to the command */ REG_WRITE(pSSDConfig->ftfxRegBase + FTFx_SSD_FCCOB0_OFFSET,FTFx_ERASE_ALL_BLOCK);// FTFx_ERASE_ALL_BLOCK=0x44 /*calling flash command sequence function to execute the command */ ret = pFlashCommandSequence(pSSDConfig); /*Enter Debug state if enabled */ if (TRUE ==(pSSDConfig->DebugEnable)) { ENTER_DEBUG_MODE; } return(ret); } 命令正如KL25的用户手册规定的一样: 运行之后,可以查看整个flash,会发现就连0X40C,锁的地方0x40c地址也被擦除成0xFF了。 4 整片flash验证 for (i = 0; i < 0x2;i ++) /*scan for normal and user margin levels */ { ret = FlashVerifyAllBlock(&flashSSDConfig, i, FlashCommandSequence); if (FTFx_OK != ret) { ErrorTrap(ret); } } 擦除了整片的FLASH之后,使用FlashVerifyAllBlock检查下整个flash,其实就是read 1s all blocks command,详细描述可以参考器件RM, command 如下: 5 写入加密位到flash configuration field. UINT8 unsecure_key[PGM_SIZE_BYTE] = {0xFE,0xFF, 0xFF, 0xFF}; /*Program the Security Byte in the Flash Configuration Field to an unsecurevalue */ ret = FlashProgram(&flashSSDConfig, SECURITY_LOCATION,PGM_SIZE_BYTE, unsecure_key, FlashCommandSequence); if (FTFx_OK != ret) { ErrorTrap(ret); } 函数目的就是给0X40C写入0XFE,也就是让之前因为擦除而导致0X40C为锁状态的情况修改为解锁。该函数使用是program longword command. 写之前flash configuration field,加密字节0X40C情况如下: 可以看到,运行解密代码之后,0X40C已经变为0XFE,也就是芯片处于解锁状态。 6 给0x00-0XFF写入0到256数据 for(i = 0; i < BUFFER_SIZE_BYTE; i++) { /*Set source buffer */ buffer = i; } /*Program to the first location of PFLASH */ destination = flashSSDConfig.PFlashBlockBase; size = BUFFER_SIZE_BYTE; ret = FlashProgram(&flashSSDConfig, destination, size, buffer,FlashCommandSequence); if (FTFx_OK != ret) { ErrorTrap(ret); } 和第5条一样,也是使用长字节编程写入的。下面直接给出测试结果: 代码中,后面的给0XC00到0X1300也是用的同样的方法写程序的。 7 FlashReadResource功能 /************************************************************************** * FlashReadResource() * ***************************************************************************/ /*Read on P-Flash */ destination =flashSSDConfig.PFlashBlockBase + PFLASH_IFR; /*Start address of Program Once Field */ ret = FlashReadResource(&flashSSDConfig, destination, DataArray,0x0, FlashCommandSequence); if (FTFx_OK != ret) { ErrorTrap(ret); } 该功能是读取IFR中的0XC0开始的四个字节到DataArray[PGM_SIZE_BYTE]; 从下面的图可以知道, DataArray的地址是0X20002054. 查看0X20002054的连续四个字节的数据如下: 可以知道,读出来的0XC0开始的IFR数据为0XFF。 IFR地址的情况如下,其实0XC0输入一次编程区域。 8 FlashGetSecurityState功能 securityStatus = 0x0; ret = FlashGetSecurityState(&flashSSDConfig, &securityStatus); if (FTFx_OK != ret) { ErrorTrap(ret); } 其实就是读取FTFA_FSEC加密位到securityStatus,securityStatus=1 未加密, 2 加密,后门秘钥允许,4 加密,后门秘钥禁止。 测试结果securityStatus=1, 即不加密 9 按照sector擦除flash j = 1; destination = flashSSDConfig.PFlashBlockBase; while ((destination +BYTE2WORD(j*FTFx_PSECTOR_SIZE)) < (flashSSDConfig.PFlashBlockBase +BYTE2WORD(flashSSDConfig.PFlashBlockSize)))// 0x400<0x20000 { size = j*FTFx_PSECTOR_SIZE; // j*0x400, j timessectors ret = FlashEraseSector(&flashSSDConfig, destination, size, FlashCommandSequence); // just erased one sector, from 0x00 to 0x3ff if (FTFx_OK != ret) { ErrorTrap(ret); } /*Verify section for several sector of PFLASH */ number = FTFx_PSECTOR_SIZE/PRD1SEC_ALIGN_SIZE; for(i = 0; i < 0x2; i++) { ret = FlashVerifySection(&flashSSDConfig,destination, number, i,FlashCommandSequence); if (FTFx_OK != ret) { ErrorTrap(ret); } } destination += BYTE2WORD(flashSSDConfig.PFlashBlockSize/PBLOCK_NUM - size); // sector erase,after erased, thenmins it. j ++; } 功能就是擦除0X00到0x3FF,这里以前面字节为例查看结果: 10 flash保护代码测试 /************************************************************************** * PFlashGetProtection() * ***************************************************************************/ ret = PFlashGetProtection(&flashSSDConfig, &protectStatus1); if (FTFx_OK != ret) { ErrorTrap(ret); } /************************************************************************** * PFlashSetProtection() * ***************************************************************************/ protectStatus1 = 0x12ABCDEF; ret = PFlashSetProtection(&flashSSDConfig, protectStatus1); if (FTFx_OK != ret) { ErrorTrap(ret); } /*Call PFlashGetProtection to verify the set step */ ret = PFlashGetProtection(&flashSSDConfig, &protectStatus1); if (FTFx_OK != ret ||0x12ABCDEF != protectStatus1) { ErrorTrap(ret); } Flash保护代码功能测试,上面的代码是首选获取flash的代码保护情况,然后设置flash的保护,最后再获取设置后的flash保护情况。获取和设置,其实都是针对的FTFA_FPROT0到FTFA_FPROT3. 下面为测试结果: 可以看到,flash没有被保护。 可以看到,这时候寄存器FTFA_FPROT0到FTFA_FPROT3显示的值是保护的。 但是,这样设置寄存器保护了flash,那么有没有改变到flashconfiguration field呢?毕竟每次reset后,FTFA_FPROT0到FTFA_FPROT3是从flash configuration field调取数据的。 可以看到,虽然控制寄存器为flash保护,但是flashconfiguration field 并没有改变, 则如果要每次都让flash都要保护,就需要直接修改flash configuration field。 |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
1912个成员聚集在这个小组
加入小组我的项目我做主,使用GN+Ninja来完成构建系统(VSCode开发RT106X)
36362 浏览 0 评论
NXP IMX8应用处理器快速入门必备:技巧、使用、设计指南
4401 浏览 0 评论
6055 浏览 1 评论
6768 浏览 0 评论
NXP i.MX6UL开发板(linux系统烧录+规格+硬件+模块移植)使用手册
4218 浏览 0 评论
620浏览 2评论
求助,S32G上Core M启动后如何让Core A在Flash指定位置加载uboot?
618浏览 2评论
ESP32-WROVER-IE + LAN8720以太网,GPIO0电压只有1.6v,无法正常进入spi flash boot模式如何解决?
610浏览 2评论
求分享适用于PN7160 Android的NFC工厂测试应用程序
696浏览 2评论
799浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 20:13 , Processed in 1.117812 second(s), Total 73, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号