您好,  [请登录] [QQ登录]  [支付宝登录[免费注册]

商品分类

分享到: 百度搜藏 搜狐微博 新浪微博 腾讯微博 QQ收藏 人人网 Facebook Twitter

TMS320F28xx DSP中内部Flash的应用研究

发布日期:2011-05-15

    1 媒介 

    TMS320F28xx DSP片内有128 K×16 bit字的Flash、两块4 K x16bit字的单周期访问RAM(SARAM)LO和L1、一块8 Kxl6 bit字的单周期访问RAM(SARAM)HO、两块1 Kxl6 bit字的单周期访问RAM(SARAM)M0和M1。由于存储器种类多、容量大,以是从体系的高度来配置各个存储器必须有符合的要领,而这些要领一样平常都与片内Flash有关。别的,TMS320F28xx DSP片内有看门狗定时器模块(WDT)、引导ROM(ROM bootloader)模块、代码寂静模块(CSM),要公道地利用这些模块为整个体系办事,肯定也要用到Flash。 
    由此可以看出,Flash的职位地方和作用比较明显.以是本文就Flash的几种用法作了研究。 

  
  2 从Flash拷贝段到RAM 

    2.1拷贝停止向量 

    在TMS320F28xx器件中,外设扩展停止(PIE)模块办理停止恳求。上电时,全部停止向量必须位于非易失性存储器(如Flash)中,但是要把停止向量拷贝到PIEVECT RAM中,这是用户代码中器件初始化步伐的一部分。PIEVECT RAM是一个特定的RAM块,它在当前TMS320F28xx器件中是一个256×16的块.在数据空间中的肇始地点为Ox000D00。 
    把停止向量连接到Flash,然后在运行时把停止向量拷贝到PIEVECT RAM中,有很多要领可以实现。一个要领是创建包括函数指针的常量C布局体,该布局体包括128个32-bit向量。要是利用DSP281x大概DSP280x外设的布局体.这个布局体叫做PieVectTableInit,它已经在DSP281x_PieVect.c大概DSP280x_PieVect.c创建(参看TI提供的例程)。由于这个布局体利用const范例关键词,以是它将会被编译器安排在.econst段中。运行时只必要把这个布局体拷贝到PIEVECT RAM中。C编译器运行时支持库包括名为memcpy的存储器拷贝函数,该函数可以被用来完成拷贝任务,其用法如下所示:

    以上这个例子为PIE RAM肇始地点利用的硬编码地点(hard coded address),明白指定为0x000D00。但是硬编码地点并不是较好的编程方法,用户可以利用DATA_SECTION指令创建一个非初始化的假变量(dummy variable),并把这个变量连接到PIE RAM.然后用这个假变量的名字来代替硬编码地点。比方,当利用DSP281x大概DSP280x外设布局体时,创建一个名为PieVectTable的非初始化布局体,并把该布局体连接到PIEVECT RAM。前面例子中的memcpy()函数可以被更换为: 

    memcpy(&PieVectTable,&PieVectTableInit,256); 

    细致拷贝长度是256个16-bit字.映射为128个32-bit字。 

    2.2初始化Flash控制寄存器 

    Flash控制寄存器FOPT、FPWR、:FSTDBY-WAIT、FACTIVEWAIT、FBANKWAIT、FOTPWAIT的初始化代码不克不及从Flash存储器当中运行.不然就会有不可预料的结果出现。以是,Flash控制寄存器的初始化函数在运行时必须从Flash(它的装载地点)拷贝到RAM(它的运行地点)。 

    Flash控制寄存器由Code Security Module(CSM)掩护。要是CSM被掩护起来了,那么必须从被掩护的RAM(比方:L0大概L1 SARAM)运行Flash控制寄存器的初始化代码,不然Flash控制寄存器的初始化代码无法访问Flash控制寄存器。要细致的是,当器件复位的时间CSM一样平常都是被掩护起来的,固然利用假暗码0xFFFF时ROM BOOTLOAD-ER会把它解锁。 

    C编译器的CODE_SECTION指令可以用来为Flash控制寄存器的初始化函数创建独立的可连接段。比方:假定Flash控制寄存器的配置在C函数InitFlash()中实现,并且想把这个函数安排在名为secureRamFuncs的可连接段当中。下列的C代码例程表现了CODE_SECTION下令在Flash存储器配置中的精确用法:



    secureRamFuncs段可以利用用户连接下令文件(.cmd)举行连接。这个段必要独立的装载和运行地点。别的,还想让连接器天生一些全局标记,这些全局标记可以用来决定装载地点、运行地点、段长度。在实现把这个段从装载地点拷贝到它的运行地点时必要这些信息。用户连接下令文件如下所示:

    在这个例子中,假定存储器Flash和SECURE_RAM都已经在用户连接下令文件中的MEMORY段中定义。这些存储器的PAGE标识符要与它们的存储器定义相立室。在上面的例程中假定两个存储空间都已经在PAGE 0(步伐存储空间)中声明过了。RUN_START、LOAD_START、LOAD_END指令将生玉成局标记,这些全局标记有特定的名称,映射着相应的地点。末了,这个段必须在运行时从Flash拷贝到RAM,可以用到编译器运行支持库内里的函数memcpy()。

     2.3性能最优化 

    常数是那些用C语言的const范例关键词声明的数据布局。编译器把全部的常数安排在.econst段中(假定为大存储模式)。当前TMS320F28xx器件上的特别管道(special pipelining)进步Flash上运行代码的性能时.每次访问位于片上Flash中的数据常数会占用很多周期。分外是在150 MHz TMS320F281x DSP上Flash等待状态要到达5个周期.100 MHz TMS320F280x DSP到达3个周期。以是,访问片上RAM中的常数与常数表则成为綦重沉重的包袱。然而,分立式嵌入式体系请求全部的初始化数据(如常数)最初都是位于非易失性存储器中,以是,必须为想访问的RAM中的常数创建独立的装载和运行地点.在运行时把这些常数从片上Flash中拷贝到RAM中。这里先容两种差别的实现要领。 
    要领一:在RAM中运行全部的常数阵列。 

    这种要领是为整个.econst段指定独立的装载和运行地点。其长处是容易利用,而弊端是RAM的利用量非常大(大概只有少量常数必要快速访问,但是用这种要领全部的常数都位于RAM)。 

    在用户连接下令文件中大略地为整个.econst段指定独立的装载和运行地点,然后在运行时通过拷贝整个.econst段的方法往工程中添加代码。比方:

    要领二:在RAM中运行特定的常数阵列。 
    这种要领是在运行时有选择性地从Flash拷贝常数到RAM。与要领一相似,这个流程可以或许完成预期成果,差别点是只有在定名段中当选择了的常数才会被拷贝到RAM中(而不是把全部的常数都拷贝到RAM中)。 

    假定想创建在RAM中运行的5个字的常数阵列,并定名为table[]。DATA_SECTION指令用来把table[]安排在名为ramconsts的用户自定义段中。相应的C源步伐如下所示:

     利用用户连接下令文件连接ramconsts段,装载到Flash而从RAM中运行,生玉成局标记来资助存储器拷贝。用户连接下令文件如下所示: 

    末了,在运行时必须把table[]从装载地点拷贝到运行地点:

    3 CSM暗码的编程

    TMS320F28xx器件上的代码寂静模块CSM提供了掩护,防备非法的步伐拷贝。在当前的TMS320F28xx器件中,整个Flash、OTP存储器,LO和L1都被CSM掩护(Flash配置寄存器同样被掩护)。当器件被掩护的时间,只有从被掩护的存储空间运行的代码可以访问(读或写)其他被掩护存储空间中的数据。从非掩护的存储空间运行的代码不可以访问被掩护存储空间中的数据。 

    CSM利用128-bit暗码构成8个单独的16-bit字。在当前的TMS320F28xx器件上,这些暗码被存储在Flash的最高8个字中(如地点:Ox3F7FF8-Ox3F7FFF)。在开辟进程中,发起在暗码位置放入假暗码0xFFFF。利用假暗码时,对CSM解掩护只需假读暗码位置。把假暗码放在暗码位置是很容易的.由于在Flash编程进程中.Flash被打扫后这些位置的状态将会是0xFFFF。用户只必要在本身的代码工程中克制毗蝉联何段到暗码地点,暗码将保持为OxFFFF。 

    在开辟完成以后.大概想把真正的暗码放在暗码位置中。别的,为了精确地掩护CSM模块,当前TMS320F28xx器件上的CSM模块必要编写值Ox0000到Flash的地点0x3F7F80-Ox3F7FF5。完成这两个任务的最大略的要领是用少量汇编语言举行编程。下面是一个汇编代码例子,这个例子指定了想要的暗码值,并且把它们放在一个名为pass-words的初始化段中。别的创建了一个名为csm_rsvd的初始化段,这个段的值全部是0x0000.并且这个段有得当的长度以得当地点Ox3F7F80-0x3F7FF5。细致,这个例子表现的是假暗码值0xFFFF.用户可以用本身的暗码代替这些假暗码。

     在这里必须告诫用户:不要把8个暗码的值全部设为Ox0000,如许做会永世地锁定CSM模块!passwords和CSB_rsvd段要由用户连接下令文件安排在存储器中。下面的例子实用于当前TMS320F28xx器件(对付其他器件,请参考器件数据手册以确定暗码和CSM保存位置的地点)。

     4 在DSP复位以后从Flash运行代码 

    TMS320F28xx具有引导ROM(ROM bootloader),器件复位以后ROM bootloader能把代码运行转到Flash中。当引导模式选择引脚被配置为"跳转到Flash"时.ROM bootloader将跳转到Flash中位于地点Ox3F7FF6处的指令。用户必要在这个地点上摆设一条指令,这条指令跳转到用户代码。由于CSM暗码从地点Ox3F7FF8开始,以是恰好有2个字可用于存放这个跳转指令。并非偶合的是,长跳转指令(在汇编代码中为LB)恰好占用2个字。 

    一样平常环境下,跳转指令将会跳转到C编译器运行支持库中C环境初始化步伐的肇始位置。这个步伐的人口标号是_c_int00。在这个步伐没有运行的时间C代码就不克不及运行。同样地,偶然间在开始运行用户的C应用步伐之前必要实行少量的汇编代码(比方:克制看门狗时钟外设)。如许,跳转指令必要跳转到用户汇编代码的肇始位置,必要在Flash中精确定位跳转指令。能到达这个目标的最大略的要领是利用汇编代码。在下面的例子中.创建了一个名为Codestart的已定名初始化段.这个段包括了一个长跳转.可以跳转到C环境初始化步伐。必要用用户连接下令文件把codestart段安排在存储器中。

     用户须在用户连接下令文件MEMORY部分的PAGE 0上定义一个名为BEGIN_Flash的存储器块。Codestart段将被连接到这个存储器块。下面的例子针对当前TMS320F28xx器件.对付其他的器件,参考相应的数据手册以确认Flash目标地点的引导。

     5 C环境引导时克制看门狗计时 

    C编译器运行时支持库中的C环境初始化函数是_c_int00,它完玉成局和静态变量的初始化。包括为每个初始化全局变量把数据从.cinit段(位于片上Flash存储器)拷贝到.ebss段(位于RAM)。比方,当一个全局变量在源代码中声明为:

int x=5;

    "5"被安排在初始化段.cinit,而标记"x"被安排在.ebss段。然后,_c_int00步伐在运行时把"5"拷贝到"x"的位置。当软件中有初始化全局和静态变量的大量数值时。在C环境引导步伐完成并且调用main()(这里看门狗可以被配置或被克制)函数之前看门狗定时器会超时。在代码开辟的进程中,这个题目大概不会在RAM中显现出来,由于从.cinit段拷贝的数据被连接到RAM后会非常快速地运行。然而,当.cinit段连接到内部Flash时。拷贝每个数据将会淹灭大量的周期。由于内部Flash存储器缺省为最大等待状态(等待状态仅在用户代码运行到main()后才会被配置)。别的。代码从Flash中实现数据拷贝.这又会增长完成数据拷贝必要的时间(代码取指和数据读肯定会访问Flash)。看门狗超时周期缺省到尽大概的最小值.连合这么一个究竟,看门狗超时变成真实的大概性。有一个大略的要领利用CCS来检测看门狗超时,步调如下:

    (1)为已经写入Flash的代码装载标记(单击File→Load Symbols→Load Symbols Only) 

    (2)复位DSP(单击Debug→Reset CPU)。 

    (3)重新开始DSP(单击Debug→Restart)。要是bootloader被设置为"Jump to Flash".那么无需举行这一步。 

    (4)运行到main()(单击Debug→Go_Main)。要是没有到达main(),那么在C环境初始化步伐完成之前看门狗很有大概已经溢出。 

    办理看门狗超时题目最大略的步伐便是在开始C环境初始化步伐之前克制看门狗。在main()到达之后重新使能看门狗,并且开始正常的代码实行流程。通过将WDCR寄存器中的WDDIS位设置为1来克制看门狗。必须利用汇编代码(由于C环境还没有创建)。在上文中,Codestart汇编代码段实现了能跳转到C环境初始化步伐_c_int00的跳转指令。为了克制看门狗,这个跳转要变为跳转到看门狗克制代码。此看门狗代码然后又跳转到_c_int00的步伐。下面的代码例子实现了这些成果:

 

    6 结束语

    文中罗列的Flash的这几种用法,在CCS中编程下载到TMS320F28xx DSP开辟板上,并通过运行步伐验证了其精确性。Flash的这几种用法可以作为体系开辟进程中的参考,有助于巨大体系开辟。