`
izuoyan
  • 浏览: 9220628 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

在TMS320F2812上实现从flash拷贝整个程序到RAM上运行的方法探讨

阅读更多

TMS<?xml:namespace prefix = st1 /><chmetcnv w:st="on" unitname="F" sourcevalue="320" hasspace="False" negative="False" numbertype="1" tcsc="0">320F</chmetcnv>2812上实现从flash拷贝整个程序到RAM上运行的方法探讨

1. 前言

TMS<chmetcnv w:st="on" unitname="F" sourcevalue="320" hasspace="False" negative="False" numbertype="1" tcsc="0">320F</chmetcnv>2812 DSP 里,代码从内部flash里运行,比从内部RAM里运行要慢30%左右,所以对运行时间苛刻的程序直接在flash里运行,往往不能满足要求。故而,需要将代码拷贝到RAM以提高运行速度。TI文档只提供了部分代码从flash拷贝到RAM中的方法。然而,在一些应用中,需要将整个代码段都拷贝到RAM中执行,以提高整体运行速度。本文通过对TMS<chmetcnv w:st="on" unitname="F" sourcevalue="320" hasspace="False" negative="False" numbertype="1" tcsc="0">320F</chmetcnv>2812 的启动代码研究,来探讨如何在从FLASH启动后将整个代码段拷贝到RAM中,然后在RAM中运行的方法。

2. TMS<chmetcnv w:st="on" unitname="F" sourcevalue="320" hasspace="False" negative="False" numbertype="1" tcsc="0">320F</chmetcnv>2812 启动过程

TMS<chmetcnv w:st="on" unitname="F" sourcevalue="320" hasspace="False" negative="False" numbertype="1" tcsc="0">320F</chmetcnv>2812的内部存储器中,0x<chmetcnv w:st="on" unitname="F" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">3F</chmetcnv> F000 ----0x3FFFC04K*16Boot ROM<?xml:namespace prefix = v /><shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"></shapetype>

<shapetype stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><?xml:namespace prefix = o /><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 275.25pt; HEIGHT: 244.5pt" o:ole="" type="#_x0000_t75"><imagedata o:title="" src="file:///D:%5CDOCUME~1%5CSHFAXU~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C03%5Cclip_image001.emz"><a href="http://p.blog.csdn.net/images/p_blog_csdn_net/flylonginsky/209999/o_pic1_2isk.jpg"><img alt="" src="http://p.blog.csdn.net/images/p_blog_csdn_net/flylonginsky/209999/o_pic1_2isk.jpg"></a></imagedata></shape>

1 2812内部BootRom地址图

CPU向量表位于北部ROM的底端(0x3FFFC0 ---- 0x3FFFF)。当VMAP=1,ENPIE=0 ,MPNMC=0时,该向量表被激活。复位向量出厂时被编程指向函数InitBoot。这个函数开始启动过程。当然,启动过程完成之后,我们需要初始化PIE中断向量表,同时使能PIE block。初始化PIE中断向量表之后,除了复位,所有中断向量均从PIE获得。

TMS<chmetcnv w:st="on" unitname="F" sourcevalue="320" hasspace="False" negative="False" numbertype="1" tcsc="0">320F</chmetcnv>2812启动代码固化在该内部ROM中。当TMS<chmetcnv w:st="on" unitname="F" sourcevalue="320" hasspace="False" negative="False" numbertype="1" tcsc="0">320F</chmetcnv>2812上电或者热复位后,首先由芯片本身将一些寄存器初始化:

PIE disabled(ENPIE=0,VMAP=1,OBJMDE=0,AMODE=0,MOM1MAP=1),

然后dsp芯片会对XMPNMC管脚采样,根据采样值的高低,来决定启动模式是“微处理器模式”还是“微计算机模式”。当XMPNMC=0时,为“微计算机模式”,此时,启动ROM存储器被使能而XINTF Zone 7被禁止。复位向量从内部启动ROM获取,启动ROM在复位期间一直被使能。

启动ROM里的复位向量(位于0x3FFFC0)指向InitBoot函数(位于0x3FFC00)。在完成器件初始化(InitBoot)之后,Boot loader将检查GPIO管脚的状态,然后再决定选用的启动模式。启动模式有4种:跳转到flash,跳转到H0 SARAM,跳转到OTP或者调用片上启动程序。

InitBoot Function 所做工作有:1.初始化状态寄存器;2.将堆栈指针设为0x4000x400 - 0x<chmetcnv w:st="on" unitname="F" sourcevalue="44" hasspace="False" negative="False" numbertype="1" tcsc="0">44F</chmetcnv>作为启动过程中的堆栈);3.CSM密码保护部分;4.调用SelectBootMode5.调用ExitBoot

在完成选择启动模式过程之后,根据选择的启动模式,dsp会跳到相应的启动入口。也可以自己选择启动入口。这些入口地址都在这之前已经被dsp定义好的。

如果从flash启动,那么我们的管脚状态应该是

GPIOF4

GPIOF12

GPIOF3

GPIOF2

(SCITXDA)

(MDXA)

(SPISTEA)

(SPICLK)

内部上拉

无内部上拉

无内部上拉

无内部上拉

Mode Selected

1

x

x

x

Jump to Flash address 0x<chmetcnv w:st="on" unitname="F" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">3F</chmetcnv> 7FF6

下图为BootROM 函数的流程图

<shape id="_x0000_i1026" style="WIDTH: 414.75pt; HEIGHT: 321pt" type="#_x0000_t75"><imagedata o:title="" src="file:///D:%5CDOCUME~1%5CSHFAXU~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C03%5Cclip_image003.emz"><font size="3"></font></imagedata></shape>

2 BootROM 函数的流程图

对于内部flash启动,如图

<shape id="_x0000_i1027" style="WIDTH: 415.5pt; HEIGHT: 67.5pt" type="#_x0000_t75"><imagedata o:title="" src="file:///D:%5CDOCUME~1%5CSHFAXU~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C03%5Cclip_image005.emz"><font face="Times New Roman" size="3"></font></imagedata></shape>

3跳转到Flash启动的流程图

0x<chmetcnv w:st="on" unitname="F" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">3F</chmetcnv>7FF6必须放置一个跳转指令,该指令跳转到你自己的启动代码或者应用程序。

3. 搬移思路

根据上节2的启动过程,flash启动过后,跳到0x<chmetcnv w:st="on" unitname="F" sourcevalue="3" hasspace="False" negative="False" numbertype="1" tcsc="0">3F</chmetcnv>7FF6,然后根据其内容再跳转到应用程序。我们在这里稍微修改一下,就可以将PC指针跳到RAM首地址,程序就能在RAM里运行了。

将“搬移程序”烧在flash上,从flash启动之后,“搬移程序”会被执行。“搬移程序”做的工作就是将“应用主程序”代码拷贝到内部RAM,然后经过初始化环境(InitBootExitBoot),将PC指针指向RAM里代码首地址。这样,你的程序就在RAM中运行起来了。也就是说,我们需要一个“搬移程序”,启动时运行,用来拷贝flash上的代码到RAM中;当然,还需要一个你的“应用主程序”,该主程序被“搬移程序”从flash里“挪”到RAM后在RAM中运行。我们还要做的工作就是,把“应用主程序”烧写到flash里的某一块,这个块又不会影响flash启动时运行“搬移程序”。完成这个烧写过程的程序,我们称之为flash烧写程序。

总结一下,完成整个搬移过程,一共需要三个程序。“搬移程序”和“应用主程序”被固化到flash里“烧写flash程序”将“应用主程序”烧入flash中指定的块中。TI的烧写flash插件用来烧写“搬移程序”。

4. 搬移方法

1)首先你要用的主程序必须编译通过,并且通过仿真器在RAM里运行无问题。将主程序的CMD文件进行改写,保证程序段(.text)分配在连续的存储空间。程序从flash启动,所有初始化段链接在非易失存储器里,而非初始化段必须链接在易失存储器。我们可以把初始化段都放在一个连续的内部RAM空间,而非初始化段放在另一个内部RAM空间。如果你的代码不是很大,也可以都放在连续的RAM空间。但在实际项目中,通常你会遇到存储空间不够的问题。这时就要考虑将无关紧要的段放在另外的非程序空间了。

.cinit

Flash

.cio

RAM

.const

Flash

.econst

Flash

.pinit

Flash

.switch

Flash

.text

Flash

.bss

RAM

.ebss

RAM

.stack

Lower 64Kw RAM

.sysmem

RAM

.esysmem

RAM

.reset

RAM1

例如:

MEMORY

{

PAGE 0 : 

   RAMH0      : origin = 0x3F8000, length = 0x002000

         

PAGE 1 : 

   /* SARAM                     */     

   RAMM0M1    : origin = 0x000000, length = 0x000800

   RAML0L1    : origin = 0x008000, length = 0x002000 

}

 

 

SECTIONS

{

   /* Allocate program areas: */

   .reset              : > RAMH0     PAGE = 0

   vectors             : > RAMH0     PAGE = 0

   .cinit              : > RAMH0     PAGE = 0

   .text               : > RAMH0     PAGE = 0

   .const              : > RAMH0     PAGE = 0

   .econst             : > RAMH0     PAGE = 0

   .switch                               : > RAMH0     PAGE = 0

   

   /* Allocate data areas: */

   .stack              : > RAMM0M1     PAGE = 1

   .bss                : > RAML0L1     PAGE = 1

   .ebss               : > RAML0L1     PAGE = 1

   .sysmem             : > RAML0L1     PAGE = 1

}

从上面的CMD可知,主程序代码均放在RAMH0中,长度为0x2000

2)其次,将该工程编译成功后,加载到内部ram,仿真器自动完成必要的初始化环境之后,pc指针应该指向_c_init00,记下现在PC指针的位置,在Boot.asm中会用到。

3)自制一个flash烧写程序,或者从网上下载其他网友的flash烧写程序,将目标地址放在除flashJ块以外的块中。烧写的长度不能小于被烧写的主程序长度。该烧写程序在RAM中运行。,其代码段不能和被烧写的主程序用的代码段存储区域相同,否则会破坏主程序在ram中的代码。

烧写之后,可以用CCSSave data功能,来查看flash中的数值是否和ram里主程序空间数值一致。

4 TI的烧写插件烧写“搬移程序”。注意,该“搬移程序”要能在dsp启动后执行。并且,烧写的时候,不能将上一步烧到flash上的主程序代码擦除。“搬移程序”具体见下节。

5. “搬移程序”具体实现方法

Boot.asm文件内容:

    .def _InitBoot

    .ref _EntryAddr_H

    .ref _EntryAddr_L

 

    .sect ".InitBoot"

;

; _InitBoot

;

; 1) Initalizes the stack pointer

; 2) Sets the device for C28x operating mode

; 3) Calls the main boot functions

; 4) Calls an exit routine

;

_InitBoot:

; Initalize the stack pointer.

  MOV SP, #0 ; Initalize the stack pointer

; Initalize the device for running in C28x mode.

  C28OBJ ; Select C28x object mode

  C28ADDR ; Select C27x/C28x addressing

  C28MAP ; Set blocks M0/M1 for C28x mode

  CLRC PAGE0 ; Always use stack addressing mode

  MOVW DP,#0 ; Initialize DP to point to the low 64 K

  CLRC OVM

; Set PM shift of 0

  SPM 0

; Read the password locations – this will unlock the

; CSM only if the passwords are erased. Otherwise it

; will not have an effect.

  MOVL XAR1,#0x3F7FF8;

  MOVL XAR0,*XAR1++

  MOVL XAR0,*XAR1++

  MOVL XAR0,*XAR1++

  MOVL XAR0,*XAR1

; Cleanup and exit. At this point the EntryAddr

; is located in the ACC register

  BF _ExitBoot,UNC

;

; _ExitBoot

;

;

;This module cleans up after the boot loader

;

; 1) Make sure the stack is deallocated.

; SP = 0x400 after exiting the boot

; loader

; 2) Push 0 onto the stack so RPC will be

; 0 after using LRETR to jump to the

; entry point

; 2) Load RPC with the entry point

; 3) Clear all XARn registers

; 4) Clear ACC, P and XT registers

; 5) LRETR – this will also clear the RPC

; register since 0 was on the stack

;

_ExitBoot:

;

; Insure that the stack is deallocated

;

  MOV SP,#0

;

; Clear the bottom of the stack. This will endup

; in RPC when we are finished

;

  MOV *SP++,#0

  MOV *SP++,#0

  

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP  

;

; Load RPC with the entry point as determined

; by the boot mode. This address will be returned

; in the ACC register.

;向堆栈中压入0x3f8000,该地址即为主程序在ram中运行的首地址。

  MOV *SP++, #0x8000

  MOV *SP++, #0x3F

  

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP 

 

  POP RPC

  

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP  

;

; Put registers back in their reset state.

;

; Clear all the XARn, ACC, XT, and P and DP

; registers

;

; NOTE: Leave the device in C28x operating mode

; (OBJMODE = 1, AMODE = 0)

;

  ZAPA

  MOVL XT,ACC

  MOVZ AR0,AL

  MOVZ AR1,AL

  MOVZ AR2,AL

  MOVZ AR3,AL

  MOVZ AR4,AL

  MOVZ AR5,AL

  MOVZ AR6,AL

  MOVZ AR7,AL

  MOVW DP, #0

;

; Restore ST0 and ST1. Note OBJMODE is

; the only bit not restored to its reset state.

; OBJMODE is left set for C28x object operating

; mode.

;

; ST0 = 0x0000 ST1 = 0x0A0B

; 15:10 OVC = 0 15:13 ARP = 0

; 9: 7 PM = 0 12 XF = 0

; 6 V = 0 11 M0M1MAP = 1

; 5 N = 0 10 reserved

; 4 Z = 0 9 OBJMODE = 1

; 3 C = 0 8 AMODE = 0

; 2 TC = 0 7 IDLESTAT = 0

; 1 OVM = 0 6 EALLOW = 0

; 0 SXM = 0 5 LOOP = 0

; 4 SPA = 0

; 3 VMAP = 1

; 2 PAGE0 = 0

; 1 DBGM = 1

; 0 INTM = 1

;

  MOV *SP++,#0

  MOV *SP++,#0x0A0B

  

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP 

  

  POP ST1

  POP ST0

  

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP

  NOP 

;

; Jump to the EntryAddr as defined by the

; boot mode selected and continue execution

;

  LRETR

;

    .end

“搬移程序”部分代码:

unsigned long *srcAddr = (unsigned long *)0x3D8000;

unsigned long *desAddr = (unsigned long *)0x3F8000; 

       InitSysCtrl();

 

       // Disable and clear all CPU interrupts:

       DINT;

       IER = 0x0000;

       IFR = 0x0000;

 

       // Initialize Pie Control Registers To Default State:

       InitPieCtrl();

 

       InitPieVectTable(); 

       

       //以下即将flash上的代码拷贝到ram中,根据自己需要,更改源地址和目标地址

    for(i = 0; i < 0x2000; i++)

    {

        *(desAddr + i) = *(srcAddr + i);

    }

    

    InitBoot();   //调用Boot.asm中程序         

分享到:
评论

相关推荐

    TMS320F2812上实现从flash拷贝整个程序到RAM上运行的方法

    ### TMS320F2812上实现从Flash拷贝整个程序到RAM上运行的方法 #### 一、引言 TMS320F2812是一款高性能的数字信号处理器(DSP),广泛应用于各种实时控制领域。在这款DSP上,程序通常存储在内部Flash中,并在此处运行...

    TMS320F28XXX_DSP上实现从flash拷贝到RAM

    在 TMS320F28XXX_DSP 上实现从 flash 拷贝整个程序到 ram 运行的方法探讨 TMS320F28XXX_DSP 里,代码从内部 flash 里运行,比从内部 RAM 里运行要慢 30% 左右,所以对运行时间苛刻的程序直接在 flash 里运行,往往...

    TMS320F2812电路板烧写FLASH代码

    《TMS320F2812电路板烧写FLASH代码详解》 TMS320F2812是一款高性能的浮点数字信号处理器(DSP),由德州仪器(TI)公司生产,广泛应用于工业控制、自动化系统、电机驱动等领域。在开发过程中,将程序代码烧写到芯片...

    DSP TMS320F2812 内部FLASH脱机运行测速程序

    本篇文章将深入探讨如何在TMS320F2812上利用其内部FLASH进行程序存储,并实现脱机运行,以及如何构建一个测速程序。 首先,了解TMS320F2812的内部结构至关重要。该芯片内置了丰富的硬件资源,包括浮点运算单元、高...

    TMS320F2812烧写flash

    《TMS320F2812烧写Flash详解》 TMS320F2812是一款由Texas Instruments公司推出的高性能浮点数字信号处理器(DSP),广泛应用于工业控制、自动化、通信等领域。其内部集成的Flash存储器允许在系统编程,使得程序更新...

    TMS320F2812的例子程序(AD,CAN,DA,LCD,FLASH,KEYBOARD等全)

    《TMS320F2812 DSP的全面实践:探索AD, CAN, DA, LCD, FLASH,KEYBOARD等应用》 TMS320F2812是一款高性能的数字信号处理器(DSP),由德州仪器(TI)公司开发,广泛应用于工业控制、通信系统和嵌入式应用。这个例子...

    TMS320F28335的程序从FLASH到RAM的移植与运行

    本文首先分析了TMS320F28335 DSP应用程序运行流程,然后讨论了代码从FLASH到RAM的搬移过程,并实现了基于TMS320F28335 DSP的2DPSK调制与解调的上电自动运行。 TMS320F28335 DSP应用程序运行流程: 1. 系统上电复位...

    TMS320F2812 TMS320F2812 TMS320F2812 TMS320F2812

    标题和描述中提到的"TMS320F2812"是德州仪器(Texas Instruments)的一款高性能数字信号处理器(Digital Signal Processor,简称DSP),它属于C2000系列,专为实时控制应用设计。以下是对TMS320F2812的一些关键特性...

    TMS320F28335 flash搬运到ram里运行

    《TMS320F28335:从Flash到RAM的运行实践》 TMS320F28335是一款由Texas Instruments(TI)公司推出的高性能浮点数字信号处理器(DSP),广泛应用于实时控制、电机驱动、电源管理等领域。在某些应用场合,为了提高...

    TMS320F2812-FLASH.rar_TMS320F2812_flash_flash在线

    总结来说,TMS320F2812的在线FLASH编程是开发和维护过程中的重要环节,它使得开发人员能够在不中断系统运行的情况下更新和优化程序,大大提高了工作效率。掌握这一技术,对于深入理解和应用TMS320F2812 DSP至关重要...

    TMS320F2812例子程序

    通过上述资源,开发者可以系统地学习和实践TMS320F2812的开发,从基础的硬件连接到复杂的算法实现,逐步掌握这款DSP的精髓。同时,持续更新的技术文档和社区支持也是提升技能的重要途径。对于有志于深入理解和应用...

    基于TMS320F2812 TMS320F28335 TI电子设计大奖赛论文+软件源码+硬件设计文件合集.zip

    基于TMS320F2812 TMS320F28335 TI电子设计大奖赛论文+软件源码+硬件设计文件合集: 基于TMS320F28027的智能晾衣架 基于TMS320F28033的20MHz手持式双踪袖珍示波器 基于TMS320F28035电动汽车电机控制器 基于TMS320F...

    TMS320F2812实验报告

    通过这样的操作,实验者可以掌握如何在TMS320F2812中读写内存、设置断点以及理解程序运行的流程。 实验结果表明,成功地实现了数据从0x80000到0x80100的复制,验证了数据存取的正确性。整个实验不仅锻炼了实验者对...

    基于TMS320F2812从FLASH到RAM移植方法

    总结起来,TMS320F2812 DSP的程序从Flash迁移到RAM是为了克服Flash执行速度较慢的问题,通过特殊流程在启动时自动完成迁移,从而提升系统性能。这种方法对于对实时性有高要求的应用具有重要意义,并且可以适应不同的...

    TMS320F2812片内FLASH在线编程技术

    串口编程技术是指使用一个预先固化在TMS320F2812 FLASH中的程序来实现对其自身或其他目标代码的编程。该预先固化程序的主要功能是实现编程时机的判断和具体编程的执行。通过JTAG口编程到FLASH中后,可以不需要再次...

    TMS320F2812中文手册

    《TMS320F2812中文手册》提供了关于TI公司TMS320C28x系列数字信号处理器的详细信息。TMS320C28x是TI公司推出的一种高性能32位定点DSP芯片,适用于各种测控应用场景,如工业自动化、电力电子、电机控制等。该系列包含...

    TMS320F2812系统中的软件复位方法国电

    ### TMS320F2812系统中的软件复位方法详解 #### 一、引言 在现代控制系统的设计中,确保系统的稳定性和可靠性至关重要。TMS320F2812作为德州仪器(TI)推出的一款高性能数字信号处理器(DSP),广泛应用于工业控制...

    tms320f2812官方中文手册datasheet.rar

    综上所述,TMS320F2812是数字信号控制领域的明星产品,其强大的处理能力和丰富的外设使其在众多领域中发挥着重要作用。通过深入学习和掌握"TMS320F2812官方中文手册",开发者可以更好地利用这款芯片,开发出高效、...

Global site tag (gtag.js) - Google Analytics