F28335第十六篇——内部Flash操作

Posted 海洋想想

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了F28335第十六篇——内部Flash操作相关的知识,希望对你有一定的参考价值。

文章目录

前言

本文主要介绍如何对DSP28335进行Flash操作。

本文主要参考资料:

  • TI.Flash2833x_API_Readme

DSP的Flash操作需要借助官方提供API。官方提供的API主要完成Flash的擦除,编写,校验三种功能。

Flash编写,只能将数据位由1变成0,而无法由0变成1。所以,在每次需要刷新程序时,需要对Flash进行先擦除,再编写。最后防止出现错误,还需要进行校验。而DSP的Flash擦除操作中,其最小的擦除单位为扇区。而编写的最小单位为字(16位)。编写操作不会改变之前已经编写过的数据位。例如,在Flash中,可以不需要擦除的情况下,将已经编写为0xFFFE的数据重写编写为0xFFFC。但是,相反的操作是不允许的。

配置方法

下面介绍如何使用Flash API。

  1. 到官网下载sprc539压缩包。

  2. 将Flash2833x_API_Library.h和Flash2833x_API_Config.h两个头文件添加到项目工程中。

  3. 添加Flash28335_API_V210.lib文件到项目中。首先,需要将lib文件添加到项目工程中。其次,需要在CCS中添加lib所在的路径。

  4. 将Flash API函数复制到SARAM中。这主要有两点原因:一,Flash API需要严格的时间限制。将函数复制到SARAM中,函数调用是无延时的,能够保证函数每个步骤的时序是正确的。二,因为Flash API是用于操作Flash中的数据的。若将函数放置于Flash中,有可能在程序运行中,函数代码被修改,造成程序失控。

其具体操作如下:
在cmd文件中添加如下代码:

   /* The Flash API functions can be grouped together as shown below.
      The defined symbols _Flash28_API_LoadStart, _Flash28_API_LoadEnd
      and _Flash28_API_RunStart are used to copy the API functions out
      of flash memory and into SARAM */

   Flash28_API:
   
        -lFlash28335_API_V210.lib(.econst) 
        -lFlash28335_API_V210.lib(.text)
                      LOAD = FLASHA, 
                       RUN = RAML0,  
                       LOAD_START(_Flash28_API_LoadStart),
                       LOAD_END(_Flash28_API_LoadEnd),
                       RUN_START(_Flash28_API_RunStart),
                       PAGE = 0

修改cmd文件,可以在SARAM和Flash中分配好存储程序的空间。但是,在程序下载过程中,程序数据只会烧写进Flash中。而在SARAM中,虽然分配好了存储空间,程序数据的拷贝还需要自己在代码中实现。在main函数中添加如下语句:

  MemCopy(&Flash28_API_LoadStart, &Flash28_API_LoadEnd, &Flash28_API_RunStart);

其中,Memcopy函数的定义如下:

void 
MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr)

    while(SourceAddr < SourceEndAddr)
     
        *DestAddr++ = *SourceAddr++;
    
    return;

经过以上步骤的设置,Flash API就成功的添加到项目中了。但是,还是需要注意一下几点:

  1. 确保系统时钟的频率是正确的,一般设置为150M。
  2. 不要工作在limp模式中。
  3. 关闭中断和看门狗。

下面重点介绍常用函数的使用方法。

擦除函数

extern Uint16  Flash_Erase(Uint16 SectorMask, FLASH_ST *FEraseStat);

Flash_Eraseh函数用于擦除指定的扇区。

参数:

  1. SectorMask:需要被擦除的扇区。其参数在头文件中有定义,代码如下所示。选择对应的扇区,即可擦除其内容。当然可以同时选择多个扇区,主需要将他们位或即可。
#define SECTORA   (Uint16)0x0001
#define SECTORB   (Uint16)0x0002
#define SECTORC   (Uint16)0x0004
#define SECTORD   (Uint16)0x0008
#define SECTORE   (Uint16)0x0010
#define SECTORF   (Uint16)0x0020
#define SECTORG   (Uint16)0x0040
#define SECTORH   (Uint16)0x0080
#define SECTOR_F28335 (SECTORA|SECTORB|SECTORC|\\
                       SECTORD|SECTORE|SECTORF|\\
                       SECTORG|SECTORH)
  1. FeraseStat:为结构体。定义为:
typedef struct 
    Uint32  FirstFailAddr;//第一出错的地址
    Uint16  ExpectedData;//期望值
    Uint16  ActualData;//实际值
FLASH_ST;

注意:
在本函数中,只有第一个成员FirstFailAddr有意义。

返回值:

返回值表示函数的状态,其具体的取值如下定义:

// Operation passed, no errors were flagged
#define STATUS_SUCCESS                        0   

// The CSM is preventing the function from performing its operation
#define STATUS_FAIL_CSM_LOCKED               10

// Device REVID does not match that required by the API
#define STATUS_FAIL_REVID_INVALID            11
    
// Invalid address passed to the API
#define STATUS_FAIL_ADDR_INVALID             12

// Incorrect PARTID
// For example the F2806 API was used on a F2808 device. 
#define STATUS_FAIL_INCORRECT_PARTID         13

// API/Silicon missmatch.  An old version of the
// API is being used on silicon it is not valid for
// Please update to the latest API. 
#define STATUS_FAIL_API_SILICON_MISMATCH     14

// ---- Erase Specific errors ---- 
#define STATUS_FAIL_NO_SECTOR_SPECIFIED      20
#define STATUS_FAIL_PRECONDITION             21
#define STATUS_FAIL_ERASE                    22
#define STATUS_FAIL_COMPACT                  23
#define STATUS_FAIL_PRECOMPACT               24

// ---- Program Specific errors ----  
#define STATUS_FAIL_PROGRAM                  30
#define STATUS_FAIL_ZERO_BIT_ERROR           31

// ---- Verify Specific errors ----
#define STATUS_FAIL_VERIFY                   40

// Busy is set by each API function before it determines
// a pass or fail condition for that operation.  
// The calling function will will not receive this 
// status condition back from the API
#define STATUS_BUSY                999    

编写和校验函数

extern Uint16  Flash_Program(Uint16 *FlashAddr, Uint16 *BufAddr, Uint32 Length, FLASH_ST *FProgStatus);
extern Uint16  Flash_Verify(Uint16 *StartAddr, Uint16 *BufAddr, Uint32 Length, FLASH_ST *FVerifyStat);

因为编写和校验函数使用方法基本一致,所以放置到一起讲解。编写函数就是将数据写入到Flash中,校验函数就是校验写入到Flash中的数据和预期数据是否一致。

参数:

  1. FlashAddr:16位数据地址,指向函数作用的Flash首地址。
  2. BufAddr:16为数据地址,指向将要被编写/校验数据的首地址。
  3. Length:16位数据,表示即将编写/校验数据的长度。
  4. FprogStatus:结构体,前文已经介绍。

返回值:

和前文一致,不再介绍。

以上是关于F28335第十六篇——内部Flash操作的主要内容,如果未能解决你的问题,请参考以下文章

第十六篇 JS实现全选操作

Python全栈开发之路 第十六篇:jQuey的动画效果属性操作文档操作input的value

Python 学习 第十六篇:networkx

Python开发第十六篇:AJAX全套

Python开发第十六篇:AJAX全套

Python之路第十六篇:Python并发编程